feat(docs): ステップバイステップガイド (#145)
* feat(docs): ステップバイステップガイドを追加 * fix * fix * docs * add docs
@ -1,32 +1,47 @@
|
|||||||
import type { Ref } from 'vue'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrollspy allows you to watch visible headings in a specific page.
|
* Scrollspy allows you to watch visible headings in a specific page.
|
||||||
* Useful for table of contents live style updates.
|
* Useful for table of contents live style updates.
|
||||||
*/
|
*/
|
||||||
export const useScrollspy = () => {
|
export const useScrollspy = (config?: IntersectionObserverInit) => {
|
||||||
const observer = ref() as Ref<IntersectionObserver>
|
let observingElements: Element[] = [];
|
||||||
const visibleHeadings = ref([]) as Ref<string[]>
|
|
||||||
const activeHeadings = ref([]) as Ref<string[]>
|
|
||||||
|
|
||||||
const observerCallback = (entries: IntersectionObserverEntry[]) =>
|
const observer = ref<IntersectionObserver>();
|
||||||
|
const visibleHeadings = ref<string[]>([]);
|
||||||
|
const activeHeadings = ref<string[]>([]);
|
||||||
|
const mainHeading = ref<string | null>(null);
|
||||||
|
|
||||||
|
function observerCallback(entries: IntersectionObserverEntry[]) {
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
const id = entry.target.id
|
const id = entry.target.id;
|
||||||
|
|
||||||
if (entry.isIntersecting) { visibleHeadings.value.push(id) } else { visibleHeadings.value = visibleHeadings.value.filter(t => t !== id) }
|
if (entry.isIntersecting) {
|
||||||
})
|
visibleHeadings.value.push(id);
|
||||||
|
} else {
|
||||||
|
visibleHeadings.value = visibleHeadings.value.filter((t) => t !== id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const updateHeadings = (headings: Element[]) =>
|
mainHeading.value = entries.reduce((max, entry) => (entry.intersectionRatio > max.intersectionRatio ? entry : max), entries[0]).target.id;
|
||||||
headings.forEach((heading) => {
|
}
|
||||||
observer.value.observe(heading)
|
|
||||||
})
|
function updateHeadings(headings: Element[]) {
|
||||||
|
observingElements.forEach((el) => {
|
||||||
|
observer.value?.unobserve(el);
|
||||||
|
});
|
||||||
|
|
||||||
|
observingElements = headings;
|
||||||
|
|
||||||
|
observingElements.forEach((heading) => {
|
||||||
|
observer.value?.observe(heading);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
watch(visibleHeadings, (val, oldVal) => {
|
watch(visibleHeadings, (val, oldVal) => {
|
||||||
if (val.length === 0) { activeHeadings.value = oldVal } else { activeHeadings.value = val }
|
if (val.length === 0) { activeHeadings.value = oldVal } else { activeHeadings.value = val }
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
// Create intersection observer
|
// Create intersection observer
|
||||||
onBeforeMount(() => (observer.value = new IntersectionObserver(observerCallback)))
|
onBeforeMount(() => (observer.value = new IntersectionObserver(observerCallback, config)))
|
||||||
|
|
||||||
// Destroy it
|
// Destroy it
|
||||||
onBeforeUnmount(() => observer.value?.disconnect())
|
onBeforeUnmount(() => observer.value?.disconnect())
|
||||||
@ -34,6 +49,7 @@ export const useScrollspy = () => {
|
|||||||
return {
|
return {
|
||||||
visibleHeadings,
|
visibleHeadings,
|
||||||
activeHeadings,
|
activeHeadings,
|
||||||
|
mainHeading,
|
||||||
updateHeadings
|
updateHeadings
|
||||||
}
|
}
|
||||||
}
|
}
|
11
content/ja/docs/2.for-users/5.stepped-guides/1.index.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# ステップバイステップガイド
|
||||||
|
|
||||||
|
このセクションでは、Misskeyを利用する中で見られる複雑な操作を、一歩ずつ丁寧に解説しています。
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
|
||||||
|
このセクションはベータ版です。内容が不完全である可能性があります。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
<MkIndex />
|
2
content/ja/docs/2.for-users/5.stepped-guides/_dir.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
title: "ステップバイステップガイド"
|
||||||
|
description: "Misskeyの操作を一歩ずつ丁寧に解説しています。操作方法がわからなくなったらここをチェック!"
|
@ -0,0 +1,82 @@
|
|||||||
|
title: "Misskey Webをアプリ化して使う方法"
|
||||||
|
description: "Misskey WebをPWAアプリ化する方法をご紹介します。スマートフォンでMisskeyを利用する際のおすすめの方法です。"
|
||||||
|
|
||||||
|
# Do not translate any keys that includes underscore
|
||||||
|
|
||||||
|
_TYPE_: "STEPPED_GUIDE"
|
||||||
|
|
||||||
|
body: |
|
||||||
|
ここでは、Misskey WebをPWAアプリ化する方法をご紹介します。スマートフォンでMisskeyを利用する際のおすすめの方法です。
|
||||||
|
|
||||||
|
## PWAとは?
|
||||||
|
|
||||||
|
PWAは、Progressive Web Appの略で、ウェブページをアプリのように扱うことができる技術です。Misskeyは、標準でPWAに対応しています。
|
||||||
|
|
||||||
|
ここでは、PWAの設定方法を端末のOS別に紹介しています。以下からお使いのOSを選んで進んでください!
|
||||||
|
|
||||||
|
guides:
|
||||||
|
- _AUTOSELECT_TYPE_: "OS_ANDROID"
|
||||||
|
_LAYOUT_TYPE_: "IMAGE_PORTRAIT_FIXED"
|
||||||
|
title: "Android (Google Chrome)"
|
||||||
|
description: |
|
||||||
|
AndroidでPWAをお使いになる際は、Google Chromeがおすすめです。
|
||||||
|
|
||||||
|
ここでは、Google Chromeを使用した設定方法について解説します。
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- title: "PWAにしたいMisskeyサーバーを開く"
|
||||||
|
image: "android/sp_0.png"
|
||||||
|
description: |
|
||||||
|
PWAとして端末にインストールしたいMisskeyサーバーにアクセスし、ログインしてください。
|
||||||
|
|
||||||
|
- title: "詳細設定メニューを開く"
|
||||||
|
image: "android/sp_1.png"
|
||||||
|
description: |
|
||||||
|
Misskeyサーバーの任意のページを開いたまま、右上にある「︙」ボタンをタップします。
|
||||||
|
|
||||||
|
- title: "「ホーム画面に追加」または「アプリをインストール」をタップ"
|
||||||
|
image: "android/sp_2.png"
|
||||||
|
description: |
|
||||||
|
メニュー内にある「ホーム画面に追加」もしくは「アプリをインストール」の項目をタップし、出てきたダイアログの指示に従ってください。
|
||||||
|
|
||||||
|
- title: "ホーム画面を確認する"
|
||||||
|
image: "android/sp_3.png"
|
||||||
|
description: |
|
||||||
|
しばらくすると、ホーム画面に、サーバーのアイコンもしくはMisskeyのアイコンが追加されます。
|
||||||
|
|
||||||
|
このアイコンをタップすることで、Misskeyはアプリモードで起動します。
|
||||||
|
|
||||||
|
- _AUTOSELECT_TYPE_: "OS_IOS"
|
||||||
|
_LAYOUT_TYPE_: "IMAGE_PORTRAIT_FIXED"
|
||||||
|
title: "iOS / iPadOS"
|
||||||
|
description: |
|
||||||
|
iOS または iPadOS でPWAをお使いになる際は、Safariをご利用ください。
|
||||||
|
|
||||||
|
開始する前に、お使いの端末に搭載されているOSが最新のものかどうかを確認してください。最新ではない場合は、[こちら](https://support.apple.com/ja-jp/ios/update)を参考にしてアップデートしてください。
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- title: "PWAにしたいMisskeyサーバーを開く"
|
||||||
|
image: "ios/sp_0.png"
|
||||||
|
description: |
|
||||||
|
PWAとして端末にインストールしたいMisskeyサーバーにアクセスし、ログインしてください。
|
||||||
|
|
||||||
|
- title: "共有ボタンをタップして開く"
|
||||||
|
image: "ios/sp_1.png"
|
||||||
|
description: |
|
||||||
|
Misskeyサーバーの任意のページを開いたまま、メニューバーの共有ボタンをタップします。
|
||||||
|
|
||||||
|
- title: "「ホーム画面に追加」をタップ"
|
||||||
|
image: "ios/sp_2.png"
|
||||||
|
description: |
|
||||||
|
オプションのリストを下にスクロールしてから、「ホーム画面に追加」をタップします。
|
||||||
|
|
||||||
|
この後、通知の送信許可を求められることがありますので、画面の指示に従い、必要に応じて許可してください。
|
||||||
|
|
||||||
|
「ホーム画面に追加」が表示されない場合は、設定項目が非表示になっている可能性があります。表示するには、リストの一番下までスクロールし、「アクションを編集」から「ホーム画面に追加」の項目を追加してください。詳しくは[Appleのサポートページ](https://support.apple.com/ja-jp/guide/iphone/iph42ab2f3a7/ios)をご覧ください。
|
||||||
|
|
||||||
|
- title: "ホーム画面を確認する"
|
||||||
|
image: "ios/sp_3.png"
|
||||||
|
description: |
|
||||||
|
しばらくすると、ホーム画面に、サーバーのアイコンもしくはMisskeyのアイコンが追加されます。
|
||||||
|
|
||||||
|
このアイコンをタップすることで、Misskeyはアプリモードで起動します。
|
@ -172,6 +172,8 @@ _docs:
|
|||||||
_toc:
|
_toc:
|
||||||
title: "このページの内容"
|
title: "このページの内容"
|
||||||
toPageTop: "ページ上部に戻る"
|
toPageTop: "ページ上部に戻る"
|
||||||
|
_steppedGuide:
|
||||||
|
selectCourse: "ガイドを選ぶ"
|
||||||
|
|
||||||
_blog:
|
_blog:
|
||||||
title: "ブログ"
|
title: "ブログ"
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="grid docs-main">
|
<div
|
||||||
|
class="grid"
|
||||||
|
:class="{
|
||||||
|
[$style.docsLayoutWithAsideToc]: shouldShowToc,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div class="lg:hidden sticky top-16 -mx-6 -mt-6 overflow-y-auto bg-slate-50 dark:bg-slate-900 z-[9890] border-b dark:border-slate-700 text-sm flex items-start">
|
<div class="lg:hidden sticky top-16 -mx-6 -mt-6 overflow-y-auto bg-slate-50 dark:bg-slate-900 z-[9890] border-b dark:border-slate-700 text-sm flex items-start">
|
||||||
<details v-if="data?.body && (data.body.toc?.links ?? []).length > 0" class="peer order-2 flex-grow flex-shrink-0" :open="openState">
|
<details v-if="shouldShowToc && data?.body && (data.body.toc?.links ?? []).length > 0" class="peer order-2 flex-grow flex-shrink-0" :open="openState">
|
||||||
<summary class="py-4 cursor-pointer">
|
<summary class="py-4 cursor-pointer">
|
||||||
{{ $t('_docs._toc.title') }}
|
{{ $t('_docs._toc.title') }}
|
||||||
</summary>
|
</summary>
|
||||||
@ -13,8 +18,7 @@
|
|||||||
<AsideNavIco class="block w-5 h-5" />
|
<AsideNavIco class="block w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-6 p-0 sm:p-12 lg:p-6 w-full overflow-x-hidden">
|
<div class="pt-6 p-0 sm:p-12 lg:p-6 w-full">
|
||||||
<template v-if="data?.body">
|
|
||||||
<Tip v-if="locale !== 'ja'" class="mb-6" :label="$t('_i18n._missing.title')">
|
<Tip v-if="locale !== 'ja'" class="mb-6" :label="$t('_i18n._missing.title')">
|
||||||
<I18nT scope="global" keypath="_i18n._missing.description" tag="p">
|
<I18nT scope="global" keypath="_i18n._missing.description" tag="p">
|
||||||
<template #link>
|
<template #link>
|
||||||
@ -22,6 +26,67 @@
|
|||||||
</template>
|
</template>
|
||||||
</I18nT>
|
</I18nT>
|
||||||
</Tip>
|
</Tip>
|
||||||
|
<div v-if="data?._TYPE_ === 'STEPPED_GUIDE'" class="grid" :class="$style.steppedGuideRoot">
|
||||||
|
<div class="markdown-body w-full lg:col-span-2 mb-6">
|
||||||
|
<h1>{{ data.title }}</h1>
|
||||||
|
<MDC :value="data?.body" />
|
||||||
|
<div>
|
||||||
|
<label for="guideSelector" class="block">{{ $t('_docs._steppedGuide.selectCourse') }}</label>
|
||||||
|
<select id="guideSelector" class="form-select" :disabled="data.guides.length <= 1" v-model="guideIndex">
|
||||||
|
<option v-for="guide, i in data.guides" :value="i">{{ guide.title }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Tip v-if="data.guides[guideIndex]?.description" class="mb-6 lg:col-span-2 markdown-body">
|
||||||
|
<MDC :value="data.guides[guideIndex].description" />
|
||||||
|
</Tip>
|
||||||
|
<div>
|
||||||
|
<ol class="relative before:absolute before:left-[13px] before:top-3.5 before:w-0.5 before:h-[calc(100%-.875rem)] before:rounded-full before:bg-gray-300 space-y-8">
|
||||||
|
<li
|
||||||
|
v-for="(step, i) in data.guides[guideIndex].steps"
|
||||||
|
:key="i"
|
||||||
|
:id="`steppedGuideSection_${guideIndex}_${i}`"
|
||||||
|
class="ml-7 relative flex items-center"
|
||||||
|
:class="{
|
||||||
|
'lg:min-h-[calc(100vh-4rem)] steppedGuideSection': (data.guides[guideIndex]._LAYOUT_TYPE_ === 'IMAGE_PORTRAIT_FIXED'),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center space-x-4 mb-4">
|
||||||
|
<div class="w-7 h-7 rounded-full flex-shrink-0 -ml-7 font-bold leading-7 text-center text-white bg-accent-600 ring-4 ring-white">{{ i + 1 }}</div>
|
||||||
|
<h3 class="font-bold text-lg">{{ step.title }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<img
|
||||||
|
v-if="step?.image"
|
||||||
|
:src="`/img/docs/${slugs.join('/')}/${step.image}`"
|
||||||
|
class="w-auto h-full mx-auto max-h-96 mb-4"
|
||||||
|
:class="{
|
||||||
|
'lg:hidden': (data.guides[guideIndex]._LAYOUT_TYPE_ === 'IMAGE_PORTRAIT_FIXED'),
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<MDC v-if="step.description" :value="step.description" class="markdown-body" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div class="hidden lg:block">
|
||||||
|
<div class="sticky top-16 h-[calc(100vh-4rem)] p-6">
|
||||||
|
<div v-if="data.guides[guideIndex]._LAYOUT_TYPE_ === 'IMAGE_PORTRAIT_FIXED'" class="relative h-full">
|
||||||
|
<Transition
|
||||||
|
:enterActiveClass="$style.steppedGuideImage_enterActive"
|
||||||
|
:leaveActiveClass="$style.steppedGuideImage_leaveActive"
|
||||||
|
:enterFromClass="$style.steppedGuideImage_enterFrom"
|
||||||
|
:leaveToClass="$style.steppedGuideImage_leaveTo"
|
||||||
|
>
|
||||||
|
<img v-if="currentStep?.image" :src="`/img/docs/${slugs.join('/')}/${currentStep.image}`" :key="`steppedGuideSection_${currentStep.image}`" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-auto" />
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-else-if="data?.body">
|
||||||
<ContentRenderer v-if="data.body.children.length > 0" :value="data" class="markdown-body w-full mb-6">
|
<ContentRenderer v-if="data.body.children.length > 0" :value="data" class="markdown-body w-full mb-6">
|
||||||
</ContentRenderer>
|
</ContentRenderer>
|
||||||
<div class="mt-8 mb-4 flex flex-wrap justify-end gap-3">
|
<div class="mt-8 mb-4 flex flex-wrap justify-end gap-3">
|
||||||
@ -37,7 +102,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden lg:block text-sm">
|
<div v-if="shouldShowToc" class="hidden lg:block text-sm">
|
||||||
<div class="sticky top-16 h-[calc(100vh-4rem)] overflow-y-auto py-6 pl-6">
|
<div class="sticky top-16 h-[calc(100vh-4rem)] overflow-y-auto py-6 pl-6">
|
||||||
<h3 class="font-bold mb-6">{{ $t('_docs._toc.title') }}</h3>
|
<h3 class="font-bold mb-6">{{ $t('_docs._toc.title') }}</h3>
|
||||||
<DocsTocLinks v-if="data?.body" :links="data?.body.toc?.links" :max-depth="data?.maxTocDepth ?? undefined" class="break-words" />
|
<DocsTocLinks v-if="data?.body" :links="data?.body.toc?.links" :max-depth="data?.maxTocDepth ?? undefined" class="break-words" />
|
||||||
@ -76,6 +141,41 @@ if (!data.value) {
|
|||||||
throw createError({ statusCode: 404, statusMessage: 'page not found', fatal: true });
|
throw createError({ statusCode: 404, statusMessage: 'page not found', fatal: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shouldShowToc = computed(() => data.value?._TYPE_ !== 'STEPPED_GUIDE');
|
||||||
|
const guideIndex = ref<number>(0);
|
||||||
|
const { mainHeading, updateHeadings } = useScrollspy({
|
||||||
|
rootMargin: '-64px 0px 0px 0px',
|
||||||
|
threshold: 0.5,
|
||||||
|
});
|
||||||
|
const currentStep = computed(() => {
|
||||||
|
if (!mainHeading.value || data.value?._TYPE_ !== 'STEPPED_GUIDE') return null;
|
||||||
|
|
||||||
|
const [currentGuideIndex, currentStepIndex] = mainHeading.value.split('_').slice(1).map((v) => parseInt(v, 10));
|
||||||
|
return data.value.guides[currentGuideIndex].steps[currentStepIndex];
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (data.value?._TYPE_ === 'STEPPED_GUIDE') {
|
||||||
|
// User Agentを元に自動選択
|
||||||
|
if (data.value.guides.some((g) => g._AUTOSELECT_TYPE_)) {
|
||||||
|
const ua = navigator.userAgent.toLowerCase();
|
||||||
|
if (ua.includes('iphone') || ua.includes('ipad')) {
|
||||||
|
guideIndex.value = data.value.guides.findIndex((g) => g._AUTOSELECT_TYPE_ === 'OS_IOS');
|
||||||
|
} else if (ua.includes('android')) {
|
||||||
|
guideIndex.value = data.value.guides.findIndex((g) => g._AUTOSELECT_TYPE_ === 'OS_ANDROID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
watch(guideIndex, () => {
|
||||||
|
updateHeadings([
|
||||||
|
...document.querySelectorAll('.steppedGuideSection'),
|
||||||
|
]);
|
||||||
|
}, { immediate: true });
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (data.value._file && /index\.[a-z]+$/.test(data.value._file)) {
|
if (data.value._file && /index\.[a-z]+$/.test(data.value._file)) {
|
||||||
route.meta.__isDocsIndexPage = true;
|
route.meta.__isDocsIndexPage = true;
|
||||||
}
|
}
|
||||||
@ -86,14 +186,29 @@ if (data.value.description) {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style module>
|
||||||
.docs-main {
|
.docsLayoutWithAsideToc,
|
||||||
|
.steppedGuideRoot {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.steppedGuideImage_enterActive,
|
||||||
|
.steppedGuideImage_leaveActive {
|
||||||
|
transition: opacity 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.steppedGuideImage_enterFrom,
|
||||||
|
.steppedGuideImage_leaveTo {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@screen lg {
|
@screen lg {
|
||||||
.docs-main {
|
.docsLayoutWithAsideToc {
|
||||||
grid-template-columns: 1fr 14rem;
|
grid-template-columns: 1fr 14rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.steppedGuideRoot {
|
||||||
|
grid-template-columns: 1fr 20rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 62 KiB |
@ -1,18 +1,41 @@
|
|||||||
// Misskey Docs Frontmatter Types
|
// Misskey Docs Frontmatter Types
|
||||||
import type { ParsedContent, MarkdownParsedContent } from '@nuxt/content/dist/runtime/types';
|
import type { ParsedContent, MarkdownParsedContent, MarkdownRoot } from '@nuxt/content/dist/runtime/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Docs Frontmatter の型定義
|
* Docs Frontmatter の型定義
|
||||||
*
|
*
|
||||||
* `/content/<lang>/docs/` のフロントマターはこの形式で入力してください
|
* `/content/<lang>/docs/` のフロントマターはこの形式で入力してください
|
||||||
*/
|
*/
|
||||||
export interface MiDocsParsedContent extends MarkdownParsedContent {
|
interface MiDocsParsedContentMd extends MarkdownParsedContent {
|
||||||
|
_TYPE_: undefined;
|
||||||
|
|
||||||
/** もくじの見出しをさかのぼる限度 */
|
/** もくじの見出しをさかのぼる限度 */
|
||||||
maxTocDepth?: number;
|
maxTocDepth?: number;
|
||||||
|
|
||||||
/** 前へ・次へボタンの階層考慮を無視 */
|
/** 前へ・次へボタンの階層考慮を無視 */
|
||||||
ignoreDirBasedNav?: boolean;
|
ignoreDirBasedNav?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ステップバイステップガイドの型定義
|
||||||
|
*/
|
||||||
|
interface MiDocsParsedContentSteppedGuide extends ParsedContent {
|
||||||
|
_TYPE_: 'STEPPED_GUIDE';
|
||||||
|
|
||||||
|
guides: {
|
||||||
|
_AUTOSELECT_TYPE_?: 'OS_ANDROID' | 'OS_IOS';
|
||||||
|
_LAYOUT_TYPE_?: 'IMAGE_PORTRAIT_FIXED';
|
||||||
|
title: string;
|
||||||
|
description?: string | MarkdownRoot;
|
||||||
|
steps: {
|
||||||
|
title: string;
|
||||||
|
description: string | MarkdownRoot;
|
||||||
|
image?: string;
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MiDocsParsedContent = MiDocsParsedContentMd | MiDocsParsedContentSteppedGuide;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blog Frontmatter の型定義
|
* Blog Frontmatter の型定義
|
||||||
|