@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.
Files changed (309) hide show
  1. package/LICENSE +21 -0
  2. package/dist/app/assets/histoire-text-dark.svg +89 -0
  3. package/dist/app/assets/histoire-text.svg +89 -0
  4. package/dist/app/assets/histoire.svg +51 -0
  5. package/dist/app/style/floating.pcss +34 -0
  6. package/dist/app/style/main.pcss +100 -0
  7. package/dist/app/style/sandbox.css +24 -0
  8. package/dist/app/style/transitions.pcss +51 -0
  9. package/dist/bundle-index.js +3 -0
  10. package/dist/bundle-main-dev.js +4 -0
  11. package/dist/bundle-main.js +5 -0
  12. package/dist/bundle-sandbox-dev.js +2 -0
  13. package/dist/bundle-sandbox.js +2 -0
  14. package/dist/bundled/App.vue.js +5 -0
  15. package/dist/bundled/App.vue2.js +167 -0
  16. package/dist/bundled/_virtual/_node-dom-env.js +188 -0
  17. package/dist/bundled/_virtual/_node-dom-polyfill.js +152 -0
  18. package/dist/bundled/_virtual/_plugin-vue_export-helper.js +10 -0
  19. package/dist/bundled/_virtual/histoire-commands.js +8 -0
  20. package/dist/bundled/_virtual/histoire-config.js +42 -0
  21. package/dist/bundled/_virtual/histoire-markdown-files.js +8 -0
  22. package/dist/bundled/_virtual/histoire-search-docs-data.js +11 -0
  23. package/dist/bundled/_virtual/histoire-search-title-data.js +11 -0
  24. package/dist/bundled/_virtual/histoire-stories.js +17 -0
  25. package/dist/bundled/_virtual/histoire-support-plugins-client.js +8 -0
  26. package/dist/bundled/_virtual/histoire-theme.js +8 -0
  27. package/dist/bundled/api.js +12 -0
  28. package/dist/bundled/app.css +116 -0
  29. package/dist/bundled/assets/histoire-text-dark.svg.js +4 -0
  30. package/dist/bundled/assets/histoire-text.svg.js +4 -0
  31. package/dist/bundled/assets/histoire.svg.js +4 -0
  32. package/dist/bundled/components/HomeView.vue.js +5 -0
  33. package/dist/bundled/components/HomeView.vue2.js +66 -0
  34. package/dist/bundled/components/app/AppHeader.vue.js +5 -0
  35. package/dist/bundled/components/app/AppHeader.vue2.js +71 -0
  36. package/dist/bundled/components/app/AppLogo.vue.js +5 -0
  37. package/dist/bundled/components/app/AppLogo.vue2.js +29 -0
  38. package/dist/bundled/components/app/Breadcrumb.vue.js +8 -0
  39. package/dist/bundled/components/app/Breadcrumb.vue2.js +91 -0
  40. package/dist/bundled/components/app/HomeCounter.vue.js +5 -0
  41. package/dist/bundled/components/app/HomeCounter.vue2.js +42 -0
  42. package/dist/bundled/components/app/InitialLoading.vue.js +5 -0
  43. package/dist/bundled/components/app/InitialLoading.vue2.js +51 -0
  44. package/dist/bundled/components/app/MobileOverlay.vue.js +5 -0
  45. package/dist/bundled/components/app/MobileOverlay.vue2.js +45 -0
  46. package/dist/bundled/components/base/BaseButton.vue.js +5 -0
  47. package/dist/bundled/components/base/BaseButton.vue2.js +39 -0
  48. package/dist/bundled/components/base/BaseCheckbox.vue.js +5 -0
  49. package/dist/bundled/components/base/BaseCheckbox.vue2.js +78 -0
  50. package/dist/bundled/components/base/BaseEmpty.vue.js +14 -0
  51. package/dist/bundled/components/base/BaseIcon.vue.js +8 -0
  52. package/dist/bundled/components/base/BaseIcon.vue2.js +29 -0
  53. package/dist/bundled/components/base/BaseKeyboardShortcut.vue.js +5 -0
  54. package/dist/bundled/components/base/BaseKeyboardShortcut.vue2.js +20 -0
  55. package/dist/bundled/components/base/BaseListItem.vue.js +5 -0
  56. package/dist/bundled/components/base/BaseListItem.vue2.js +33 -0
  57. package/dist/bundled/components/base/BaseListItemLink.vue.js +33 -0
  58. package/dist/bundled/components/base/BaseListItemLink.vue2.js +26 -0
  59. package/dist/bundled/components/base/BaseOverflowMenu.vue.js +5 -0
  60. package/dist/bundled/components/base/BaseOverflowMenu.vue2.js +100 -0
  61. package/dist/bundled/components/base/BaseOverflowTab.vue.js +36 -0
  62. package/dist/bundled/components/base/BaseOverflowTab.vue2.js +18 -0
  63. package/dist/bundled/components/base/BaseSelect.vue.js +5 -0
  64. package/dist/bundled/components/base/BaseSelect.vue2.js +77 -0
  65. package/dist/bundled/components/base/BaseSplitPane.vue.js +8 -0
  66. package/dist/bundled/components/base/BaseSplitPane.vue2.js +183 -0
  67. package/dist/bundled/components/base/BaseTab.vue.js +36 -0
  68. package/dist/bundled/components/base/BaseTab.vue2.js +18 -0
  69. package/dist/bundled/components/base/BaseTag.vue.js +13 -0
  70. package/dist/bundled/components/command/CommandPrompts.vue.js +5 -0
  71. package/dist/bundled/components/command/CommandPrompts.vue2.js +91 -0
  72. package/dist/bundled/components/command/CommandPromptsModal.vue.js +5 -0
  73. package/dist/bundled/components/command/CommandPromptsModal.vue2.js +45 -0
  74. package/dist/bundled/components/command/PromptSelect.vue.js +5 -0
  75. package/dist/bundled/components/command/PromptSelect.vue2.js +142 -0
  76. package/dist/bundled/components/command/PromptText.vue.js +5 -0
  77. package/dist/bundled/components/command/PromptText.vue2.js +67 -0
  78. package/dist/bundled/components/misc/CheckerboardPattern.vue.js +40 -0
  79. package/dist/bundled/components/misc/HatchedPattern.vue.js +12 -0
  80. package/dist/bundled/components/panel/ControlsComponentPropItem.vue.js +5 -0
  81. package/dist/bundled/components/panel/ControlsComponentPropItem.vue2.js +72 -0
  82. package/dist/bundled/components/panel/ControlsComponentProps.vue.js +5 -0
  83. package/dist/bundled/components/panel/ControlsComponentProps.vue2.js +45 -0
  84. package/dist/bundled/components/panel/ControlsComponentState.vue.js +5 -0
  85. package/dist/bundled/components/panel/ControlsComponentState.vue2.js +41 -0
  86. package/dist/bundled/components/panel/ControlsComponentStateItem.vue.js +5 -0
  87. package/dist/bundled/components/panel/ControlsComponentStateItem.vue2.js +46 -0
  88. package/dist/bundled/components/panel/PaneTabs.vue.js +5 -0
  89. package/dist/bundled/components/panel/PaneTabs.vue2.js +114 -0
  90. package/dist/bundled/components/panel/StatePresets.vue.js +5 -0
  91. package/dist/bundled/components/panel/StatePresets.vue2.js +193 -0
  92. package/dist/bundled/components/panel/StoryControls.vue.js +5 -0
  93. package/dist/bundled/components/panel/StoryControls.vue2.js +87 -0
  94. package/dist/bundled/components/panel/StoryDocs.vue.js +7 -0
  95. package/dist/bundled/components/panel/StoryDocs.vue2.js +161 -0
  96. package/dist/bundled/components/panel/StoryEvent.vue.js +5 -0
  97. package/dist/bundled/components/panel/StoryEvent.vue2.js +59 -0
  98. package/dist/bundled/components/panel/StoryEvents.vue.js +5 -0
  99. package/dist/bundled/components/panel/StoryEvents.vue2.js +53 -0
  100. package/dist/bundled/components/panel/StorySidePanel.vue.js +5 -0
  101. package/dist/bundled/components/panel/StorySidePanel.vue2.js +83 -0
  102. package/dist/bundled/components/panel/StorySourceCode.vue.js +8 -0
  103. package/dist/bundled/components/panel/StorySourceCode.vue2.js +204 -0
  104. package/dist/bundled/components/search/SearchItem.vue.js +8 -0
  105. package/dist/bundled/components/search/SearchItem.vue2.js +93 -0
  106. package/dist/bundled/components/search/SearchItemContent.vue.js +5 -0
  107. package/dist/bundled/components/search/SearchItemContent.vue2.js +71 -0
  108. package/dist/bundled/components/search/SearchLoading.vue.js +5 -0
  109. package/dist/bundled/components/search/SearchLoading.vue2.js +21 -0
  110. package/dist/bundled/components/search/SearchModal.vue.js +5 -0
  111. package/dist/bundled/components/search/SearchModal.vue2.js +51 -0
  112. package/dist/bundled/components/search/SearchPane.vue.js +5 -0
  113. package/dist/bundled/components/search/SearchPane.vue2.js +272 -0
  114. package/dist/bundled/components/search/search-docs-data.js +11 -0
  115. package/dist/bundled/components/search/search-title-data.js +11 -0
  116. package/dist/bundled/components/story/GenericMountStory.vue.js +5 -0
  117. package/dist/bundled/components/story/GenericMountStory.vue2.js +34 -0
  118. package/dist/bundled/components/story/GenericRenderStory.vue.js +5 -0
  119. package/dist/bundled/components/story/GenericRenderStory.vue2.js +39 -0
  120. package/dist/bundled/components/story/StoryResponsivePreview.vue.js +8 -0
  121. package/dist/bundled/components/story/StoryResponsivePreview.vue2.js +207 -0
  122. package/dist/bundled/components/story/StoryVariantGrid.vue.js +5 -0
  123. package/dist/bundled/components/story/StoryVariantGrid.vue2.js +146 -0
  124. package/dist/bundled/components/story/StoryVariantGridItem.vue.js +8 -0
  125. package/dist/bundled/components/story/StoryVariantGridItem.vue2.js +153 -0
  126. package/dist/bundled/components/story/StoryVariantListItem.vue.js +8 -0
  127. package/dist/bundled/components/story/StoryVariantListItem.vue2.js +55 -0
  128. package/dist/bundled/components/story/StoryVariantSingle.vue.js +8 -0
  129. package/dist/bundled/components/story/StoryVariantSingle.vue2.js +107 -0
  130. package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue.js +5 -0
  131. package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue2.js +70 -0
  132. package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue.js +5 -0
  133. package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue2.js +128 -0
  134. package/dist/bundled/components/story/StoryVariantSingleView.vue.js +5 -0
  135. package/dist/bundled/components/story/StoryVariantSingleView.vue2.js +66 -0
  136. package/dist/bundled/components/story/StoryView.vue.js +5 -0
  137. package/dist/bundled/components/story/StoryView.vue2.js +104 -0
  138. package/dist/bundled/components/story/StoryViewer.vue.js +8 -0
  139. package/dist/bundled/components/story/StoryViewer.vue2.js +55 -0
  140. package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue.js +5 -0
  141. package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue2.js +31 -0
  142. package/dist/bundled/components/toolbar/ToolbarBackground.vue.js +8 -0
  143. package/dist/bundled/components/toolbar/ToolbarBackground.vue2.js +98 -0
  144. package/dist/bundled/components/toolbar/ToolbarNewTab.vue.js +5 -0
  145. package/dist/bundled/components/toolbar/ToolbarNewTab.vue2.js +36 -0
  146. package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue.js +5 -0
  147. package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue2.js +127 -0
  148. package/dist/bundled/components/toolbar/ToolbarTextDirection.vue.js +5 -0
  149. package/dist/bundled/components/toolbar/ToolbarTextDirection.vue2.js +27 -0
  150. package/dist/bundled/components/toolbar/ToolbarTitle.vue.js +5 -0
  151. package/dist/bundled/components/toolbar/ToolbarTitle.vue2.js +26 -0
  152. package/dist/bundled/components/tree/StoryGroup.vue.js +5 -0
  153. package/dist/bundled/components/tree/StoryGroup.vue2.js +74 -0
  154. package/dist/bundled/components/tree/StoryList.vue.js +5 -0
  155. package/dist/bundled/components/tree/StoryList.vue2.js +41 -0
  156. package/dist/bundled/components/tree/StoryListFolder.vue.js +8 -0
  157. package/dist/bundled/components/tree/StoryListFolder.vue2.js +86 -0
  158. package/dist/bundled/components/tree/StoryListItem.vue.js +8 -0
  159. package/dist/bundled/components/tree/StoryListItem.vue2.js +69 -0
  160. package/dist/bundled/index.js +36 -0
  161. package/dist/bundled/plugin.js +49 -0
  162. package/dist/bundled/router.js +32 -0
  163. package/dist/bundled/sandbox.js +87 -0
  164. package/dist/bundled/stores/command.js +25 -0
  165. package/dist/bundled/stores/events.js +29 -0
  166. package/dist/bundled/stores/folder.js +54 -0
  167. package/dist/bundled/stores/preview-settings.js +19 -0
  168. package/dist/bundled/stores/story.js +43 -0
  169. package/dist/bundled/util/commands.js +57 -0
  170. package/dist/bundled/util/config.js +8 -0
  171. package/dist/bundled/util/const.js +10 -0
  172. package/dist/bundled/util/dark.js +28 -0
  173. package/dist/bundled/util/docs.js +26 -0
  174. package/dist/bundled/util/env.js +4 -0
  175. package/dist/bundled/util/events.js +33 -0
  176. package/dist/bundled/util/keyboard.js +90 -0
  177. package/dist/bundled/util/mapping.js +70 -0
  178. package/dist/bundled/util/open-in-editor.js +7 -0
  179. package/dist/bundled/util/preview-settings.js +21 -0
  180. package/dist/bundled/util/responsive.js +6 -0
  181. package/dist/bundled/util/sandbox.js +11 -0
  182. package/dist/bundled/util/scroll.js +31 -0
  183. package/dist/bundled/util/select.js +28 -0
  184. package/dist/bundled/util/state.js +41 -0
  185. package/dist/bundled/util/tooltip.js +15 -0
  186. package/dist/bundled/util/variant.js +21 -0
  187. package/dist/style.css +2853 -0
  188. package/package.json +62 -0
  189. package/postcss-scope-wrapper.cjs +35 -0
  190. package/postcss.config.cjs +9 -0
  191. package/scripts/copy.mjs +12 -0
  192. package/scripts/watchAndCopy.mjs +15 -0
  193. package/src/app/App.vue +172 -0
  194. package/src/app/api.ts +9 -0
  195. package/src/app/assets/histoire-text-dark.svg +89 -0
  196. package/src/app/assets/histoire-text.svg +89 -0
  197. package/src/app/assets/histoire.svg +51 -0
  198. package/src/app/components/HomeView.vue +61 -0
  199. package/src/app/components/app/AppHeader.vue +65 -0
  200. package/src/app/components/app/AppLogo.vue +25 -0
  201. package/src/app/components/app/Breadcrumb.vue +98 -0
  202. package/src/app/components/app/HomeCounter.vue +39 -0
  203. package/src/app/components/app/InitialLoading.vue +44 -0
  204. package/src/app/components/app/MobileOverlay.vue +33 -0
  205. package/src/app/components/base/BaseButton.vue +33 -0
  206. package/src/app/components/base/BaseCheckbox.vue +76 -0
  207. package/src/app/components/base/BaseCopyIcon.vue +34 -0
  208. package/src/app/components/base/BaseEmpty.vue +21 -0
  209. package/src/app/components/base/BaseIcon.vue +31 -0
  210. package/src/app/components/base/BaseKeyboardShortcut.vue +16 -0
  211. package/src/app/components/base/BaseListItem.vue +30 -0
  212. package/src/app/components/base/BaseListItemLink.vue +56 -0
  213. package/src/app/components/base/BaseOverflowMenu.vue +119 -0
  214. package/src/app/components/base/BaseOverflowTab.vue +47 -0
  215. package/src/app/components/base/BaseSelect.vue +75 -0
  216. package/src/app/components/base/BaseSplitPane.vue +244 -0
  217. package/src/app/components/base/BaseTab.vue +47 -0
  218. package/src/app/components/base/BaseTag.vue +5 -0
  219. package/src/app/components/command/CommandPrompts.vue +95 -0
  220. package/src/app/components/command/CommandPromptsModal.vue +41 -0
  221. package/src/app/components/command/PromptSelect.vue +142 -0
  222. package/src/app/components/command/PromptText.vue +65 -0
  223. package/src/app/components/misc/CheckerboardPattern.vue +32 -0
  224. package/src/app/components/misc/HatchedPattern.vue +13 -0
  225. package/src/app/components/panel/ControlsComponentPropItem.vue +73 -0
  226. package/src/app/components/panel/ControlsComponentProps.vue +34 -0
  227. package/src/app/components/panel/ControlsComponentState.vue +38 -0
  228. package/src/app/components/panel/ControlsComponentStateItem.vue +44 -0
  229. package/src/app/components/panel/PaneTabs.vue +84 -0
  230. package/src/app/components/panel/StatePresets.vue +199 -0
  231. package/src/app/components/panel/StoryControls.vue +97 -0
  232. package/src/app/components/panel/StoryDocs.vue +202 -0
  233. package/src/app/components/panel/StoryEvent.vue +54 -0
  234. package/src/app/components/panel/StoryEvents.vue +48 -0
  235. package/src/app/components/panel/StorySidePanel.vue +76 -0
  236. package/src/app/components/panel/StorySourceCode.vue +248 -0
  237. package/src/app/components/search/SearchItem.vue +89 -0
  238. package/src/app/components/search/SearchItemContent.vue +67 -0
  239. package/src/app/components/search/SearchLoading.vue +16 -0
  240. package/src/app/components/search/SearchModal.vue +44 -0
  241. package/src/app/components/search/SearchPane.vue +319 -0
  242. package/src/app/components/search/search-docs-data.ts +9 -0
  243. package/src/app/components/search/search-title-data.ts +9 -0
  244. package/src/app/components/search/types.ts +4 -0
  245. package/src/app/components/story/GenericMountStory.vue +35 -0
  246. package/src/app/components/story/GenericRenderStory.vue +41 -0
  247. package/src/app/components/story/StoryResponsivePreview.vue +216 -0
  248. package/src/app/components/story/StoryVariantGrid.vue +169 -0
  249. package/src/app/components/story/StoryVariantGridItem.vue +163 -0
  250. package/src/app/components/story/StoryVariantListItem.vue +52 -0
  251. package/src/app/components/story/StoryVariantSingle.vue +105 -0
  252. package/src/app/components/story/StoryVariantSinglePreviewNative.vue +66 -0
  253. package/src/app/components/story/StoryVariantSinglePreviewRemote.vue +143 -0
  254. package/src/app/components/story/StoryVariantSingleView.vue +61 -0
  255. package/src/app/components/story/StoryView.vue +110 -0
  256. package/src/app/components/story/StoryViewer.vue +52 -0
  257. package/src/app/components/toolbar/DevOnlyToolbarOpenInEditor.vue +23 -0
  258. package/src/app/components/toolbar/ToolbarBackground.vue +81 -0
  259. package/src/app/components/toolbar/ToolbarNewTab.vue +29 -0
  260. package/src/app/components/toolbar/ToolbarResponsiveSize.vue +82 -0
  261. package/src/app/components/toolbar/ToolbarTextDirection.vue +19 -0
  262. package/src/app/components/toolbar/ToolbarTitle.vue +21 -0
  263. package/src/app/components/tree/StoryGroup.vue +73 -0
  264. package/src/app/components/tree/StoryList.vue +35 -0
  265. package/src/app/components/tree/StoryListFolder.vue +88 -0
  266. package/src/app/components/tree/StoryListItem.vue +72 -0
  267. package/src/app/index.ts +33 -0
  268. package/src/app/plugin.ts +59 -0
  269. package/src/app/router.ts +29 -0
  270. package/src/app/sandbox.ts +101 -0
  271. package/src/app/stores/command.ts +26 -0
  272. package/src/app/stores/events.ts +36 -0
  273. package/src/app/stores/folder.ts +63 -0
  274. package/src/app/stores/preview-settings.ts +18 -0
  275. package/src/app/stores/story.ts +47 -0
  276. package/src/app/style/floating.pcss +34 -0
  277. package/src/app/style/main.pcss +100 -0
  278. package/src/app/style/sandbox.css +24 -0
  279. package/src/app/style/transitions.pcss +51 -0
  280. package/src/app/types.ts +72 -0
  281. package/src/app/util/commands.ts +57 -0
  282. package/src/app/util/config.ts +5 -0
  283. package/src/app/util/const.ts +4 -0
  284. package/src/app/util/dark.ts +27 -0
  285. package/src/app/util/docs.ts +27 -0
  286. package/src/app/util/env.ts +1 -0
  287. package/src/app/util/events.ts +31 -0
  288. package/src/app/util/keyboard.ts +103 -0
  289. package/src/app/util/mapping.ts +80 -0
  290. package/src/app/util/open-in-editor.ts +3 -0
  291. package/src/app/util/preview-settings.ts +23 -0
  292. package/src/app/util/responsive.ts +3 -0
  293. package/src/app/util/sandbox.ts +9 -0
  294. package/src/app/util/scroll.ts +32 -0
  295. package/src/app/util/select.ts +30 -0
  296. package/src/app/util/state.ts +45 -0
  297. package/src/app/util/tooltip.ts +13 -0
  298. package/src/app/util/variant.ts +21 -0
  299. package/src/bundle-index.js +1 -0
  300. package/src/bundle-main-dev.js +4 -0
  301. package/src/bundle-main.js +5 -0
  302. package/src/bundle-sandbox-dev.js +2 -0
  303. package/src/bundle-sandbox.js +2 -0
  304. package/src/index.ts +1 -0
  305. package/src/shim.d.ts +10 -0
  306. package/src/virtual.d.ts +7 -0
  307. package/tailwind.config.cjs +137 -0
  308. package/tsconfig.json +53 -0
  309. package/vite.config.ts +88 -0
@@ -0,0 +1,319 @@
1
+ <script lang="ts" setup>
2
+ import type { ClientCommand } from '@histoire/shared'
3
+ import type { SearchResult, SearchResultType, Story, Variant } from '../../types'
4
+ import type { SearchData } from './types'
5
+ import { Icon } from '@iconify/vue'
6
+ import { useDebounce, useFocus } from '@vueuse/core'
7
+ import Fuse from 'fuse.js'
8
+ import { registeredCommands } from 'virtual:$histoire-commands'
9
+ import { computed, ref, watch } from 'vue'
10
+ import { useCommandStore } from '../../stores/command.js'
11
+ import { useStoryStore } from '../../stores/story'
12
+ import { builtinCommands, getCommandContext } from '../../util/commands.js'
13
+ import { useSelection } from '../../util/select.js'
14
+ import BaseEmpty from '../base/BaseEmpty.vue'
15
+ import { onUpdate, searchData } from './search-title-data'
16
+ import SearchItem from './SearchItem.vue'
17
+
18
+ const DocSearchData = () => import('./search-docs-data')
19
+
20
+ const props = defineProps({
21
+ shown: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ })
26
+
27
+ const emit = defineEmits({
28
+ close: () => true,
29
+ })
30
+
31
+ function close() {
32
+ emit('close')
33
+ }
34
+
35
+ // Autofocus
36
+
37
+ const input = ref<HTMLInputElement>()
38
+ const { focused } = useFocus(input, {
39
+ initialValue: true,
40
+ })
41
+
42
+ watch(() => props.shown, (value) => {
43
+ if (value) {
44
+ requestAnimationFrame(() => {
45
+ focused.value = true
46
+ input.value.select()
47
+ })
48
+ }
49
+ })
50
+
51
+ // Index
52
+
53
+ const searchInputText = ref('')
54
+ const rateLimitedSearch = useDebounce(searchInputText, 50)
55
+
56
+ const storyStore = useStoryStore()
57
+
58
+ let titleSearchIndex: Fuse<{ id: number, text: string }>
59
+ let titleIdMap: SearchData['idMap']
60
+
61
+ function createIndex() {
62
+ return new Fuse<{ id: number, text: string }>([], {
63
+ keys: ['text'],
64
+ })
65
+ }
66
+
67
+ async function loadSearchIndex(data: SearchData) {
68
+ titleSearchIndex = createIndex()
69
+
70
+ for (const document of data.index) {
71
+ titleSearchIndex.add(document)
72
+ }
73
+
74
+ titleIdMap = data.idMap
75
+ }
76
+
77
+ loadSearchIndex(searchData)
78
+ // Handle HMR
79
+ onUpdate((searchData) => {
80
+ loadSearchIndex(searchData)
81
+ })
82
+
83
+ let docSearchIndex: Fuse<{ id: number, text: string }>
84
+ let docIdMap: SearchData['idMap']
85
+
86
+ async function loadDocSearchIndex() {
87
+ async function load(data: SearchData) {
88
+ docSearchIndex = createIndex()
89
+
90
+ for (const document of data.index) {
91
+ docSearchIndex.add(document)
92
+ }
93
+
94
+ docIdMap = data.idMap
95
+
96
+ if (rateLimitedSearch.value) {
97
+ await searchOnDocField(rateLimitedSearch.value)
98
+ }
99
+ }
100
+
101
+ const searchDataModule = await DocSearchData()
102
+
103
+ await load(searchDataModule.searchData)
104
+ // Handle HMR
105
+ searchDataModule.onUpdate((searchData) => {
106
+ load(searchData)
107
+ })
108
+ }
109
+
110
+ loadDocSearchIndex()
111
+
112
+ // Search
113
+
114
+ const titleResults = ref<SearchResult[]>([])
115
+
116
+ watch(rateLimitedSearch, async (value) => {
117
+ const list: SearchResult[] = []
118
+ const result = titleSearchIndex.search(value)
119
+ let rank = 0
120
+
121
+ for (const document of result) {
122
+ const idMapData = titleIdMap[document.item.id]
123
+ if (!idMapData) continue
124
+ switch (idMapData.kind) {
125
+ case 'story': {
126
+ list.push(storyResultFactory(storyStore.getStoryById(idMapData.id), rank))
127
+ rank++
128
+ break
129
+ }
130
+ case 'variant': {
131
+ const [storyId] = idMapData.id.split(':')
132
+ const story = storyStore.getStoryById(storyId)
133
+ const variant = storyStore.getVariantById(idMapData.id)
134
+ list.push(variantResultFactory(story, variant, rank))
135
+ rank++
136
+ break
137
+ }
138
+ }
139
+ }
140
+
141
+ titleResults.value = list
142
+ })
143
+
144
+ const docsResults = ref<SearchResult[]>([])
145
+
146
+ async function searchOnDocField(query: string) {
147
+ if (docSearchIndex) {
148
+ const list: SearchResult[] = []
149
+ const result = docSearchIndex.search(query)
150
+ let rank = 0
151
+
152
+ for (const document of result) {
153
+ const idMapData = docIdMap[document.item.id]
154
+ if (!idMapData) continue
155
+ switch (idMapData.kind) {
156
+ case 'story': {
157
+ list.push(storyResultFactory(storyStore.getStoryById(idMapData.id), rank, 'docs'))
158
+ rank++
159
+ break
160
+ }
161
+ }
162
+ }
163
+
164
+ docsResults.value = list
165
+ }
166
+ }
167
+
168
+ watch(rateLimitedSearch, searchOnDocField)
169
+
170
+ function storyResultFactory(story: Story, rank: number, type: SearchResultType = 'title'): SearchResult {
171
+ return {
172
+ kind: 'story',
173
+ rank,
174
+ id: `story:${story.id}`,
175
+ title: story.title,
176
+ route: {
177
+ name: 'story',
178
+ params: {
179
+ storyId: story.id,
180
+ },
181
+ query: {
182
+ ...type === 'docs'
183
+ ? { tab: 'docs' }
184
+ : {},
185
+ },
186
+ },
187
+ path: story.file.path.slice(0, -1),
188
+ icon: story.icon,
189
+ iconColor: story.iconColor,
190
+ }
191
+ }
192
+
193
+ function variantResultFactory(story: Story, variant: Variant, rank: number, type: SearchResultType = 'title'): SearchResult {
194
+ return {
195
+ kind: 'variant',
196
+ rank,
197
+ id: `variant:${story.id}:${variant.id}`,
198
+ title: variant.title,
199
+ route: {
200
+ name: 'story',
201
+ params: {
202
+ storyId: story.id,
203
+ },
204
+ query: {
205
+ variantId: variant.id,
206
+ ...type === 'docs'
207
+ ? { tab: 'docs' }
208
+ : {},
209
+ },
210
+ },
211
+ path: [...story.file.path ?? [], story.title],
212
+ icon: variant.icon,
213
+ iconColor: variant.iconColor,
214
+ }
215
+ }
216
+
217
+ // Commands
218
+
219
+ const allCommands = [
220
+ ...builtinCommands,
221
+ ...registeredCommands,
222
+ ]
223
+
224
+ const commandResults = computed(() => {
225
+ if (__HISTOIRE_DEV__) {
226
+ const commandCtx = getCommandContext()
227
+ const searchText = searchInputText.value.toLowerCase()
228
+ return allCommands
229
+ .filter(command => !command.showIf || command.showIf(commandCtx))
230
+ .filter(command => command.label.toLowerCase().includes(searchText) || command.searchText?.toLowerCase().includes(searchText))
231
+ .map(command => commandResultFactory(command, 0))
232
+ }
233
+ return []
234
+ })
235
+
236
+ const commandStore = useCommandStore()
237
+
238
+ function commandResultFactory(command: ClientCommand, rank: number): SearchResult {
239
+ return {
240
+ kind: 'command',
241
+ rank,
242
+ id: `_command:${command.id}`,
243
+ title: command.label,
244
+ icon: command.icon ?? 'carbon:chevron-right',
245
+ onActivate: () => {
246
+ commandStore.activateCommand(command)
247
+ },
248
+ }
249
+ }
250
+
251
+ // Results
252
+
253
+ const results = computed(() => {
254
+ const list = [
255
+ ...commandResults.value,
256
+ ...titleResults.value,
257
+ ]
258
+ const seen = {}
259
+ for (const r of titleResults.value) {
260
+ seen[r.id] = true
261
+ }
262
+ for (const r of docsResults.value) {
263
+ if (!seen[r.id]) {
264
+ list.push(r)
265
+ }
266
+ }
267
+ return list
268
+ })
269
+
270
+ // Selection
271
+
272
+ const {
273
+ selectedIndex,
274
+ selectNext,
275
+ selectPrevious,
276
+ } = useSelection(results)
277
+ </script>
278
+
279
+ <template>
280
+ <div
281
+ class="histoire-search-pane htw-flex htw-items-center htw-gap-4 htw-pl-6 htw-border htw-border-transparent focus-visible:htw-border-primary-500"
282
+ @click="focused = true"
283
+ >
284
+ <Icon
285
+ icon="carbon:search"
286
+ class="flex-none htw-w-4 htw-h-4"
287
+ />
288
+
289
+ <input
290
+ ref="input"
291
+ v-model="searchInputText"
292
+ placeholder="Search for stories, variants..."
293
+ class="htw-bg-transparent htw-w-full htw-flex-1 htw-pl-0 htw-pr-6 htw-py-4 htw-outline-none"
294
+ @keydown.down.prevent="selectNext()"
295
+ @keydown.up.prevent="selectPrevious()"
296
+ @keydown.escape="close()"
297
+ >
298
+ </div>
299
+
300
+ <BaseEmpty
301
+ v-if="rateLimitedSearch && !results.length"
302
+ class="no-animation"
303
+ >
304
+ No results
305
+ </BaseEmpty>
306
+
307
+ <div
308
+ v-else-if="results.length"
309
+ class="htw-max-h-[400px] htw-overflow-y-auto htw-rounded-b-lg"
310
+ >
311
+ <SearchItem
312
+ v-for="(result, index) of results"
313
+ :key="result.id"
314
+ :result="result"
315
+ :selected="index === selectedIndex"
316
+ @close="close()"
317
+ />
318
+ </div>
319
+ </template>
@@ -0,0 +1,9 @@
1
+ import type { SearchData } from './types.js'
2
+ import { onUpdate as _onUpdate, searchData as _searchData } from 'virtual:$histoire-search-docs-data'
3
+ import { markRaw } from 'vue'
4
+
5
+ export const searchData: SearchData = markRaw(_searchData)
6
+
7
+ export function onUpdate(cb: (data: SearchData) => unknown) {
8
+ _onUpdate(cb)
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { SearchData } from './types.js'
2
+ import { onUpdate as _onUpdate, searchData as _searchData } from 'virtual:$histoire-search-title-data'
3
+ import { markRaw } from 'vue'
4
+
5
+ export const searchData: SearchData = markRaw(_searchData)
6
+
7
+ export function onUpdate(cb: (data: SearchData) => unknown) {
8
+ _onUpdate(cb)
9
+ }
@@ -0,0 +1,4 @@
1
+ export interface SearchData {
2
+ index: Array<{ id: number, text: string }>
3
+ idMap: Record<number, { id: string, kind: string }>
4
+ }
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ export default {
3
+ inheritAttrs: false,
4
+ }
5
+ </script>
6
+
7
+ <script lang="ts" setup>
8
+ import type { Story } from '../../types'
9
+ import { clientSupportPlugins } from 'virtual:$histoire-support-plugins-client'
10
+ import { markRaw, ref, watchEffect } from 'vue'
11
+
12
+ const props = defineProps<{
13
+ story: Story
14
+ }>()
15
+
16
+ const mountComponent = ref(null)
17
+
18
+ watchEffect(async () => {
19
+ const clientPlugin = clientSupportPlugins[props.story.file?.supportPluginId]
20
+ if (clientPlugin) {
21
+ const pluginModule = await clientPlugin()
22
+ mountComponent.value = markRaw(pluginModule.MountStory)
23
+ }
24
+ })
25
+ </script>
26
+
27
+ <template>
28
+ <component
29
+ :is="mountComponent"
30
+ v-if="mountComponent"
31
+ class="histoire-generic-mount-story"
32
+ :story="story"
33
+ v-bind="$attrs"
34
+ />
35
+ </template>
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ export default {
3
+ inheritAttrs: false,
4
+ }
5
+ </script>
6
+
7
+ <script lang="ts" setup>
8
+ import type { Story } from '../../types'
9
+ import { clientSupportPlugins } from 'virtual:$histoire-support-plugins-client'
10
+ import { markRaw, ref, watchEffect } from 'vue'
11
+
12
+ const props = defineProps<{
13
+ story: Story
14
+ }>()
15
+
16
+ const mountComponent = ref(null)
17
+
18
+ watchEffect(async () => {
19
+ const clientPlugin = clientSupportPlugins[props.story.file?.supportPluginId]
20
+ if (clientPlugin) {
21
+ try {
22
+ const pluginModule = await clientPlugin()
23
+ mountComponent.value = markRaw(pluginModule.RenderStory)
24
+ }
25
+ catch (e) {
26
+ console.error(e)
27
+ throw e
28
+ }
29
+ }
30
+ })
31
+ </script>
32
+
33
+ <template>
34
+ <component
35
+ :is="mountComponent"
36
+ v-if="mountComponent"
37
+ class="histoire-generic-render-story __histoire-render-story"
38
+ :story="story"
39
+ v-bind="$attrs"
40
+ />
41
+ </template>
@@ -0,0 +1,216 @@
1
+ <script lang="ts" setup>
2
+ import type { Ref } from 'vue'
3
+ import type { Variant } from '../../types'
4
+ import { Icon } from '@iconify/vue'
5
+ import { useEventListener } from '@vueuse/core'
6
+ import { VTooltip as vTooltip } from 'floating-vue'
7
+ import { computed, onUnmounted, ref } from 'vue'
8
+ import { usePreviewSettingsStore } from '../../stores/preview-settings'
9
+ import CheckerboardPattern from '../misc/CheckerboardPattern.vue'
10
+ import HatchedPattern from '../misc/HatchedPattern.vue'
11
+
12
+ const props = defineProps<{
13
+ variant: Variant
14
+ }>()
15
+
16
+ const settings = usePreviewSettingsStore().currentSettings
17
+
18
+ // Resize
19
+
20
+ const resizing = ref(false)
21
+
22
+ const onUnmountedCleanupFns: (() => unknown)[] = []
23
+ onUnmounted(() => {
24
+ onUnmountedCleanupFns.forEach(fn => fn())
25
+ })
26
+
27
+ function addWindowListener(event: string, listener: (event: any) => unknown) {
28
+ window.addEventListener(event, listener)
29
+ const removeListener = () => window.removeEventListener(event, listener)
30
+ onUnmountedCleanupFns.push(removeListener)
31
+ return () => {
32
+ removeListener()
33
+ onUnmountedCleanupFns.splice(onUnmountedCleanupFns.indexOf(removeListener), 1)
34
+ }
35
+ }
36
+
37
+ function useDragger(el: Ref<HTMLDivElement>, value: Ref<number>, min: number, max: number, axis: 'x' | 'y') {
38
+ function onMouseDown(event: MouseEvent) {
39
+ event.preventDefault()
40
+ event.stopPropagation()
41
+ const start = axis === 'x' ? event.clientX : event.clientY
42
+ const startValue = value.value ?? (axis === 'x' ? previewWrapper.value.clientWidth - 67 : previewWrapper.value.clientHeight - 70)
43
+ resizing.value = true
44
+
45
+ const removeListeners = [
46
+ addWindowListener('mousemove', onMouseMove),
47
+ addWindowListener('mouseup', onMouseUp),
48
+ ]
49
+
50
+ function onMouseMove(event: MouseEvent) {
51
+ const snapTarget = (axis === 'x' ? previewWrapper.value.clientWidth : previewWrapper.value.clientHeight)
52
+ const delta = (axis === 'x' ? event.clientX : event.clientY) - start
53
+ value.value = Math.max(min, Math.min(max, startValue + delta))
54
+
55
+ if (Math.abs(value.value - (snapTarget - 67)) < 16) {
56
+ value.value = null
57
+ }
58
+ }
59
+
60
+ function onMouseUp() {
61
+ removeListeners.forEach(fn => fn())
62
+ resizing.value = false
63
+ }
64
+ }
65
+ useEventListener(el, 'mousedown', onMouseDown)
66
+
67
+ function onTouchStart(event: TouchEvent) {
68
+ event.preventDefault()
69
+ event.stopPropagation()
70
+ const start = axis === 'x' ? event.touches[0].clientX : event.touches[0].clientY
71
+ const startValue = value.value
72
+ resizing.value = true
73
+
74
+ const removeListeners = [
75
+ addWindowListener('touchmove', onTouchMove),
76
+ addWindowListener('touchend', onTouchEnd),
77
+ addWindowListener('touchcancel', onTouchEnd),
78
+ ]
79
+
80
+ function onTouchMove(event: TouchEvent) {
81
+ const delta = (axis === 'x' ? event.touches[0].clientX : event.touches[0].clientY) - start
82
+ value.value = Math.max(min, Math.min(max, startValue + delta))
83
+ }
84
+
85
+ function onTouchEnd() {
86
+ removeListeners.forEach(fn => fn())
87
+ resizing.value = false
88
+ }
89
+ }
90
+ useEventListener(el, 'touchstart', onTouchStart)
91
+ }
92
+
93
+ const responsiveWidth = computed({
94
+ get: () => settings[settings.rotate ? 'responsiveHeight' : 'responsiveWidth'],
95
+ set: (value) => { settings[settings.rotate ? 'responsiveHeight' : 'responsiveWidth'] = value },
96
+ })
97
+ const responsiveHeight = computed({
98
+ get: () => settings[settings.rotate ? 'responsiveWidth' : 'responsiveHeight'],
99
+ set: (value) => { settings[settings.rotate ? 'responsiveWidth' : 'responsiveHeight'] = value },
100
+ })
101
+
102
+ const horizontalDragger = ref<HTMLDivElement>()
103
+ const verticalDragger = ref<HTMLDivElement>()
104
+ const cornerDragger = ref<HTMLDivElement>()
105
+ const previewWrapper = ref<HTMLDivElement>()
106
+
107
+ useDragger(horizontalDragger, responsiveWidth, 32, 20000, 'x')
108
+ useDragger(verticalDragger, responsiveHeight, 32, 20000, 'y')
109
+ useDragger(cornerDragger, responsiveWidth, 32, 20000, 'x')
110
+ useDragger(cornerDragger, responsiveHeight, 32, 20000, 'y')
111
+
112
+ // Handle rotate
113
+
114
+ const finalWidth = computed(() => settings.rotate ? settings.responsiveHeight : settings.responsiveWidth)
115
+ const finalHeight = computed(() => settings.rotate ? settings.responsiveWidth : settings.responsiveHeight)
116
+
117
+ // Disabled responsive
118
+
119
+ const isResponsiveEnabled = computed(() => !props.variant.responsiveDisabled)
120
+
121
+ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${responsiveHeight.value ?? 'Auto'}`)
122
+ </script>
123
+
124
+ <template>
125
+ <div class="histoire-story-responsive-preview htw-w-full htw-h-full htw-flex-1 htw-rounded-lg htw-relative htw-overflow-hidden">
126
+ <div
127
+ v-if="isResponsiveEnabled"
128
+ class="htw-absolute htw-inset-0 htw-w-full htw-h-full htw-bg-gray-100 dark:htw-bg-gray-750 htw-rounded-r-lg htw-border-l-2 htw-border-gray-500/10 dark:htw-border-gray-700/30 htw-overflow-hidden"
129
+ >
130
+ <HatchedPattern
131
+ class="htw-w-full htw-h-full htw-text-black/[1%] dark:htw-text-white/[1%]"
132
+ />
133
+ </div>
134
+
135
+ <div
136
+ ref="previewWrapper"
137
+ class="htw-h-full htw-overflow-auto htw-relative"
138
+ >
139
+ <div
140
+ class="htw-overflow-hidden htw-bg-white dark:htw-bg-gray-700 htw-rounded-lg htw-relative"
141
+ :class="isResponsiveEnabled ? {
142
+ 'htw-w-fit': !!finalWidth,
143
+ 'htw-h-fit': !!finalHeight,
144
+ 'htw-h-full': !finalHeight,
145
+ } : 'htw-h-full'"
146
+ >
147
+ <div
148
+ class="bind-preview-bg htw-rounded-lg htw-h-full"
149
+ data-test-id="responsive-preview-bg"
150
+ >
151
+ <CheckerboardPattern
152
+ v-if="settings.checkerboard"
153
+ class="htw-absolute htw-inset-0 htw-w-full htw-h-full htw-text-gray-500/20"
154
+ />
155
+ <div class="htw-p-8 htw-h-full htw-relative">
156
+ <div class="htw-w-full htw-h-full htw-relative">
157
+ <div class="htw-absolute htw-inset-0" />
158
+
159
+ <slot
160
+ :is-responsive-enabled="isResponsiveEnabled"
161
+ :final-width="finalWidth"
162
+ :final-height="finalHeight"
163
+ :resizing="resizing"
164
+ />
165
+ </div>
166
+
167
+ <!-- Markers -->
168
+ <div class="htw-absolute htw-top-5 htw-left-8 htw-h-2 htw-w-px htw-bg-gray-400/25" />
169
+ <div class="htw-absolute htw-top-5 htw-right-8 htw-h-2 htw-w-px htw-bg-gray-400/25" />
170
+ <div class="htw-absolute htw-bottom-5 htw-left-8 htw-h-2 htw-w-px htw-bg-gray-400/25" />
171
+ <div class="htw-absolute htw-bottom-5 htw-right-8 htw-h-2 htw-w-px htw-bg-gray-400/25" />
172
+ <div class="htw-absolute htw-left-5 htw-top-8 htw-w-2 htw-h-px htw-bg-gray-400/25" />
173
+ <div class="htw-absolute htw-left-5 htw-bottom-8 htw-w-2 htw-h-px htw-bg-gray-400/25" />
174
+ <div class="htw-absolute htw-right-5 htw-top-8 htw-w-2 htw-h-px htw-bg-gray-400/25" />
175
+ <div class="htw-absolute htw-right-5 htw-bottom-8 htw-w-2 htw-h-px htw-bg-gray-400/25" />
176
+ </div>
177
+
178
+ <!-- Resize Dragger -->
179
+ <template v-if="isResponsiveEnabled">
180
+ <div
181
+ ref="horizontalDragger"
182
+ v-tooltip.right="sizeTooltip"
183
+ class="htw-absolute htw-w-4 htw-top-0 htw-bottom-4 htw-right-0 hover:htw-bg-primary-500/30 htw-flex htw-items-center htw-justify-center htw-cursor-ew-resize htw-group hover:htw-text-primary-500"
184
+ >
185
+ <Icon
186
+ icon="mdi:drag-vertical-variant"
187
+ class="htw-w-4 htw-h-4 htw-opacity-20 group-hover:htw-opacity-90"
188
+ />
189
+ </div>
190
+ <div
191
+ ref="verticalDragger"
192
+ v-tooltip.bottom="sizeTooltip"
193
+ class="htw-absolute htw-h-4 htw-left-0 htw-right-4 htw-bottom-0 hover:htw-bg-primary-500/30 htw-flex htw-items-center htw-justify-center htw-cursor-ns-resize htw-group hover:htw-text-primary-500"
194
+ >
195
+ <Icon
196
+ icon="mdi:drag-horizontal-variant"
197
+ class="htw-w-4 htw-h-4 htw-opacity-20 group-hover:htw-opacity-90"
198
+ />
199
+ </div>
200
+ <div
201
+ ref="cornerDragger"
202
+ v-tooltip.bottom="sizeTooltip"
203
+ class="htw-absolute htw-w-4 htw-h-4 htw-right-0 htw-bottom-0 hover:htw-bg-primary-500/30 htw-flex htw-items-center htw-justify-center htw-cursor-nwse-resize htw-group hover:htw-text-primary-500"
204
+ />
205
+ </template>
206
+ </div>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ </template>
211
+
212
+ <style scoped>
213
+ .bind-preview-bg {
214
+ background-color: v-bind('settings.backgroundColor');
215
+ }
216
+ </style>