@poveste/app 0.1.3 → 0.2.1

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 (187) hide show
  1. package/dist/app/style/floating.pcss +4 -4
  2. package/dist/app/style/main.pcss +2 -2
  3. package/dist/app/style/sandbox.css +1 -1
  4. package/dist/bundle-main.js +2 -0
  5. package/dist/bundled/App.vue2.js +81 -37
  6. package/dist/bundled/app.css +51 -46
  7. package/dist/bundled/components/HomeView.vue2.js +3 -3
  8. package/dist/bundled/components/app/AppActions.vue.js +5 -0
  9. package/dist/bundled/components/app/AppActions.vue2.js +76 -0
  10. package/dist/bundled/components/app/AppHeader.vue2.js +5 -47
  11. package/dist/bundled/components/app/Breadcrumb.vue.js +1 -1
  12. package/dist/bundled/components/app/Breadcrumb.vue2.js +9 -9
  13. package/dist/bundled/components/app/HomeCounter.vue2.js +5 -5
  14. package/dist/bundled/components/app/InitialLoading.vue2.js +5 -5
  15. package/dist/bundled/components/app/MobileOverlay.vue2.js +5 -5
  16. package/dist/bundled/components/app/TopBar.vue.js +5 -0
  17. package/dist/bundled/components/app/TopBar.vue2.js +73 -0
  18. package/dist/bundled/components/app/TopBarChip.vue.js +13 -0
  19. package/dist/bundled/components/app/TopBarChipItem.vue.js +13 -0
  20. package/dist/bundled/components/base/BaseButton.vue2.js +3 -3
  21. package/dist/bundled/components/base/BaseCheckbox.vue2.js +8 -8
  22. package/dist/bundled/components/base/BaseEmpty.vue.js +2 -2
  23. package/dist/bundled/components/base/BaseKeyboardShortcut.vue2.js +1 -1
  24. package/dist/bundled/components/base/BaseListItem.vue2.js +2 -2
  25. package/dist/bundled/components/base/BaseListItemLink.vue.js +2 -2
  26. package/dist/bundled/components/base/BaseOverflowMenu.vue2.js +4 -4
  27. package/dist/bundled/components/base/BaseOverflowTab.vue.js +3 -3
  28. package/dist/bundled/components/base/BaseSelect.vue2.js +6 -6
  29. package/dist/bundled/components/base/BaseSplitPane.vue.js +1 -1
  30. package/dist/bundled/components/base/BaseSplitPane.vue2.js +20 -16
  31. package/dist/bundled/components/base/BaseTab.vue.js +3 -3
  32. package/dist/bundled/components/base/BaseTag.vue.js +1 -1
  33. package/dist/bundled/components/command/CommandPrompts.vue2.js +5 -5
  34. package/dist/bundled/components/command/CommandPromptsModal.vue2.js +3 -3
  35. package/dist/bundled/components/command/PromptSelect.vue2.js +12 -12
  36. package/dist/bundled/components/command/PromptText.vue2.js +4 -4
  37. package/dist/bundled/components/layout/LayoutItem.vue.js +5 -0
  38. package/dist/bundled/components/layout/LayoutItem.vue2.js +44 -0
  39. package/dist/bundled/components/layout/LayoutItemGroup.vue.js +5 -0
  40. package/dist/bundled/components/layout/LayoutItemGroup.vue2.js +25 -0
  41. package/dist/bundled/components/layout/LayoutModal.vue.js +5 -0
  42. package/dist/bundled/components/layout/LayoutModal.vue2.js +68 -0
  43. package/dist/bundled/components/layout/LayoutPane.vue.js +5 -0
  44. package/dist/bundled/components/layout/LayoutPane.vue2.js +59 -0
  45. package/dist/bundled/components/panel/ControlsComponentPropItem.vue2.js +2 -2
  46. package/dist/bundled/components/panel/ControlsComponentProps.vue2.js +4 -4
  47. package/dist/bundled/components/panel/ControlsComponentState.vue2.js +2 -2
  48. package/dist/bundled/components/panel/PaneTabs.vue2.js +4 -4
  49. package/dist/bundled/components/panel/StatePresets.vue2.js +13 -13
  50. package/dist/bundled/components/panel/StoryControls.vue2.js +6 -6
  51. package/dist/bundled/components/panel/StoryDocs.vue2.js +4 -4
  52. package/dist/bundled/components/panel/StoryEvent.vue2.js +7 -7
  53. package/dist/bundled/components/panel/StoryEvents.vue2.js +1 -1
  54. package/dist/bundled/components/panel/StorySidePanel.vue2.js +58 -47
  55. package/dist/bundled/components/panel/StorySourceCode.vue.js +1 -1
  56. package/dist/bundled/components/panel/StorySourceCode.vue2.js +19 -19
  57. package/dist/bundled/components/search/SearchItem.vue.js +1 -1
  58. package/dist/bundled/components/search/SearchItem.vue2.js +3 -3
  59. package/dist/bundled/components/search/SearchItemContent.vue2.js +9 -9
  60. package/dist/bundled/components/search/SearchLoading.vue2.js +2 -2
  61. package/dist/bundled/components/search/SearchModal.vue2.js +3 -3
  62. package/dist/bundled/components/search/SearchPane.vue2.js +4 -4
  63. package/dist/bundled/components/story/StoryResponsivePreview.vue.js +1 -1
  64. package/dist/bundled/components/story/StoryResponsivePreview.vue2.js +21 -21
  65. package/dist/bundled/components/story/StoryVariantGrid.vue2.js +7 -26
  66. package/dist/bundled/components/story/StoryVariantGridItem.vue.js +1 -1
  67. package/dist/bundled/components/story/StoryVariantGridItem.vue2.js +36 -21
  68. package/dist/bundled/components/story/StoryVariantListItem.vue.js +1 -1
  69. package/dist/bundled/components/story/StoryVariantListItem.vue2.js +5 -5
  70. package/dist/bundled/components/story/StoryVariantSingle.vue.js +1 -1
  71. package/dist/bundled/components/story/StoryVariantSingle.vue2.js +10 -10
  72. package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue2.js +6 -5
  73. package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue2.js +33 -8
  74. package/dist/bundled/components/story/StoryVariantSingleView.vue2.js +8 -39
  75. package/dist/bundled/components/story/StoryView.vue2.js +21 -11
  76. package/dist/bundled/components/story/StoryViewer.vue.js +1 -1
  77. package/dist/bundled/components/story/StoryViewer.vue2.js +2 -2
  78. package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue2.js +13 -9
  79. package/dist/bundled/components/toolbar/ToolbarBackground.vue.js +1 -1
  80. package/dist/bundled/components/toolbar/ToolbarBackground.vue2.js +62 -33
  81. package/dist/bundled/components/toolbar/ToolbarNewTab.vue2.js +13 -10
  82. package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue2.js +14 -14
  83. package/dist/bundled/components/toolbar/ToolbarTextDirection.vue2.js +13 -9
  84. package/dist/bundled/components/toolbar/ToolbarTitle.vue.js +4 -1
  85. package/dist/bundled/components/toolbar/ToolbarTitle.vue2.js +30 -7
  86. package/dist/bundled/components/tree/StoryGroup.vue2.js +5 -5
  87. package/dist/bundled/components/tree/StoryList.vue2.js +1 -1
  88. package/dist/bundled/components/tree/StoryListFolder.vue.js +1 -1
  89. package/dist/bundled/components/tree/StoryListFolder.vue2.js +7 -7
  90. package/dist/bundled/components/tree/StoryListItem.vue.js +1 -1
  91. package/dist/bundled/components/tree/StoryListItem.vue2.js +8 -8
  92. package/dist/bundled/index.js +3 -0
  93. package/dist/bundled/sandbox.js +41 -15
  94. package/dist/bundled/stores/layout.js +16 -0
  95. package/dist/bundled/stores/preview-settings.js +19 -4
  96. package/dist/bundled/util/color-scheme.js +27 -0
  97. package/dist/bundled/util/const.js +2 -0
  98. package/dist/bundled/util/dark.js +3 -3
  99. package/dist/bundled/util/keyboard.js +60 -32
  100. package/dist/bundled/util/preview-settings.js +11 -0
  101. package/dist/bundled/util/tooltip.js +2 -2
  102. package/dist/style.css +644 -529
  103. package/package.json +8 -8
  104. package/src/app/App.vue +109 -66
  105. package/src/app/components/HomeView.vue +3 -3
  106. package/src/app/components/app/AppActions.vue +58 -0
  107. package/src/app/components/app/AppHeader.vue +4 -47
  108. package/src/app/components/app/Breadcrumb.vue +8 -8
  109. package/src/app/components/app/HomeCounter.vue +5 -5
  110. package/src/app/components/app/InitialLoading.vue +5 -5
  111. package/src/app/components/app/MobileOverlay.vue +5 -5
  112. package/src/app/components/app/TopBar.vue +60 -0
  113. package/src/app/components/app/TopBarChip.vue +5 -0
  114. package/src/app/components/app/TopBarChipItem.vue +7 -0
  115. package/src/app/components/base/BaseButton.vue +3 -3
  116. package/src/app/components/base/BaseCheckbox.vue +9 -9
  117. package/src/app/components/base/BaseCopyIcon.vue +1 -1
  118. package/src/app/components/base/BaseEmpty.vue +4 -4
  119. package/src/app/components/base/BaseKeyboardShortcut.vue +1 -1
  120. package/src/app/components/base/BaseListItem.vue +3 -3
  121. package/src/app/components/base/BaseListItemLink.vue +3 -3
  122. package/src/app/components/base/BaseOverflowMenu.vue +4 -4
  123. package/src/app/components/base/BaseOverflowTab.vue +3 -3
  124. package/src/app/components/base/BaseSelect.vue +6 -6
  125. package/src/app/components/base/BaseSplitPane.vue +21 -16
  126. package/src/app/components/base/BaseTab.vue +3 -3
  127. package/src/app/components/base/BaseTag.vue +1 -1
  128. package/src/app/components/command/CommandPrompts.vue +5 -5
  129. package/src/app/components/command/CommandPromptsModal.vue +3 -3
  130. package/src/app/components/command/PromptSelect.vue +14 -14
  131. package/src/app/components/command/PromptText.vue +4 -4
  132. package/src/app/components/layout/LayoutItem.vue +36 -0
  133. package/src/app/components/layout/LayoutItemGroup.vue +18 -0
  134. package/src/app/components/layout/LayoutModal.vue +60 -0
  135. package/src/app/components/layout/LayoutPane.vue +45 -0
  136. package/src/app/components/panel/ControlsComponentPropItem.vue +2 -2
  137. package/src/app/components/panel/ControlsComponentProps.vue +3 -3
  138. package/src/app/components/panel/ControlsComponentState.vue +2 -2
  139. package/src/app/components/panel/PaneTabs.vue +4 -4
  140. package/src/app/components/panel/StatePresets.vue +13 -13
  141. package/src/app/components/panel/StoryControls.vue +6 -6
  142. package/src/app/components/panel/StoryDocs.vue +4 -4
  143. package/src/app/components/panel/StoryEvent.vue +7 -7
  144. package/src/app/components/panel/StoryEvents.vue +1 -1
  145. package/src/app/components/panel/StorySidePanel.vue +51 -41
  146. package/src/app/components/panel/StorySourceCode.vue +19 -19
  147. package/src/app/components/search/SearchItem.vue +2 -2
  148. package/src/app/components/search/SearchItemContent.vue +9 -9
  149. package/src/app/components/search/SearchLoading.vue +2 -2
  150. package/src/app/components/search/SearchModal.vue +3 -3
  151. package/src/app/components/search/SearchPane.vue +4 -4
  152. package/src/app/components/story/StoryResponsivePreview.vue +27 -27
  153. package/src/app/components/story/StoryVariantGrid.vue +5 -24
  154. package/src/app/components/story/StoryVariantGridItem.vue +36 -17
  155. package/src/app/components/story/StoryVariantListItem.vue +4 -4
  156. package/src/app/components/story/StoryVariantSingle.vue +9 -9
  157. package/src/app/components/story/StoryVariantSinglePreviewNative.vue +7 -5
  158. package/src/app/components/story/StoryVariantSinglePreviewRemote.vue +37 -7
  159. package/src/app/components/story/StoryVariantSingleView.vue +1 -34
  160. package/src/app/components/story/StoryView.vue +23 -8
  161. package/src/app/components/story/StoryViewer.vue +1 -1
  162. package/src/app/components/toolbar/DevOnlyToolbarOpenInEditor.vue +5 -4
  163. package/src/app/components/toolbar/ToolbarBackground.vue +62 -25
  164. package/src/app/components/toolbar/ToolbarNewTab.vue +5 -4
  165. package/src/app/components/toolbar/ToolbarResponsiveSize.vue +15 -15
  166. package/src/app/components/toolbar/ToolbarTextDirection.vue +5 -4
  167. package/src/app/components/toolbar/ToolbarTitle.vue +32 -8
  168. package/src/app/components/tree/StoryGroup.vue +5 -5
  169. package/src/app/components/tree/StoryList.vue +1 -1
  170. package/src/app/components/tree/StoryListFolder.vue +6 -6
  171. package/src/app/components/tree/StoryListItem.vue +6 -6
  172. package/src/app/index.ts +3 -0
  173. package/src/app/sandbox.ts +59 -15
  174. package/src/app/stores/layout.ts +22 -0
  175. package/src/app/stores/preview-settings.ts +26 -2
  176. package/src/app/style/floating.pcss +4 -4
  177. package/src/app/style/main.pcss +2 -2
  178. package/src/app/style/sandbox.css +1 -1
  179. package/src/app/types.ts +49 -0
  180. package/src/app/util/color-scheme.ts +36 -0
  181. package/src/app/util/const.ts +1 -0
  182. package/src/app/util/dark.ts +3 -3
  183. package/src/app/util/keyboard.ts +65 -32
  184. package/src/app/util/preview-settings.ts +16 -0
  185. package/src/app/util/tooltip.ts +2 -2
  186. package/src/bundle-main.js +2 -0
  187. package/src/shim.d.ts +2 -2
@@ -278,19 +278,19 @@ const {
278
278
 
279
279
  <template>
280
280
  <div
281
- class="poveste-search-pane htw-flex htw-items-center htw-gap-4 htw-pl-6 htw-border htw-border-transparent focus-visible:htw-border-primary-500"
281
+ class="poveste-search-pane ptw-flex ptw-items-center ptw-gap-4 ptw-pl-6 ptw-border ptw-border-transparent focus-visible:ptw-border-primary-500"
282
282
  @click="focused = true"
283
283
  >
284
284
  <Icon
285
285
  icon="carbon:search"
286
- class="flex-none htw-w-4 htw-h-4"
286
+ class="flex-none ptw-w-4 ptw-h-4"
287
287
  />
288
288
 
289
289
  <input
290
290
  ref="input"
291
291
  v-model="searchInputText"
292
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"
293
+ class="ptw-bg-transparent ptw-w-full ptw-flex-1 ptw-pl-0 ptw-pr-6 ptw-py-4 ptw-outline-none"
294
294
  @keydown.down.prevent="selectNext()"
295
295
  @keydown.up.prevent="selectPrevious()"
296
296
  @keydown.escape="close()"
@@ -306,7 +306,7 @@ const {
306
306
 
307
307
  <div
308
308
  v-else-if="results.length"
309
- class="htw-max-h-[400px] htw-overflow-y-auto htw-rounded-b-lg"
309
+ class="ptw-max-h-[400px] ptw-overflow-y-auto ptw-rounded-b-lg"
310
310
  >
311
311
  <SearchItem
312
312
  v-for="(result, index) of results"
@@ -122,39 +122,39 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
122
122
  </script>
123
123
 
124
124
  <template>
125
- <div class="poveste-story-responsive-preview htw-w-full htw-h-full htw-flex-1 htw-rounded-lg htw-relative htw-overflow-hidden">
125
+ <div class="poveste-story-responsive-preview ptw-w-full ptw-h-full ptw-flex-1 ptw-rounded-lg ptw-relative ptw-overflow-hidden">
126
126
  <div
127
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"
128
+ class="ptw-absolute ptw-inset-0 ptw-w-full ptw-h-full ptw-bg-gray-100 dark:ptw-bg-gray-750 ptw-rounded-r-lg ptw-border-l-2 ptw-border-gray-500/10 dark:ptw-border-gray-700/30 ptw-overflow-hidden"
129
129
  >
130
130
  <HatchedPattern
131
- class="htw-w-full htw-h-full htw-text-black/[1%] dark:htw-text-white/[1%]"
131
+ class="ptw-w-full ptw-h-full ptw-text-black/[1%] dark:ptw-text-white/[1%]"
132
132
  />
133
133
  </div>
134
134
 
135
135
  <div
136
136
  ref="previewWrapper"
137
- class="htw-h-full htw-overflow-auto htw-relative"
137
+ class="ptw-h-full ptw-overflow-auto ptw-relative"
138
138
  >
139
139
  <div
140
- class="htw-overflow-hidden htw-bg-white dark:htw-bg-gray-700 htw-rounded-lg htw-relative"
140
+ class="ptw-overflow-hidden ptw-bg-white dark:ptw-bg-gray-700 ptw-rounded-lg ptw-relative"
141
141
  :class="isResponsiveEnabled ? {
142
- 'htw-w-fit': !!finalWidth,
143
- 'htw-h-fit': !!finalHeight,
144
- 'htw-h-full': !finalHeight,
145
- } : 'htw-h-full'"
142
+ 'ptw-w-fit': !!finalWidth,
143
+ 'ptw-h-fit': !!finalHeight,
144
+ 'ptw-h-full': !finalHeight,
145
+ } : 'ptw-h-full'"
146
146
  >
147
147
  <div
148
- class="bind-preview-bg htw-rounded-lg htw-h-full"
148
+ class="bind-preview-bg ptw-rounded-lg ptw-h-full"
149
149
  data-test-id="responsive-preview-bg"
150
150
  >
151
151
  <CheckerboardPattern
152
152
  v-if="settings.checkerboard"
153
- class="htw-absolute htw-inset-0 htw-w-full htw-h-full htw-text-gray-500/20"
153
+ class="ptw-absolute ptw-inset-0 ptw-w-full ptw-h-full ptw-text-gray-500/20"
154
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" />
155
+ <div class="ptw-p-8 ptw-h-full ptw-relative">
156
+ <div class="ptw-w-full ptw-h-full ptw-relative">
157
+ <div class="ptw-absolute ptw-inset-0" />
158
158
 
159
159
  <slot
160
160
  :is-responsive-enabled="isResponsiveEnabled"
@@ -165,14 +165,14 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
165
165
  </div>
166
166
 
167
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" />
168
+ <div class="ptw-absolute ptw-top-5 ptw-left-8 ptw-h-2 ptw-w-px ptw-bg-gray-400/25" />
169
+ <div class="ptw-absolute ptw-top-5 ptw-right-8 ptw-h-2 ptw-w-px ptw-bg-gray-400/25" />
170
+ <div class="ptw-absolute ptw-bottom-5 ptw-left-8 ptw-h-2 ptw-w-px ptw-bg-gray-400/25" />
171
+ <div class="ptw-absolute ptw-bottom-5 ptw-right-8 ptw-h-2 ptw-w-px ptw-bg-gray-400/25" />
172
+ <div class="ptw-absolute ptw-left-5 ptw-top-8 ptw-w-2 ptw-h-px ptw-bg-gray-400/25" />
173
+ <div class="ptw-absolute ptw-left-5 ptw-bottom-8 ptw-w-2 ptw-h-px ptw-bg-gray-400/25" />
174
+ <div class="ptw-absolute ptw-right-5 ptw-top-8 ptw-w-2 ptw-h-px ptw-bg-gray-400/25" />
175
+ <div class="ptw-absolute ptw-right-5 ptw-bottom-8 ptw-w-2 ptw-h-px ptw-bg-gray-400/25" />
176
176
  </div>
177
177
 
178
178
  <!-- Resize Dragger -->
@@ -180,27 +180,27 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
180
180
  <div
181
181
  ref="horizontalDragger"
182
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"
183
+ class="ptw-absolute ptw-w-4 ptw-top-0 ptw-bottom-4 ptw-right-0 hover:ptw-bg-primary-500/30 ptw-flex ptw-items-center ptw-justify-center ptw-cursor-ew-resize ptw-group hover:ptw-text-primary-500"
184
184
  >
185
185
  <Icon
186
186
  icon="mdi:drag-vertical-variant"
187
- class="htw-w-4 htw-h-4 htw-opacity-20 group-hover:htw-opacity-90"
187
+ class="ptw-w-4 ptw-h-4 ptw-opacity-20 group-hover:ptw-opacity-90"
188
188
  />
189
189
  </div>
190
190
  <div
191
191
  ref="verticalDragger"
192
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"
193
+ class="ptw-absolute ptw-h-4 ptw-left-0 ptw-right-4 ptw-bottom-0 hover:ptw-bg-primary-500/30 ptw-flex ptw-items-center ptw-justify-center ptw-cursor-ns-resize ptw-group hover:ptw-text-primary-500"
194
194
  >
195
195
  <Icon
196
196
  icon="mdi:drag-horizontal-variant"
197
- class="htw-w-4 htw-h-4 htw-opacity-20 group-hover:htw-opacity-90"
197
+ class="ptw-w-4 ptw-h-4 ptw-opacity-20 group-hover:ptw-opacity-90"
198
198
  />
199
199
  </div>
200
200
  <div
201
201
  ref="cornerDragger"
202
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"
203
+ class="ptw-absolute ptw-w-4 ptw-h-4 ptw-right-0 ptw-bottom-0 hover:ptw-bg-primary-500/30 ptw-flex ptw-items-center ptw-justify-center ptw-cursor-nwse-resize ptw-group hover:ptw-text-primary-500"
204
204
  />
205
205
  </template>
206
206
  </div>
@@ -2,10 +2,6 @@
2
2
  import { useResizeObserver } from '@vueuse/core'
3
3
  import { computed, onMounted, ref, watch } from 'vue'
4
4
  import { useStoryStore } from '../../stores/story'
5
- import { isMobile } from '../../util/responsive'
6
- import DevOnlyToolbarOpenInEditor from '../toolbar/DevOnlyToolbarOpenInEditor.vue'
7
- import ToolbarBackground from '../toolbar/ToolbarBackground.vue'
8
- import ToolbarTextDirection from '../toolbar/ToolbarTextDirection.vue'
9
5
  import StoryVariantGridItem from './StoryVariantGridItem.vue'
10
6
 
11
7
  const storyStore = useStoryStore()
@@ -119,37 +115,22 @@ const columnCount = computed(() => Math.min(storyStore.currentStory.variants.len
119
115
  </script>
120
116
 
121
117
  <template>
122
- <div class="poveste-story-variant-grid htw-flex htw-flex-col htw-items-stretch htw-h-full __poveste-pane-shadow-from-right">
123
- <!-- Toolbar -->
124
- <div
125
- v-if="!isMobile"
126
- class="htw-flex-none htw-flex htw-items-center htw-justify-end htw-h-8 htw-mx-2 htw-mt-1"
127
- >
128
- <ToolbarBackground />
129
- <ToolbarTextDirection />
130
-
131
- <DevOnlyToolbarOpenInEditor
132
- v-if="__POVESTE_DEV__"
133
- :file="storyStore.currentStory.file?.filePath"
134
- tooltip="Edit story in editor"
135
- />
136
- </div>
137
-
118
+ <div class="poveste-story-variant-grid ptw-flex ptw-flex-col ptw-items-stretch ptw-h-full __poveste-pane-shadow-from-right">
138
119
  <div
139
120
  ref="el"
140
- class="htw-overflow-y-auto htw-flex htw-flex-1"
121
+ class="ptw-overflow-y-auto ptw-flex ptw-flex-1"
141
122
  @scroll="updateMaxCount()"
142
123
  >
143
- <div class="htw-flex htw-w-0 htw-flex-1 htw-mx-4">
124
+ <div class="ptw-flex ptw-w-0 ptw-flex-1 ptw-mx-4">
144
125
  <div
145
- class="htw-m-auto"
126
+ class="ptw-m-auto"
146
127
  :style="{
147
128
  minHeight: `${(storyStore.currentStory.variants.length / countPerRow) * (maxItemHeight + gap) - gap}px`,
148
129
  }"
149
130
  >
150
131
  <div
151
132
  ref="gridEl"
152
- class="htw-grid htw-gap-4 htw-my-4"
133
+ class="ptw-grid ptw-gap-4 ptw-my-4"
153
134
  :style="{
154
135
  gridTemplateColumns: `repeat(${columnCount}, ${gridColumnWidth}px)`,
155
136
  }"
@@ -7,8 +7,8 @@ import { useResizeObserver } from '@vueuse/core'
7
7
  import { computed, ref, toRefs } from 'vue'
8
8
  import { useRouter } from 'vue-router'
9
9
  import { usePreviewSettingsStore } from '../../stores/preview-settings'
10
+ import { usePreviewDark } from '../../util/color-scheme'
10
11
  import { povesteConfig } from '../../util/config'
11
- import { isDark } from '../../util/dark'
12
12
  import { getSourceCode } from '../../util/docs'
13
13
  import { getContrastColor } from '../../util/preview-settings'
14
14
  import { useScrollOnActive } from '../../util/scroll'
@@ -16,6 +16,7 @@ import { useCurrentVariantRoute } from '../../util/variant'
16
16
  import CheckerboardPattern from '../misc/CheckerboardPattern.vue'
17
17
  import ToolbarNewTab from '../toolbar/ToolbarNewTab.vue'
18
18
  import GenericRenderStory from './GenericRenderStory.vue'
19
+ import StoryVariantSinglePreviewRemote from './StoryVariantSinglePreviewRemote.vue'
19
20
 
20
21
  const props = defineProps({
21
22
  variant: {
@@ -66,39 +67,49 @@ useResizeObserver(el, () => {
66
67
 
67
68
  const settings = usePreviewSettingsStore().currentSettings
68
69
 
70
+ const previewDark = usePreviewDark(settings)
71
+
69
72
  const contrastColor = computed(() => getContrastColor(settings))
70
73
  const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastColor)
74
+
75
+ const useIframe = computed(() => {
76
+ const layout = props.story.layout
77
+ if (layout?.type === 'grid' && layout.iframeGrid !== undefined) {
78
+ return layout.iframeGrid
79
+ }
80
+ return povesteConfig.isolateStyles !== false
81
+ })
71
82
  </script>
72
83
 
73
84
  <template>
74
85
  <div
75
86
  ref="el"
76
- class="poveste-story-variant-grid-item htw-cursor-default htw-flex htw-flex-col htw-gap-y-1 htw-group"
87
+ class="poveste-story-variant-grid-item ptw-cursor-default ptw-flex ptw-flex-col ptw-gap-y-1 ptw-group"
77
88
  >
78
89
  <!-- Header -->
79
- <div class="htw-flex-none htw-flex htw-items-center">
90
+ <div class="ptw-flex-none ptw-flex ptw-items-center">
80
91
  <RouterLink
81
92
  v-tooltip="variant.title"
82
93
  :to="targetRoute"
83
- class="htw-rounded htw-w-max htw-px-2 htw-py-0.5 htw-min-w-16 htw-cursor-pointer htw-flex htw-items-center htw-gap-1 htw-flex-shrink"
94
+ class="ptw-rounded ptw-w-max ptw-px-2 ptw-py-0.5 ptw-min-w-16 ptw-cursor-pointer ptw-flex ptw-items-center ptw-gap-1 ptw-flex-shrink"
84
95
  :class="{
85
- 'hover:htw-bg-gray-200 htw-text-gray-500 dark:hover:htw-bg-gray-800': !isActive,
86
- 'htw-bg-primary-200 hover:htw-bg-primary-300 htw-text-primary-800 dark:htw-bg-primary-700 dark:hover:htw-bg-primary-800 dark:htw-text-primary-200': isActive,
96
+ 'hover:ptw-bg-gray-200 ptw-text-gray-500 dark:hover:ptw-bg-gray-800': !isActive,
97
+ 'ptw-bg-primary-200 hover:ptw-bg-primary-300 ptw-text-primary-800 dark:ptw-bg-primary-700 dark:hover:ptw-bg-primary-800 dark:ptw-text-primary-200': isActive,
87
98
  }"
88
99
  >
89
100
  <Icon
90
101
  :icon="variant.icon ?? 'carbon:cube'"
91
- class="htw-w-4 htw-h-4 htw-opacity-50"
102
+ class="ptw-w-4 ptw-h-4 ptw-opacity-50"
92
103
  :class="{
93
- 'htw-text-gray-500': !isActive && !variant.iconColor,
104
+ 'ptw-text-gray-500': !isActive && !variant.iconColor,
94
105
  'bind-icon-color': !isActive && variant.iconColor,
95
106
  }"
96
107
  />
97
- <span class="htw-truncate htw-flex-1">{{ variant.title }}</span>
108
+ <span class="ptw-truncate ptw-flex-1">{{ variant.title }}</span>
98
109
  </RouterLink>
99
110
 
100
111
  <!-- Toolbar -->
101
- <div class="htw-flex-none htw-ml-auto htw-hidden group-hover:htw-flex htw-items-center">
112
+ <div class="ptw-flex-none ptw-ml-auto ptw-hidden group-hover:ptw-flex ptw-items-center">
102
113
  <HstCopyIcon
103
114
  :content="() => getSourceCode(story, variant)"
104
115
  />
@@ -111,27 +122,27 @@ const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastC
111
122
 
112
123
  <!-- Body -->
113
124
  <div
114
- class="htw-border htw-bg-white dark:htw-bg-gray-700 htw-rounded htw-flex-1 htw-p-4 htw-relative"
125
+ class="ptw-border ptw-bg-white dark:ptw-bg-gray-700 ptw-rounded ptw-flex-1 ptw-p-4 ptw-relative"
115
126
  :class="{
116
- 'htw-border-gray-100 dark:htw-border-gray-800': !isActive,
117
- 'htw-border-primary-200 dark:htw-border-primary-900': isActive,
127
+ 'ptw-border-gray-100 dark:ptw-border-gray-800': !isActive,
128
+ 'ptw-border-primary-200 dark:ptw-border-primary-900': isActive,
118
129
  }"
119
130
  data-test-id="sandbox-render"
120
131
  @click.stop="selectVariant()"
121
132
  @keyup="selectVariant()"
122
133
  >
123
134
  <div
124
- class="htw-absolute htw-inset-0 htw-rounded bind-preview-bg"
135
+ class="ptw-absolute ptw-inset-0 ptw-rounded bind-preview-bg"
125
136
  data-test-id="responsive-preview-bg"
126
137
  />
127
138
 
128
139
  <CheckerboardPattern
129
140
  v-if="settings.checkerboard"
130
- class="htw-absolute htw-inset-0 htw-w-full htw-h-full htw-text-gray-500/20"
141
+ class="ptw-absolute ptw-inset-0 ptw-w-full ptw-h-full ptw-text-gray-500/20"
131
142
  />
132
143
 
133
144
  <div
134
- class="htw-relative htw-h-full"
145
+ class="ptw-relative ptw-h-full"
135
146
  :style="{
136
147
  '--poveste-contrast-color': contrastColor,
137
148
  // Deprecated alias — keep so stories referencing `var(--histoire-contrast-color)` still work.
@@ -139,13 +150,21 @@ const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastC
139
150
  'color': autoApplyContrastColor ? contrastColor : undefined,
140
151
  }"
141
152
  >
153
+ <StoryVariantSinglePreviewRemote
154
+ v-if="useIframe"
155
+ :key="`iframe-${story.id}-${variant.id}`"
156
+ :story="story"
157
+ :variant="variant"
158
+ auto-height
159
+ />
142
160
  <GenericRenderStory
161
+ v-else
143
162
  :key="`${story.id}-${variant.id}`"
144
163
  :variant="variant"
145
164
  :story="story"
146
165
  :dir="settings.textDirection"
147
166
  :class="{
148
- [povesteConfig.theme.darkClass]: isDark,
167
+ [povesteConfig.theme.darkClass]: previewDark,
149
168
  }"
150
169
  @ready="onReady"
151
170
  />
@@ -30,17 +30,17 @@ useScrollOnActive(isActive, el)
30
30
  v-slot="{ active }"
31
31
  :to="targetRoute"
32
32
  :is-active="isActive"
33
- class="htw-px-2 htw-py-2 md:htw-py-1.5 htw-m-1 htw-rounded-sm htw-flex htw-items-center htw-gap-2"
33
+ class="ptw-px-2 ptw-py-2 md:ptw-py-1.5 ptw-m-1 ptw-rounded-sm ptw-flex ptw-items-center ptw-gap-2"
34
34
  >
35
35
  <Icon
36
36
  :icon="variant.icon ?? 'carbon:cube'"
37
- class="htw-w-5 htw-h-5 sm:htw-w-4 sm:htw-h-4 htw-flex-none"
37
+ class="ptw-w-5 ptw-h-5 sm:ptw-w-4 sm:ptw-h-4 ptw-flex-none"
38
38
  :class="{
39
- 'htw-text-gray-500': !active && !variant.iconColor,
39
+ 'ptw-text-gray-500': !active && !variant.iconColor,
40
40
  'bind-icon-color': !active && variant.iconColor,
41
41
  }"
42
42
  />
43
- <span class="htw-truncate">{{ variant.title }}</span>
43
+ <span class="ptw-truncate">{{ variant.title }}</span>
44
44
  </BaseListItemLink>
45
45
  </div>
46
46
  </template>
@@ -21,7 +21,7 @@ const variant = computed(() => storyStore.currentVariant)
21
21
  <template>
22
22
  <div
23
23
  v-if="hasSingleVariant && variant"
24
- class="poveste-story-variant-single htw-p-2 htw-h-full __poveste-pane-shadow-from-right"
24
+ class="poveste-story-variant-single ptw-p-2 ptw-h-full __poveste-pane-shadow-from-right"
25
25
  >
26
26
  <StoryVariantSingleView
27
27
  :variant="variant"
@@ -31,18 +31,18 @@ const variant = computed(() => storyStore.currentVariant)
31
31
  <template v-else>
32
32
  <div
33
33
  v-if="isMobile"
34
- class="htw-divide-y htw-divide-gray-100 dark:htw-divide-gray-800 htw-h-full htw-flex htw-flex-col"
34
+ class="ptw-divide-y ptw-divide-gray-100 dark:ptw-divide-gray-800 ptw-h-full ptw-flex ptw-flex-col"
35
35
  >
36
36
  <a
37
- class="htw-px-6 htw-h-12 hover:htw-text-primary-500 dark:hover:htw-text-primary-400 htw-cursor-pointer htw-flex htw-gap-2 htw-flex-wrap htw-w-full htw-items-center htw-flex-none"
37
+ class="ptw-px-6 ptw-h-12 hover:ptw-text-primary-500 dark:hover:ptw-text-primary-400 ptw-cursor-pointer ptw-flex ptw-gap-2 ptw-flex-wrap ptw-w-full ptw-items-center ptw-flex-none"
38
38
  @click="$emit('openVariantMenu')"
39
39
  >
40
40
  <template v-if="variant">
41
41
  <Icon
42
42
  :icon="variant.icon ?? 'carbon:cube'"
43
- class="htw-w-5 htw-h-5 htw-flex-none"
43
+ class="ptw-w-5 ptw-h-5 ptw-flex-none"
44
44
  :class="{
45
- 'htw-text-gray-500': !variant.iconColor,
45
+ 'ptw-text-gray-500': !variant.iconColor,
46
46
  'bind-icon-color': variant.iconColor,
47
47
  }"
48
48
  />
@@ -54,12 +54,12 @@ const variant = computed(() => storyStore.currentVariant)
54
54
 
55
55
  <Icon
56
56
  icon="carbon:chevron-sort"
57
- class="htw-w-5 htw-h-5 htw-shrink-0 htw-ml-auto"
57
+ class="ptw-w-5 ptw-h-5 ptw-shrink-0 ptw-ml-auto"
58
58
  />
59
59
  </a>
60
60
  <div
61
61
  v-if="storyStore.currentVariant"
62
- class="htw-p-2 htw-h-full"
62
+ class="ptw-p-2 ptw-h-full"
63
63
  >
64
64
  <StoryVariantSingleView
65
65
  :variant="storyStore.currentVariant"
@@ -75,7 +75,7 @@ const variant = computed(() => storyStore.currentVariant)
75
75
  :default-split="17"
76
76
  >
77
77
  <template #first>
78
- <div class="htw-h-full htw-overflow-y-auto">
78
+ <div class="ptw-h-full ptw-overflow-y-auto">
79
79
  <StoryVariantListItem
80
80
  v-for="(v, index) of storyStore.currentStory.variants"
81
81
  :key="index"
@@ -86,7 +86,7 @@ const variant = computed(() => storyStore.currentVariant)
86
86
  <template #last>
87
87
  <div
88
88
  v-if="storyStore.currentVariant"
89
- class="htw-p-2 htw-h-full __poveste-pane-shadow-from-right"
89
+ class="ptw-p-2 ptw-h-full __poveste-pane-shadow-from-right"
90
90
  >
91
91
  <StoryVariantSingleView
92
92
  :variant="storyStore.currentVariant"
@@ -2,8 +2,8 @@
2
2
  import type { Story, Variant } from '../../types'
3
3
  import { computed } from 'vue'
4
4
  import { usePreviewSettingsStore } from '../../stores/preview-settings'
5
+ import { usePreviewDark } from '../../util/color-scheme'
5
6
  import { povesteConfig } from '../../util/config'
6
- import { isDark } from '../../util/dark'
7
7
  import { getContrastColor } from '../../util/preview-settings'
8
8
  import GenericRenderStory from './GenericRenderStory.vue'
9
9
  import StoryResponsivePreview from './StoryResponsivePreview.vue'
@@ -25,6 +25,8 @@ function onReady() {
25
25
 
26
26
  const settings = usePreviewSettingsStore().currentSettings
27
27
 
28
+ const previewDark = usePreviewDark(settings)
29
+
28
30
  const contrastColor = computed(() => getContrastColor(settings))
29
31
  const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastColor)
30
32
  </script>
@@ -48,17 +50,17 @@ const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastC
48
50
  'color': autoApplyContrastColor ? contrastColor : undefined,
49
51
  },
50
52
  ]"
51
- class="htw-relative"
53
+ class="ptw-relative"
52
54
  data-test-id="sandbox-render"
53
55
  >
54
56
  <GenericRenderStory
55
57
  :key="`${story.id}-${variant.id}`"
56
58
  :variant="variant"
57
59
  :story="story"
58
- class="htw-h-full"
60
+ class="ptw-h-full"
59
61
  :class="{
60
- [povesteConfig.sandboxDarkClass]: isDark, // @TODO remove
61
- [povesteConfig.theme.darkClass]: isDark,
62
+ [povesteConfig.sandboxDarkClass]: previewDark, // @TODO remove
63
+ [povesteConfig.theme.darkClass]: previewDark,
62
64
  }"
63
65
  :dir="settings.textDirection"
64
66
  @ready="onReady"
@@ -3,10 +3,11 @@ import type { HstEvent } from '../../stores/events'
3
3
  import type { Story, Variant } from '../../types'
4
4
  import { applyState } from '@poveste/shared'
5
5
  import { useEventListener } from '@vueuse/core'
6
- import { computed, ref, toRaw, watch } from 'vue'
6
+ import { computed, onBeforeUnmount, ref, toRaw, watch } from 'vue'
7
7
  import { useEventsStore } from '../../stores/events'
8
8
  import { usePreviewSettingsStore } from '../../stores/preview-settings'
9
- import { EVENT_SEND, PREVIEW_SETTINGS_SYNC, SANDBOX_READY, STATE_SYNC } from '../../util/const'
9
+ import { EVENT_SEND, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from '../../util/const'
10
+ import { trackWindow } from '../../util/keyboard'
10
11
  import { getSandboxUrl } from '../../util/sandbox'
11
12
  import { toRawDeep } from '../../util/state'
12
13
  import StoryResponsivePreview from './StoryResponsivePreview.vue'
@@ -14,6 +15,7 @@ import StoryResponsivePreview from './StoryResponsivePreview.vue'
14
15
  const props = defineProps<{
15
16
  story: Story
16
17
  variant: Variant
18
+ autoHeight?: boolean
17
19
  }>()
18
20
 
19
21
  const settings = usePreviewSettingsStore().currentSettings
@@ -48,8 +50,13 @@ Object.assign(props.variant, {
48
50
  previewReady: false,
49
51
  })
50
52
 
53
+ const reportedHeight = ref<number | null>(null)
54
+
51
55
  useEventListener(window, 'message', (event) => {
52
- switch (event.data.type) {
56
+ // With many grid iframes mounted, every sandbox postMessage hits every
57
+ // parent listener. Skip events that didn't originate from this iframe.
58
+ if (event.source !== iframe.value?.contentWindow) return
59
+ switch (event.data?.type) {
53
60
  case STATE_SYNC:
54
61
  updateVariantState(event.data.state)
55
62
  break
@@ -59,6 +66,12 @@ useEventListener(window, 'message', (event) => {
59
66
  case SANDBOX_READY:
60
67
  setPreviewReady()
61
68
  break
69
+ case SANDBOX_HEIGHT:
70
+ if (typeof event.data.h === 'number') {
71
+ const next = Math.max(40, event.data.h)
72
+ if (next !== reportedHeight.value) reportedHeight.value = next
73
+ }
74
+ break
62
75
  }
63
76
  })
64
77
 
@@ -84,11 +97,21 @@ const sandboxUrl = computed(() => {
84
97
 
85
98
  const isIframeLoaded = ref(false)
86
99
 
100
+ let stopTrackKeyboard: (() => void) | undefined
101
+ let unmounted = false
102
+
87
103
  watch(sandboxUrl, () => {
88
104
  isIframeLoaded.value = false
89
105
  Object.assign(props.variant, {
90
106
  previewReady: false,
91
107
  })
108
+ stopTrackKeyboard?.()
109
+ stopTrackKeyboard = undefined
110
+ })
111
+
112
+ onBeforeUnmount(() => {
113
+ unmounted = true
114
+ stopTrackKeyboard?.()
92
115
  })
93
116
 
94
117
  // Settings
@@ -112,9 +135,16 @@ watch(() => settings, () => {
112
135
  // Iframe load
113
136
 
114
137
  function onIframeLoad() {
138
+ if (unmounted) {
139
+ return
140
+ }
115
141
  isIframeLoaded.value = true
116
142
  syncState()
117
143
  syncSettings()
144
+ stopTrackKeyboard?.()
145
+ if (iframe.value?.contentWindow) {
146
+ stopTrackKeyboard = trackWindow(iframe.value.contentWindow)
147
+ }
118
148
  }
119
149
  </script>
120
150
 
@@ -127,15 +157,15 @@ function onIframeLoad() {
127
157
  <iframe
128
158
  ref="iframe"
129
159
  :src="sandboxUrl"
130
- class="htw-w-full htw-h-full htw-relative"
160
+ class="ptw-w-full ptw-h-full ptw-relative"
131
161
  :class="{
132
- 'htw-invisible': !isIframeLoaded,
133
- 'htw-pointer-events-none': resizing,
162
+ 'ptw-invisible': !isIframeLoaded,
163
+ 'ptw-pointer-events-none': resizing,
134
164
  }"
135
165
  :style="isResponsiveEnabled ? {
136
166
  width: finalWidth ? `${finalWidth}px` : null,
137
167
  height: finalHeight ? `${finalHeight}px` : null,
138
- } : undefined"
168
+ } : (props.autoHeight && reportedHeight ? { height: `${reportedHeight}px` } : undefined)"
139
169
  data-test-id="preview-iframe"
140
170
  @load="onIframeLoad()"
141
171
  />
@@ -1,12 +1,5 @@
1
1
  <script lang="ts" setup>
2
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
3
  import StoryVariantSinglePreviewNative from './StoryVariantSinglePreviewNative.vue'
11
4
  import StoryVariantSinglePreviewRemote from './StoryVariantSinglePreviewRemote.vue'
12
5
 
@@ -18,35 +11,9 @@ defineProps<{
18
11
 
19
12
  <template>
20
13
  <div
21
- class="poveste-story-variant-single-view htw-h-full htw-flex htw-flex-col"
14
+ class="poveste-story-variant-single-view ptw-h-full ptw-flex ptw-flex-col"
22
15
  data-test-id="story-variant-single-view"
23
16
  >
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="__POVESTE_DEV__"
44
- :file="story.file?.filePath"
45
- tooltip="Edit story in editor"
46
- />
47
- </div>
48
-
49
- <!-- Preview -->
50
17
  <StoryVariantSinglePreviewNative
51
18
  v-if="story.layout?.iframe === false"
52
19
  :story="story"