@ohos-ports/histoire-app 1.0.0-beta.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/LICENSE +21 -0
- package/dist/app/assets/histoire-text-dark.svg +89 -0
- package/dist/app/assets/histoire-text.svg +89 -0
- package/dist/app/assets/histoire.svg +51 -0
- package/dist/app/style/floating.pcss +34 -0
- package/dist/app/style/main.pcss +100 -0
- package/dist/app/style/sandbox.css +24 -0
- package/dist/app/style/transitions.pcss +51 -0
- package/dist/bundle-index.js +3 -0
- package/dist/bundle-main-dev.js +4 -0
- package/dist/bundle-main.js +5 -0
- package/dist/bundle-sandbox-dev.js +2 -0
- package/dist/bundle-sandbox.js +2 -0
- package/dist/bundled/App.vue.js +5 -0
- package/dist/bundled/App.vue2.js +167 -0
- package/dist/bundled/_virtual/_node-dom-env.js +188 -0
- package/dist/bundled/_virtual/_node-dom-polyfill.js +152 -0
- package/dist/bundled/_virtual/_plugin-vue_export-helper.js +10 -0
- package/dist/bundled/_virtual/histoire-commands.js +8 -0
- package/dist/bundled/_virtual/histoire-config.js +42 -0
- package/dist/bundled/_virtual/histoire-markdown-files.js +8 -0
- package/dist/bundled/_virtual/histoire-search-docs-data.js +11 -0
- package/dist/bundled/_virtual/histoire-search-title-data.js +11 -0
- package/dist/bundled/_virtual/histoire-stories.js +17 -0
- package/dist/bundled/_virtual/histoire-support-plugins-client.js +8 -0
- package/dist/bundled/_virtual/histoire-theme.js +8 -0
- package/dist/bundled/api.js +12 -0
- package/dist/bundled/app.css +116 -0
- package/dist/bundled/assets/histoire-text-dark.svg.js +4 -0
- package/dist/bundled/assets/histoire-text.svg.js +4 -0
- package/dist/bundled/assets/histoire.svg.js +4 -0
- package/dist/bundled/components/HomeView.vue.js +5 -0
- package/dist/bundled/components/HomeView.vue2.js +66 -0
- package/dist/bundled/components/app/AppHeader.vue.js +5 -0
- package/dist/bundled/components/app/AppHeader.vue2.js +71 -0
- package/dist/bundled/components/app/AppLogo.vue.js +5 -0
- package/dist/bundled/components/app/AppLogo.vue2.js +29 -0
- package/dist/bundled/components/app/Breadcrumb.vue.js +8 -0
- package/dist/bundled/components/app/Breadcrumb.vue2.js +91 -0
- package/dist/bundled/components/app/HomeCounter.vue.js +5 -0
- package/dist/bundled/components/app/HomeCounter.vue2.js +42 -0
- package/dist/bundled/components/app/InitialLoading.vue.js +5 -0
- package/dist/bundled/components/app/InitialLoading.vue2.js +51 -0
- package/dist/bundled/components/app/MobileOverlay.vue.js +5 -0
- package/dist/bundled/components/app/MobileOverlay.vue2.js +45 -0
- package/dist/bundled/components/base/BaseButton.vue.js +5 -0
- package/dist/bundled/components/base/BaseButton.vue2.js +39 -0
- package/dist/bundled/components/base/BaseCheckbox.vue.js +5 -0
- package/dist/bundled/components/base/BaseCheckbox.vue2.js +78 -0
- package/dist/bundled/components/base/BaseEmpty.vue.js +14 -0
- package/dist/bundled/components/base/BaseIcon.vue.js +8 -0
- package/dist/bundled/components/base/BaseIcon.vue2.js +29 -0
- package/dist/bundled/components/base/BaseKeyboardShortcut.vue.js +5 -0
- package/dist/bundled/components/base/BaseKeyboardShortcut.vue2.js +20 -0
- package/dist/bundled/components/base/BaseListItem.vue.js +5 -0
- package/dist/bundled/components/base/BaseListItem.vue2.js +33 -0
- package/dist/bundled/components/base/BaseListItemLink.vue.js +33 -0
- package/dist/bundled/components/base/BaseListItemLink.vue2.js +26 -0
- package/dist/bundled/components/base/BaseOverflowMenu.vue.js +5 -0
- package/dist/bundled/components/base/BaseOverflowMenu.vue2.js +100 -0
- package/dist/bundled/components/base/BaseOverflowTab.vue.js +36 -0
- package/dist/bundled/components/base/BaseOverflowTab.vue2.js +18 -0
- package/dist/bundled/components/base/BaseSelect.vue.js +5 -0
- package/dist/bundled/components/base/BaseSelect.vue2.js +77 -0
- package/dist/bundled/components/base/BaseSplitPane.vue.js +8 -0
- package/dist/bundled/components/base/BaseSplitPane.vue2.js +183 -0
- package/dist/bundled/components/base/BaseTab.vue.js +36 -0
- package/dist/bundled/components/base/BaseTab.vue2.js +18 -0
- package/dist/bundled/components/base/BaseTag.vue.js +13 -0
- package/dist/bundled/components/command/CommandPrompts.vue.js +5 -0
- package/dist/bundled/components/command/CommandPrompts.vue2.js +91 -0
- package/dist/bundled/components/command/CommandPromptsModal.vue.js +5 -0
- package/dist/bundled/components/command/CommandPromptsModal.vue2.js +45 -0
- package/dist/bundled/components/command/PromptSelect.vue.js +5 -0
- package/dist/bundled/components/command/PromptSelect.vue2.js +142 -0
- package/dist/bundled/components/command/PromptText.vue.js +5 -0
- package/dist/bundled/components/command/PromptText.vue2.js +67 -0
- package/dist/bundled/components/misc/CheckerboardPattern.vue.js +40 -0
- package/dist/bundled/components/misc/HatchedPattern.vue.js +12 -0
- package/dist/bundled/components/panel/ControlsComponentPropItem.vue.js +5 -0
- package/dist/bundled/components/panel/ControlsComponentPropItem.vue2.js +72 -0
- package/dist/bundled/components/panel/ControlsComponentProps.vue.js +5 -0
- package/dist/bundled/components/panel/ControlsComponentProps.vue2.js +45 -0
- package/dist/bundled/components/panel/ControlsComponentState.vue.js +5 -0
- package/dist/bundled/components/panel/ControlsComponentState.vue2.js +41 -0
- package/dist/bundled/components/panel/ControlsComponentStateItem.vue.js +5 -0
- package/dist/bundled/components/panel/ControlsComponentStateItem.vue2.js +46 -0
- package/dist/bundled/components/panel/PaneTabs.vue.js +5 -0
- package/dist/bundled/components/panel/PaneTabs.vue2.js +114 -0
- package/dist/bundled/components/panel/StatePresets.vue.js +5 -0
- package/dist/bundled/components/panel/StatePresets.vue2.js +193 -0
- package/dist/bundled/components/panel/StoryControls.vue.js +5 -0
- package/dist/bundled/components/panel/StoryControls.vue2.js +87 -0
- package/dist/bundled/components/panel/StoryDocs.vue.js +7 -0
- package/dist/bundled/components/panel/StoryDocs.vue2.js +161 -0
- package/dist/bundled/components/panel/StoryEvent.vue.js +5 -0
- package/dist/bundled/components/panel/StoryEvent.vue2.js +59 -0
- package/dist/bundled/components/panel/StoryEvents.vue.js +5 -0
- package/dist/bundled/components/panel/StoryEvents.vue2.js +53 -0
- package/dist/bundled/components/panel/StorySidePanel.vue.js +5 -0
- package/dist/bundled/components/panel/StorySidePanel.vue2.js +83 -0
- package/dist/bundled/components/panel/StorySourceCode.vue.js +8 -0
- package/dist/bundled/components/panel/StorySourceCode.vue2.js +204 -0
- package/dist/bundled/components/search/SearchItem.vue.js +8 -0
- package/dist/bundled/components/search/SearchItem.vue2.js +93 -0
- package/dist/bundled/components/search/SearchItemContent.vue.js +5 -0
- package/dist/bundled/components/search/SearchItemContent.vue2.js +71 -0
- package/dist/bundled/components/search/SearchLoading.vue.js +5 -0
- package/dist/bundled/components/search/SearchLoading.vue2.js +21 -0
- package/dist/bundled/components/search/SearchModal.vue.js +5 -0
- package/dist/bundled/components/search/SearchModal.vue2.js +51 -0
- package/dist/bundled/components/search/SearchPane.vue.js +5 -0
- package/dist/bundled/components/search/SearchPane.vue2.js +272 -0
- package/dist/bundled/components/search/search-docs-data.js +11 -0
- package/dist/bundled/components/search/search-title-data.js +11 -0
- package/dist/bundled/components/story/GenericMountStory.vue.js +5 -0
- package/dist/bundled/components/story/GenericMountStory.vue2.js +34 -0
- package/dist/bundled/components/story/GenericRenderStory.vue.js +5 -0
- package/dist/bundled/components/story/GenericRenderStory.vue2.js +39 -0
- package/dist/bundled/components/story/StoryResponsivePreview.vue.js +8 -0
- package/dist/bundled/components/story/StoryResponsivePreview.vue2.js +207 -0
- package/dist/bundled/components/story/StoryVariantGrid.vue.js +5 -0
- package/dist/bundled/components/story/StoryVariantGrid.vue2.js +146 -0
- package/dist/bundled/components/story/StoryVariantGridItem.vue.js +8 -0
- package/dist/bundled/components/story/StoryVariantGridItem.vue2.js +153 -0
- package/dist/bundled/components/story/StoryVariantListItem.vue.js +8 -0
- package/dist/bundled/components/story/StoryVariantListItem.vue2.js +55 -0
- package/dist/bundled/components/story/StoryVariantSingle.vue.js +8 -0
- package/dist/bundled/components/story/StoryVariantSingle.vue2.js +107 -0
- package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue.js +5 -0
- package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue2.js +70 -0
- package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue.js +5 -0
- package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue2.js +128 -0
- package/dist/bundled/components/story/StoryVariantSingleView.vue.js +5 -0
- package/dist/bundled/components/story/StoryVariantSingleView.vue2.js +66 -0
- package/dist/bundled/components/story/StoryView.vue.js +5 -0
- package/dist/bundled/components/story/StoryView.vue2.js +104 -0
- package/dist/bundled/components/story/StoryViewer.vue.js +8 -0
- package/dist/bundled/components/story/StoryViewer.vue2.js +55 -0
- package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue.js +5 -0
- package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue2.js +31 -0
- package/dist/bundled/components/toolbar/ToolbarBackground.vue.js +8 -0
- package/dist/bundled/components/toolbar/ToolbarBackground.vue2.js +98 -0
- package/dist/bundled/components/toolbar/ToolbarNewTab.vue.js +5 -0
- package/dist/bundled/components/toolbar/ToolbarNewTab.vue2.js +36 -0
- package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue.js +5 -0
- package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue2.js +127 -0
- package/dist/bundled/components/toolbar/ToolbarTextDirection.vue.js +5 -0
- package/dist/bundled/components/toolbar/ToolbarTextDirection.vue2.js +27 -0
- package/dist/bundled/components/toolbar/ToolbarTitle.vue.js +5 -0
- package/dist/bundled/components/toolbar/ToolbarTitle.vue2.js +26 -0
- package/dist/bundled/components/tree/StoryGroup.vue.js +5 -0
- package/dist/bundled/components/tree/StoryGroup.vue2.js +74 -0
- package/dist/bundled/components/tree/StoryList.vue.js +5 -0
- package/dist/bundled/components/tree/StoryList.vue2.js +41 -0
- package/dist/bundled/components/tree/StoryListFolder.vue.js +8 -0
- package/dist/bundled/components/tree/StoryListFolder.vue2.js +86 -0
- package/dist/bundled/components/tree/StoryListItem.vue.js +8 -0
- package/dist/bundled/components/tree/StoryListItem.vue2.js +69 -0
- package/dist/bundled/index.js +36 -0
- package/dist/bundled/plugin.js +49 -0
- package/dist/bundled/router.js +32 -0
- package/dist/bundled/sandbox.js +87 -0
- package/dist/bundled/stores/command.js +25 -0
- package/dist/bundled/stores/events.js +29 -0
- package/dist/bundled/stores/folder.js +54 -0
- package/dist/bundled/stores/preview-settings.js +19 -0
- package/dist/bundled/stores/story.js +43 -0
- package/dist/bundled/util/commands.js +57 -0
- package/dist/bundled/util/config.js +8 -0
- package/dist/bundled/util/const.js +10 -0
- package/dist/bundled/util/dark.js +28 -0
- package/dist/bundled/util/docs.js +26 -0
- package/dist/bundled/util/env.js +4 -0
- package/dist/bundled/util/events.js +33 -0
- package/dist/bundled/util/keyboard.js +90 -0
- package/dist/bundled/util/mapping.js +70 -0
- package/dist/bundled/util/open-in-editor.js +7 -0
- package/dist/bundled/util/preview-settings.js +21 -0
- package/dist/bundled/util/responsive.js +6 -0
- package/dist/bundled/util/sandbox.js +11 -0
- package/dist/bundled/util/scroll.js +31 -0
- package/dist/bundled/util/select.js +28 -0
- package/dist/bundled/util/state.js +41 -0
- package/dist/bundled/util/tooltip.js +15 -0
- package/dist/bundled/util/variant.js +21 -0
- package/dist/style.css +2853 -0
- package/package.json +62 -0
- package/postcss-scope-wrapper.cjs +35 -0
- package/postcss.config.cjs +9 -0
- package/scripts/copy.mjs +12 -0
- package/scripts/watchAndCopy.mjs +15 -0
- package/src/app/App.vue +172 -0
- package/src/app/api.ts +9 -0
- package/src/app/assets/histoire-text-dark.svg +89 -0
- package/src/app/assets/histoire-text.svg +89 -0
- package/src/app/assets/histoire.svg +51 -0
- package/src/app/components/HomeView.vue +61 -0
- package/src/app/components/app/AppHeader.vue +65 -0
- package/src/app/components/app/AppLogo.vue +25 -0
- package/src/app/components/app/Breadcrumb.vue +98 -0
- package/src/app/components/app/HomeCounter.vue +39 -0
- package/src/app/components/app/InitialLoading.vue +44 -0
- package/src/app/components/app/MobileOverlay.vue +33 -0
- package/src/app/components/base/BaseButton.vue +33 -0
- package/src/app/components/base/BaseCheckbox.vue +76 -0
- package/src/app/components/base/BaseCopyIcon.vue +34 -0
- package/src/app/components/base/BaseEmpty.vue +21 -0
- package/src/app/components/base/BaseIcon.vue +31 -0
- package/src/app/components/base/BaseKeyboardShortcut.vue +16 -0
- package/src/app/components/base/BaseListItem.vue +30 -0
- package/src/app/components/base/BaseListItemLink.vue +56 -0
- package/src/app/components/base/BaseOverflowMenu.vue +119 -0
- package/src/app/components/base/BaseOverflowTab.vue +47 -0
- package/src/app/components/base/BaseSelect.vue +75 -0
- package/src/app/components/base/BaseSplitPane.vue +244 -0
- package/src/app/components/base/BaseTab.vue +47 -0
- package/src/app/components/base/BaseTag.vue +5 -0
- package/src/app/components/command/CommandPrompts.vue +95 -0
- package/src/app/components/command/CommandPromptsModal.vue +41 -0
- package/src/app/components/command/PromptSelect.vue +142 -0
- package/src/app/components/command/PromptText.vue +65 -0
- package/src/app/components/misc/CheckerboardPattern.vue +32 -0
- package/src/app/components/misc/HatchedPattern.vue +13 -0
- package/src/app/components/panel/ControlsComponentPropItem.vue +73 -0
- package/src/app/components/panel/ControlsComponentProps.vue +34 -0
- package/src/app/components/panel/ControlsComponentState.vue +38 -0
- package/src/app/components/panel/ControlsComponentStateItem.vue +44 -0
- package/src/app/components/panel/PaneTabs.vue +84 -0
- package/src/app/components/panel/StatePresets.vue +199 -0
- package/src/app/components/panel/StoryControls.vue +97 -0
- package/src/app/components/panel/StoryDocs.vue +202 -0
- package/src/app/components/panel/StoryEvent.vue +54 -0
- package/src/app/components/panel/StoryEvents.vue +48 -0
- package/src/app/components/panel/StorySidePanel.vue +76 -0
- package/src/app/components/panel/StorySourceCode.vue +248 -0
- package/src/app/components/search/SearchItem.vue +89 -0
- package/src/app/components/search/SearchItemContent.vue +67 -0
- package/src/app/components/search/SearchLoading.vue +16 -0
- package/src/app/components/search/SearchModal.vue +44 -0
- package/src/app/components/search/SearchPane.vue +319 -0
- package/src/app/components/search/search-docs-data.ts +9 -0
- package/src/app/components/search/search-title-data.ts +9 -0
- package/src/app/components/search/types.ts +4 -0
- package/src/app/components/story/GenericMountStory.vue +35 -0
- package/src/app/components/story/GenericRenderStory.vue +41 -0
- package/src/app/components/story/StoryResponsivePreview.vue +216 -0
- package/src/app/components/story/StoryVariantGrid.vue +169 -0
- package/src/app/components/story/StoryVariantGridItem.vue +163 -0
- package/src/app/components/story/StoryVariantListItem.vue +52 -0
- package/src/app/components/story/StoryVariantSingle.vue +105 -0
- package/src/app/components/story/StoryVariantSinglePreviewNative.vue +66 -0
- package/src/app/components/story/StoryVariantSinglePreviewRemote.vue +143 -0
- package/src/app/components/story/StoryVariantSingleView.vue +61 -0
- package/src/app/components/story/StoryView.vue +110 -0
- package/src/app/components/story/StoryViewer.vue +52 -0
- package/src/app/components/toolbar/DevOnlyToolbarOpenInEditor.vue +23 -0
- package/src/app/components/toolbar/ToolbarBackground.vue +81 -0
- package/src/app/components/toolbar/ToolbarNewTab.vue +29 -0
- package/src/app/components/toolbar/ToolbarResponsiveSize.vue +82 -0
- package/src/app/components/toolbar/ToolbarTextDirection.vue +19 -0
- package/src/app/components/toolbar/ToolbarTitle.vue +21 -0
- package/src/app/components/tree/StoryGroup.vue +73 -0
- package/src/app/components/tree/StoryList.vue +35 -0
- package/src/app/components/tree/StoryListFolder.vue +88 -0
- package/src/app/components/tree/StoryListItem.vue +72 -0
- package/src/app/index.ts +33 -0
- package/src/app/plugin.ts +59 -0
- package/src/app/router.ts +29 -0
- package/src/app/sandbox.ts +101 -0
- package/src/app/stores/command.ts +26 -0
- package/src/app/stores/events.ts +36 -0
- package/src/app/stores/folder.ts +63 -0
- package/src/app/stores/preview-settings.ts +18 -0
- package/src/app/stores/story.ts +47 -0
- package/src/app/style/floating.pcss +34 -0
- package/src/app/style/main.pcss +100 -0
- package/src/app/style/sandbox.css +24 -0
- package/src/app/style/transitions.pcss +51 -0
- package/src/app/types.ts +72 -0
- package/src/app/util/commands.ts +57 -0
- package/src/app/util/config.ts +5 -0
- package/src/app/util/const.ts +4 -0
- package/src/app/util/dark.ts +27 -0
- package/src/app/util/docs.ts +27 -0
- package/src/app/util/env.ts +1 -0
- package/src/app/util/events.ts +31 -0
- package/src/app/util/keyboard.ts +103 -0
- package/src/app/util/mapping.ts +80 -0
- package/src/app/util/open-in-editor.ts +3 -0
- package/src/app/util/preview-settings.ts +23 -0
- package/src/app/util/responsive.ts +3 -0
- package/src/app/util/sandbox.ts +9 -0
- package/src/app/util/scroll.ts +32 -0
- package/src/app/util/select.ts +30 -0
- package/src/app/util/state.ts +45 -0
- package/src/app/util/tooltip.ts +13 -0
- package/src/app/util/variant.ts +21 -0
- package/src/bundle-index.js +1 -0
- package/src/bundle-main-dev.js +4 -0
- package/src/bundle-main.js +5 -0
- package/src/bundle-sandbox-dev.js +2 -0
- package/src/bundle-sandbox.js +2 -0
- package/src/index.ts +1 -0
- package/src/shim.d.ts +10 -0
- package/src/virtual.d.ts +7 -0
- package/tailwind.config.cjs +137 -0
- package/tsconfig.json +53 -0
- package/vite.config.ts +88 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Story, Variant } from '../../types'
|
|
3
|
+
import { isMobile } from '../../util/responsive'
|
|
4
|
+
import DevOnlyToolbarOpenInEditor from '../toolbar/DevOnlyToolbarOpenInEditor.vue'
|
|
5
|
+
import ToolbarBackground from '../toolbar/ToolbarBackground.vue'
|
|
6
|
+
import ToolbarNewTab from '../toolbar/ToolbarNewTab.vue'
|
|
7
|
+
import ToolbarResponsiveSize from '../toolbar/ToolbarResponsiveSize.vue'
|
|
8
|
+
import ToolbarTextDirection from '../toolbar/ToolbarTextDirection.vue'
|
|
9
|
+
import ToolbarTitle from '../toolbar/ToolbarTitle.vue'
|
|
10
|
+
import StoryVariantSinglePreviewNative from './StoryVariantSinglePreviewNative.vue'
|
|
11
|
+
import StoryVariantSinglePreviewRemote from './StoryVariantSinglePreviewRemote.vue'
|
|
12
|
+
|
|
13
|
+
defineProps<{
|
|
14
|
+
variant: Variant
|
|
15
|
+
story: Story
|
|
16
|
+
}>()
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<div
|
|
21
|
+
class="histoire-story-variant-single-view htw-h-full htw-flex htw-flex-col"
|
|
22
|
+
data-test-id="story-variant-single-view"
|
|
23
|
+
>
|
|
24
|
+
<!-- Toolbar -->
|
|
25
|
+
<div
|
|
26
|
+
v-if="!isMobile"
|
|
27
|
+
class="htw-flex-none htw-flex htw-items-center htw-h-8 -htw-mt-1"
|
|
28
|
+
>
|
|
29
|
+
<ToolbarTitle
|
|
30
|
+
:variant="variant"
|
|
31
|
+
/>
|
|
32
|
+
<ToolbarResponsiveSize
|
|
33
|
+
v-if="!variant.responsiveDisabled"
|
|
34
|
+
/>
|
|
35
|
+
<ToolbarBackground />
|
|
36
|
+
<ToolbarTextDirection />
|
|
37
|
+
<ToolbarNewTab
|
|
38
|
+
:variant="variant"
|
|
39
|
+
:story="story"
|
|
40
|
+
/>
|
|
41
|
+
|
|
42
|
+
<DevOnlyToolbarOpenInEditor
|
|
43
|
+
v-if="__HISTOIRE_DEV__"
|
|
44
|
+
:file="story.file?.filePath"
|
|
45
|
+
tooltip="Edit story in editor"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Preview -->
|
|
50
|
+
<StoryVariantSinglePreviewNative
|
|
51
|
+
v-if="story.layout?.iframe === false"
|
|
52
|
+
:story="story"
|
|
53
|
+
:variant="variant"
|
|
54
|
+
/>
|
|
55
|
+
<StoryVariantSinglePreviewRemote
|
|
56
|
+
v-else
|
|
57
|
+
:story="story"
|
|
58
|
+
:variant="variant"
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { ref, watch } from 'vue'
|
|
4
|
+
import { useRoute, useRouter } from 'vue-router'
|
|
5
|
+
import { useStoryStore } from '../../stores/story'
|
|
6
|
+
|
|
7
|
+
import { isMobile } from '../../util/responsive'
|
|
8
|
+
import BaseEmpty from '../base/BaseEmpty.vue'
|
|
9
|
+
import BaseSplitPane from '../base/BaseSplitPane.vue'
|
|
10
|
+
import StoryDocs from '../panel/StoryDocs.vue'
|
|
11
|
+
import StorySidePanel from '../panel/StorySidePanel.vue'
|
|
12
|
+
import StoryViewer from './StoryViewer.vue'
|
|
13
|
+
|
|
14
|
+
const storyStore = useStoryStore()
|
|
15
|
+
|
|
16
|
+
const router = useRouter()
|
|
17
|
+
const route = useRoute()
|
|
18
|
+
|
|
19
|
+
// Restore variant selection
|
|
20
|
+
|
|
21
|
+
watch(() => storyStore.currentVariant, (value) => {
|
|
22
|
+
if (value) {
|
|
23
|
+
storyStore.currentStory.lastSelectedVariant = value
|
|
24
|
+
}
|
|
25
|
+
}, {
|
|
26
|
+
immediate: true,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
watch(() => [storyStore.currentStory, storyStore.currentVariant], () => {
|
|
30
|
+
if (!storyStore.currentVariant) {
|
|
31
|
+
if (storyStore.currentStory?.lastSelectedVariant) {
|
|
32
|
+
setVariant(storyStore.currentStory.lastSelectedVariant.id)
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (storyStore.currentStory?.variants.length === 1) {
|
|
37
|
+
setVariant(storyStore.currentStory.variants[0].id)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, {
|
|
41
|
+
immediate: true,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
function setVariant(variantId: string) {
|
|
45
|
+
router.replace({
|
|
46
|
+
...route,
|
|
47
|
+
query: {
|
|
48
|
+
...route.query,
|
|
49
|
+
variantId,
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Docs auto-scroll to top
|
|
55
|
+
|
|
56
|
+
const docsOnlyScroller = ref<HTMLElement>(null)
|
|
57
|
+
|
|
58
|
+
function scrollDocsToTop() {
|
|
59
|
+
docsOnlyScroller.value?.scrollTo(0, 0)
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<BaseEmpty
|
|
65
|
+
v-if="!storyStore.currentStory"
|
|
66
|
+
class="histoire-story-view histoire-no-story"
|
|
67
|
+
>
|
|
68
|
+
<Icon
|
|
69
|
+
icon="carbon:software-resource-resource"
|
|
70
|
+
class="htw-w-16 htw-h-16 htw-opacity-50"
|
|
71
|
+
/>
|
|
72
|
+
</BaseEmpty>
|
|
73
|
+
|
|
74
|
+
<div
|
|
75
|
+
v-else
|
|
76
|
+
class="histoire-story-view histoire-with-story htw-h-full"
|
|
77
|
+
>
|
|
78
|
+
<div
|
|
79
|
+
v-if="storyStore.currentStory.docsOnly"
|
|
80
|
+
ref="docsOnlyScroller"
|
|
81
|
+
class="htw-h-full htw-overflow-auto"
|
|
82
|
+
>
|
|
83
|
+
<StoryDocs
|
|
84
|
+
:story="storyStore.currentStory"
|
|
85
|
+
standalone
|
|
86
|
+
class="md:htw-p-12 htw-w-full md:htw-max-w-[600px] lg:htw-max-w-[800px] xl:htw-max-w-[900px]"
|
|
87
|
+
@scroll-top="scrollDocsToTop()"
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
<template v-else-if="isMobile">
|
|
91
|
+
<StoryViewer />
|
|
92
|
+
</template>
|
|
93
|
+
<BaseSplitPane
|
|
94
|
+
v-else
|
|
95
|
+
save-id="story-main"
|
|
96
|
+
:min="30"
|
|
97
|
+
:max="95"
|
|
98
|
+
:default-split="75"
|
|
99
|
+
class="htw-h-full"
|
|
100
|
+
>
|
|
101
|
+
<template #first>
|
|
102
|
+
<StoryViewer />
|
|
103
|
+
</template>
|
|
104
|
+
|
|
105
|
+
<template #last>
|
|
106
|
+
<StorySidePanel />
|
|
107
|
+
</template>
|
|
108
|
+
</BaseSplitPane>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import { useStoryStore } from '../../stores/story'
|
|
4
|
+
import MobileOverlay from '../app/MobileOverlay.vue'
|
|
5
|
+
import StoryVariantGrid from './StoryVariantGrid.vue'
|
|
6
|
+
import StoryVariantListItem from './StoryVariantListItem.vue'
|
|
7
|
+
import StoryVariantSingle from './StoryVariantSingle.vue'
|
|
8
|
+
|
|
9
|
+
const storyStore = useStoryStore()
|
|
10
|
+
|
|
11
|
+
const variant = computed(() => storyStore.currentVariant)
|
|
12
|
+
|
|
13
|
+
const isMenuOpened = ref(false)
|
|
14
|
+
|
|
15
|
+
function closeMenu() {
|
|
16
|
+
isMenuOpened.value = false
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
watch(variant, () => {
|
|
20
|
+
isMenuOpened.value = false
|
|
21
|
+
})
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<div class="histoire-story-viewer htw-bg-gray-50 htw-h-full dark:htw-bg-gray-750">
|
|
26
|
+
<StoryVariantGrid
|
|
27
|
+
v-if="storyStore.currentStory.layout.type === 'grid'"
|
|
28
|
+
/>
|
|
29
|
+
<StoryVariantSingle
|
|
30
|
+
v-else-if="storyStore.currentStory.layout.type === 'single'"
|
|
31
|
+
@open-variant-menu="isMenuOpened = true"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<MobileOverlay
|
|
36
|
+
title="Select a variant"
|
|
37
|
+
:opened="isMenuOpened"
|
|
38
|
+
@close="closeMenu"
|
|
39
|
+
>
|
|
40
|
+
<StoryVariantListItem
|
|
41
|
+
v-for="(v, index) of storyStore.currentStory.variants"
|
|
42
|
+
:key="index"
|
|
43
|
+
:variant="v"
|
|
44
|
+
/>
|
|
45
|
+
</MobileOverlay>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<style scoped>
|
|
49
|
+
.bind-icon-color {
|
|
50
|
+
color: v-bind('variant?.iconColor');
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { openInEditor } from '../../util/open-in-editor.js'
|
|
4
|
+
|
|
5
|
+
defineProps<{
|
|
6
|
+
file: string
|
|
7
|
+
tooltip: string
|
|
8
|
+
}>()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<a
|
|
13
|
+
v-tooltip="tooltip"
|
|
14
|
+
target="_blank"
|
|
15
|
+
class="histoire-toolbar-open-in-editor htw-flex htw-items-center htw-gap-1 htw-h-full htw-px-2 hover:htw-text-primary-500 htw-opacity-50 hover:htw-opacity-100 dark:hover:htw-text-primary-400 htw-text-gray-900 dark:htw-text-gray-100"
|
|
16
|
+
@click="openInEditor(file)"
|
|
17
|
+
>
|
|
18
|
+
<Icon
|
|
19
|
+
icon="carbon:script-reference"
|
|
20
|
+
class="htw-w-4 htw-h-4"
|
|
21
|
+
/>
|
|
22
|
+
</a>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
5
|
+
import { histoireConfig } from '../../util/config'
|
|
6
|
+
import { getContrastColor } from '../../util/preview-settings'
|
|
7
|
+
import BaseCheckbox from '../base/BaseCheckbox.vue'
|
|
8
|
+
|
|
9
|
+
const settings = usePreviewSettingsStore().currentSettings
|
|
10
|
+
|
|
11
|
+
const contrastColor = computed(() => getContrastColor(settings))
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<VDropdown
|
|
16
|
+
v-if="histoireConfig.backgroundPresets.length"
|
|
17
|
+
placement="bottom-end"
|
|
18
|
+
:skidding="6"
|
|
19
|
+
class="histoire-toolbar-background htw-h-full htw-flex-none"
|
|
20
|
+
data-test-id="toolbar-background"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
v-tooltip="'Background color'"
|
|
24
|
+
class="htw-cursor-pointer hover:htw-text-primary-500 htw-flex htw-items-center htw-gap-1 htw-h-full htw-px-2 htw-group"
|
|
25
|
+
>
|
|
26
|
+
<div
|
|
27
|
+
class="bind-preview-bg htw-w-4 htw-h-4 htw-rounded-full htw-border htw-border-black/50 dark:htw-border-white/50 htw-flex htw-items-center htw-justify-center htw-text-xs"
|
|
28
|
+
>
|
|
29
|
+
<span v-if="contrastColor">a</span>
|
|
30
|
+
</div>
|
|
31
|
+
<Icon
|
|
32
|
+
icon="carbon:caret-down"
|
|
33
|
+
class="htw-w-4 htw-h-4 htw-opacity-50 group-hover:htw-opacity-100"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<template #popper="{ hide }">
|
|
38
|
+
<div
|
|
39
|
+
class="htw-flex htw-flex-col htw-items-stretch"
|
|
40
|
+
data-test-id="background-popper"
|
|
41
|
+
>
|
|
42
|
+
<BaseCheckbox v-model="settings.checkerboard">
|
|
43
|
+
Checkerboard
|
|
44
|
+
</BaseCheckbox>
|
|
45
|
+
|
|
46
|
+
<button
|
|
47
|
+
v-for="(option, index) in histoireConfig.backgroundPresets"
|
|
48
|
+
:key="index"
|
|
49
|
+
class="htw-px-4 htw-py-3 htw-cursor-pointer htw-text-left htw-flex htw-items-baseline htw-gap-4"
|
|
50
|
+
:class="[
|
|
51
|
+
settings.backgroundColor === option.color
|
|
52
|
+
? 'htw-bg-primary-500 hover:htw-bg-primary-600 htw-text-white dark:htw-text-black'
|
|
53
|
+
: 'htw-bg-transparent hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700',
|
|
54
|
+
]"
|
|
55
|
+
@click="settings.backgroundColor = option.color;hide()"
|
|
56
|
+
>
|
|
57
|
+
<span class="htw-mr-auto">{{ option.label }}</span>
|
|
58
|
+
<template v-if="option.color !== '$checkerboard'">
|
|
59
|
+
<span class="htw-ml-auto htw-opacity-70">{{ option.color }}</span>
|
|
60
|
+
<div
|
|
61
|
+
class="htw-w-4 htw-h-4 htw-rounded-full htw-border htw-border-black/20 dark:htw-border-white/20 htw-flex htw-items-center htw-justify-center htw-text-xs"
|
|
62
|
+
:style="{
|
|
63
|
+
backgroundColor: option.color,
|
|
64
|
+
color: option.contrastColor,
|
|
65
|
+
}"
|
|
66
|
+
>
|
|
67
|
+
<span v-if="option.contrastColor">a</span>
|
|
68
|
+
</div>
|
|
69
|
+
</template>
|
|
70
|
+
</button>
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
73
|
+
</VDropdown>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<style scoped>
|
|
77
|
+
.bind-preview-bg {
|
|
78
|
+
background-color: v-bind('settings.backgroundColor');
|
|
79
|
+
color: v-bind('contrastColor');
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Story, Variant } from '../../types'
|
|
3
|
+
import { Icon } from '@iconify/vue'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { getSandboxUrl } from '../../util/sandbox'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
variant: Variant
|
|
9
|
+
story: Story
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const sandboxUrl = computed(() => {
|
|
13
|
+
return getSandboxUrl(props.story, props.variant)
|
|
14
|
+
})
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<a
|
|
19
|
+
v-tooltip="'Open variant in new tab'"
|
|
20
|
+
:href="sandboxUrl"
|
|
21
|
+
target="_blank"
|
|
22
|
+
class="histoire-toolbar-new-tab htw-flex htw-items-center htw-gap-1 htw-h-full htw-px-2 hover:htw-text-primary-500 htw-opacity-50 hover:htw-opacity-100 dark:hover:htw-text-primary-400 htw-text-gray-900 dark:htw-text-gray-100"
|
|
23
|
+
>
|
|
24
|
+
<Icon
|
|
25
|
+
icon="carbon:launch"
|
|
26
|
+
class="htw-w-4 htw-h-4"
|
|
27
|
+
/>
|
|
28
|
+
</a>
|
|
29
|
+
</template>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
4
|
+
import { histoireConfig } from '../../util/config'
|
|
5
|
+
import BaseCheckbox from '../base/BaseCheckbox.vue'
|
|
6
|
+
|
|
7
|
+
const settings = usePreviewSettingsStore().currentSettings
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<!-- Responsive size -->
|
|
12
|
+
<VDropdown
|
|
13
|
+
placement="bottom-end"
|
|
14
|
+
:skidding="6"
|
|
15
|
+
:disabled="!histoireConfig.responsivePresets?.length"
|
|
16
|
+
class="histoire-toolbar-responsive-size htw-h-full htw-flex-none"
|
|
17
|
+
>
|
|
18
|
+
<div
|
|
19
|
+
v-tooltip="'Responsive sizes'"
|
|
20
|
+
class="htw-flex htw-items-center htw-gap-1 htw-h-full htw-px-2 htw-group"
|
|
21
|
+
:class="{
|
|
22
|
+
'htw-cursor-pointer hover:htw-text-primary-500': histoireConfig.responsivePresets?.length,
|
|
23
|
+
}"
|
|
24
|
+
>
|
|
25
|
+
<Icon
|
|
26
|
+
icon="carbon:devices"
|
|
27
|
+
class="htw-w-4 htw-h-4 htw-opacity-50 group-hover:htw-opacity-100"
|
|
28
|
+
/>
|
|
29
|
+
<Icon
|
|
30
|
+
icon="carbon:caret-down"
|
|
31
|
+
class="htw-w-4 htw-h-4 htw-opacity-50 group-hover:htw-opacity-100"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<template #popper="{ hide }">
|
|
36
|
+
<div class="htw-flex htw-flex-col htw-items-stretch">
|
|
37
|
+
<BaseCheckbox v-model="settings.rotate">
|
|
38
|
+
Rotate
|
|
39
|
+
</BaseCheckbox>
|
|
40
|
+
|
|
41
|
+
<div class="htw-flex htw-items-center htw-gap-2 htw-px-4 htw-py-3">
|
|
42
|
+
<input
|
|
43
|
+
v-model.number="settings.responsiveWidth"
|
|
44
|
+
v-tooltip="'Responsive width (px)'"
|
|
45
|
+
type="number"
|
|
46
|
+
class="htw-bg-transparent htw-border htw-border-gray-200 dark:htw-border-gray-850 htw-rounded htw-w-20 htw-opacity-50 focus:htw-opacity-100 htw-flex-1 htw-min-w-0"
|
|
47
|
+
step="16"
|
|
48
|
+
placeholder="Auto"
|
|
49
|
+
>
|
|
50
|
+
<span class="htw-opacity-50">×</span>
|
|
51
|
+
<input
|
|
52
|
+
v-model.number="settings.responsiveHeight"
|
|
53
|
+
v-tooltip="'Responsive height (px)'"
|
|
54
|
+
type="number"
|
|
55
|
+
class="htw-bg-transparent htw-border htw-border-gray-200 dark:htw-border-gray-850 htw-rounded htw-w-20 htw-opacity-50 focus:htw-opacity-100 htw-flex-1 htw-min-w-0"
|
|
56
|
+
step="16"
|
|
57
|
+
placeholder="Auto"
|
|
58
|
+
>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<button
|
|
62
|
+
v-for="(preset, index) in histoireConfig.responsivePresets"
|
|
63
|
+
:key="index"
|
|
64
|
+
class="htw-px-4 htw-py-3 htw-cursor-pointer htw-text-left htw-flex htw-gap-4"
|
|
65
|
+
:class="[
|
|
66
|
+
settings.responsiveWidth === preset.width && settings.responsiveHeight === preset.height
|
|
67
|
+
? 'htw-bg-primary-500 hover:htw-bg-primary-600 htw-text-white dark:htw-text-black'
|
|
68
|
+
: 'htw-bg-transparent hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700',
|
|
69
|
+
]"
|
|
70
|
+
@click="settings.responsiveWidth = preset.width;settings.responsiveHeight = preset.height;hide()"
|
|
71
|
+
>
|
|
72
|
+
{{ preset.label }}
|
|
73
|
+
<span class="htw-ml-auto htw-opacity-70 htw-flex htw-gap-1">
|
|
74
|
+
<span v-if="preset.width">{{ preset.width }}<span v-if="!preset.height">px</span></span>
|
|
75
|
+
<span v-if="preset.width && preset.height">x</span>
|
|
76
|
+
<span v-if="preset.height">{{ preset.height }}<span v-if="!preset.width">px</span></span>
|
|
77
|
+
</span>
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
</template>
|
|
81
|
+
</VDropdown>
|
|
82
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
4
|
+
|
|
5
|
+
const settings = usePreviewSettingsStore().currentSettings
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<a
|
|
10
|
+
v-tooltip="`Switch to text direction ${settings.textDirection === 'ltr' ? 'Right to Left' : 'Left to Right'}`"
|
|
11
|
+
class="histoire-toolbar-text-direction htw-flex htw-items-center htw-gap-1 htw-h-full htw-px-2 hover:htw-text-primary-500 htw-opacity-50 hover:htw-opacity-100 dark:hover:htw-text-primary-400 htw-text-gray-900 dark:htw-text-gray-100"
|
|
12
|
+
@click="settings.textDirection = settings.textDirection === 'ltr' ? 'rtl' : 'ltr'"
|
|
13
|
+
>
|
|
14
|
+
<Icon
|
|
15
|
+
:icon="settings.textDirection === 'ltr' ? 'fluent:text-paragraph-direction-right-16-regular' : 'fluent:text-paragraph-direction-left-16-regular'"
|
|
16
|
+
class="htw-w-4 htw-h-4"
|
|
17
|
+
/>
|
|
18
|
+
</a>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Variant } from '../../types'
|
|
3
|
+
import { Icon } from '@iconify/vue'
|
|
4
|
+
|
|
5
|
+
defineProps<{
|
|
6
|
+
variant: Variant
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div class="histoire-toolbar-title htw-flex htw-items-center htw-gap-1 htw-text-gray-500 htw-flex-1 htw-truncate htw-min-w-0">
|
|
12
|
+
<Icon
|
|
13
|
+
:icon="variant.icon ?? 'carbon:cube'"
|
|
14
|
+
class="htw-w-4 htw-h-4 htw-opacity-50"
|
|
15
|
+
:class="[
|
|
16
|
+
variant.iconColor ? 'bind-icon-color' : 'htw-text-gray-500',
|
|
17
|
+
]"
|
|
18
|
+
/>
|
|
19
|
+
<span>{{ variant.title }}</span>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Story, TreeGroup } from '../../types'
|
|
3
|
+
import { Icon } from '@iconify/vue'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { useFolderStore } from '../../stores/folder'
|
|
6
|
+
import StoryListFolder from './StoryListFolder.vue'
|
|
7
|
+
import StoryListItem from './StoryListItem.vue'
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<{
|
|
10
|
+
path?: Array<string>
|
|
11
|
+
group: TreeGroup
|
|
12
|
+
stories: Story[]
|
|
13
|
+
}>(), {
|
|
14
|
+
path: () => [],
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const folderStore = useFolderStore()
|
|
18
|
+
|
|
19
|
+
const folderPath = computed(() => [...props.path, props.group.title])
|
|
20
|
+
const isFolderOpen = computed(() => folderStore.isFolderOpened(folderPath.value, true))
|
|
21
|
+
|
|
22
|
+
function toggleOpen() {
|
|
23
|
+
folderStore.toggleFolder(folderPath.value, false)
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<template>
|
|
28
|
+
<div
|
|
29
|
+
data-test-id="story-group"
|
|
30
|
+
class="histoire-story-group htw-my-2 first:htw-mt-0 last:htw-mb-0 htw-group"
|
|
31
|
+
>
|
|
32
|
+
<template v-if="group.title">
|
|
33
|
+
<div class="htw-h-[1px] htw-bg-gray-500/10 htw-mx-6 htw-mb-2 group-first:htw-hidden" />
|
|
34
|
+
<div
|
|
35
|
+
role="button"
|
|
36
|
+
tabindex="0"
|
|
37
|
+
class="htw-px-0.5 htw-py-2 md:htw-py-1.5 htw-mx-1 htw-rounded-sm hover:htw-bg-primary-100 dark:hover:htw-bg-primary-900 htw-cursor-pointer htw-select-none htw-flex htw-items-center htw-gap-2 htw-min-w-0 htw-opacity-50 hover:htw-opacity-100"
|
|
38
|
+
@click="toggleOpen"
|
|
39
|
+
@keyup.enter="toggleOpen"
|
|
40
|
+
@keyup.space="toggleOpen"
|
|
41
|
+
>
|
|
42
|
+
<Icon
|
|
43
|
+
:icon="isFolderOpen ? 'ri:subtract-line' : 'ri:add-line'"
|
|
44
|
+
class="htw-w-4 htw-h-4 htw-ml-4 htw-rounded-sm htw-border htw-border-gray-500/40"
|
|
45
|
+
/>
|
|
46
|
+
<span class="htw-truncate">{{ group.title }}</span>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<!-- Children -->
|
|
51
|
+
<div
|
|
52
|
+
v-if="isFolderOpen"
|
|
53
|
+
>
|
|
54
|
+
<template
|
|
55
|
+
v-for="element of group.children"
|
|
56
|
+
:key="element.title"
|
|
57
|
+
>
|
|
58
|
+
<StoryListFolder
|
|
59
|
+
v-if="(element as TreeFolder).children"
|
|
60
|
+
:path="folderPath"
|
|
61
|
+
:folder="(element as TreeFolder)"
|
|
62
|
+
:stories="stories"
|
|
63
|
+
:depth="0"
|
|
64
|
+
/>
|
|
65
|
+
<StoryListItem
|
|
66
|
+
v-else
|
|
67
|
+
:story="stories[(element as TreeLeaf).index]"
|
|
68
|
+
:depth="0"
|
|
69
|
+
/>
|
|
70
|
+
</template>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Story, Tree, TreeFolder, TreeGroup, TreeLeaf } from '../../types'
|
|
3
|
+
import StoryGroup from './StoryGroup.vue'
|
|
4
|
+
import StoryListFolder from './StoryListFolder.vue'
|
|
5
|
+
import StoryListItem from './StoryListItem.vue'
|
|
6
|
+
|
|
7
|
+
defineProps<{
|
|
8
|
+
tree: Tree
|
|
9
|
+
stories: Story[]
|
|
10
|
+
}>()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div class="histoire-story-list htw-overflow-y-auto">
|
|
15
|
+
<template
|
|
16
|
+
v-for="element of tree"
|
|
17
|
+
:key="element.title"
|
|
18
|
+
>
|
|
19
|
+
<StoryGroup
|
|
20
|
+
v-if="(element as TreeGroup).group"
|
|
21
|
+
:group="(element as TreeGroup)"
|
|
22
|
+
:stories="stories"
|
|
23
|
+
/>
|
|
24
|
+
<StoryListFolder
|
|
25
|
+
v-else-if="(element as TreeFolder).children"
|
|
26
|
+
:folder="(element as TreeFolder)"
|
|
27
|
+
:stories="stories"
|
|
28
|
+
/>
|
|
29
|
+
<StoryListItem
|
|
30
|
+
v-else
|
|
31
|
+
:story="stories[(element as TreeLeaf).index]"
|
|
32
|
+
/>
|
|
33
|
+
</template>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Story, TreeFolder, TreeLeaf } from '../../types'
|
|
3
|
+
import { Icon } from '@iconify/vue'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { useFolderStore } from '../../stores/folder'
|
|
6
|
+
import StoryListItem from './StoryListItem.vue'
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(defineProps<{
|
|
9
|
+
path?: Array<string>
|
|
10
|
+
folder: TreeFolder
|
|
11
|
+
stories: Story[]
|
|
12
|
+
depth?: number
|
|
13
|
+
}>(), {
|
|
14
|
+
depth: 0,
|
|
15
|
+
path: () => [],
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const folderStore = useFolderStore()
|
|
19
|
+
|
|
20
|
+
const folderPath = computed(() => [...props.path, props.folder.title])
|
|
21
|
+
const isFolderOpen = computed(() => folderStore.isFolderOpened(folderPath.value))
|
|
22
|
+
|
|
23
|
+
function toggleOpen() {
|
|
24
|
+
folderStore.toggleFolder(folderPath.value)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const folderPadding = computed(() => {
|
|
28
|
+
return `${props.depth * 12}px`
|
|
29
|
+
})
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<div
|
|
34
|
+
data-test-id="story-list-folder"
|
|
35
|
+
class="histoire-story-list-folder"
|
|
36
|
+
>
|
|
37
|
+
<div
|
|
38
|
+
role="button"
|
|
39
|
+
tabindex="0"
|
|
40
|
+
class="histoire-story-list-folder-button htw-px-0.5 htw-py-2 md:htw-py-1.5 htw-mx-1 htw-rounded-sm hover:htw-bg-primary-100 dark:hover:htw-bg-primary-900 htw-cursor-pointer htw-select-none htw-flex"
|
|
41
|
+
@click="toggleOpen"
|
|
42
|
+
@keyup.enter="toggleOpen"
|
|
43
|
+
@keyup.space="toggleOpen"
|
|
44
|
+
>
|
|
45
|
+
<span class="bind-tree-padding htw-flex htw-items-center htw-gap-2 htw-min-w-0">
|
|
46
|
+
<span class="htw-flex htw-flex-none htw-items-center htw-opacity-30 [.histoire-story-list-folder-button:hover_&]:htw-opacity-100 htw-ml-4 htw-w-4 htw-h-4 htw-rounded-sm htw-border htw-border-gray-500/40">
|
|
47
|
+
<Icon
|
|
48
|
+
icon="carbon:caret-right"
|
|
49
|
+
class="htw-w-full htw-h-full htw-transition-transform htw-duration-150"
|
|
50
|
+
:class="{
|
|
51
|
+
'htw-rotate-90': isFolderOpen,
|
|
52
|
+
}"
|
|
53
|
+
/>
|
|
54
|
+
</span>
|
|
55
|
+
<span class="htw-truncate">{{ folder.title }}</span>
|
|
56
|
+
</span>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<!-- Children -->
|
|
60
|
+
<div
|
|
61
|
+
v-if="isFolderOpen"
|
|
62
|
+
>
|
|
63
|
+
<template
|
|
64
|
+
v-for="element of folder.children"
|
|
65
|
+
:key="element.title"
|
|
66
|
+
>
|
|
67
|
+
<StoryListFolder
|
|
68
|
+
v-if="(element as TreeFolder).children"
|
|
69
|
+
:path="folderPath"
|
|
70
|
+
:folder="(element as TreeFolder)"
|
|
71
|
+
:stories="stories"
|
|
72
|
+
:depth="depth + 1"
|
|
73
|
+
/>
|
|
74
|
+
<StoryListItem
|
|
75
|
+
v-else
|
|
76
|
+
:story="stories[(element as TreeLeaf).index]"
|
|
77
|
+
:depth="depth + 1"
|
|
78
|
+
/>
|
|
79
|
+
</template>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</template>
|
|
83
|
+
|
|
84
|
+
<style scoped>
|
|
85
|
+
.bind-tree-padding {
|
|
86
|
+
padding-left: v-bind(folderPadding);
|
|
87
|
+
}
|
|
88
|
+
</style>
|