-
(mapFile(files.find(f => f.id === query.storyId)))
@@ -22,69 +26,129 @@ const app = createApp({
setup() {
const story = computed(() => file.value.story)
- const variant = computed(() => story.value?.variants.find(v => v.id === query.variantId))
+ const grid = computed(() => query.grid === 'true')
+ const gridSelectedVariantId = ref(null)
+ const variant = computed(() => story.value?.variants.find(v => v.id === query.variantId || v.id === gridSelectedVariantId.value))
let synced = false
let mounted = false
+ const previewSettingsStore = usePreviewSettingsStore()
+
window.addEventListener('message', (event) => {
// console.log('[sandbox] received message', event.data)
if (event.data?.type === STATE_SYNC) {
if (!mounted) return
synced = true
- applyState(variant.value.state, event.data.state)
+ if (!grid.value || variant.value?.id === event.data.variantId) {
+ applyState(variant.value.state, event.data.state)
+ }
}
else if (event.data?.type === PREVIEW_SETTINGS_SYNC) {
- applyPreviewSettings(event.data.settings)
+ if (grid.value) {
+ Object.assign(previewSettingsStore.currentSettings, event.data.settings)
+ }
+ else {
+ applyPreviewSettings(event.data.settings)
+ }
+ }
+ else if (event.data?.type === SELECT_VARIANT) {
+ gridSelectedVariantId.value = event.data.variantId
}
})
- watch(() => variant.value.state, (value) => {
+ watch(() => variant.value?.state, (value) => {
if (synced && mounted) {
synced = false
return
}
+ if (!variant.value) return
window.parent?.postMessage({
+ __histoire: true,
type: STATE_SYNC,
+ variantId: variant.value.id,
state: toRawDeep(value, true),
})
}, {
deep: true,
+ flush: 'sync',
})
+ function sendReady() {
+ window.parent?.postMessage({
+ __histoire: true,
+ type: SANDBOX_READY,
+ variantId: variant.value?.id,
+ })
+ }
+
onMounted(() => {
mounted = true
- })
- return {
- story,
- variant,
- }
- },
+ if (grid.value) {
+ sendReady()
+ }
+ })
- render() {
- return [
+ return () => [
h('div', { class: 'htw-sandbox-hidden' }, [
h(GenericMountStory, {
key: file.value.story.id,
story: file.value.story,
}),
]),
- this.story && this.variant
- ? h(GenericRenderStory, {
- story: this.story,
- variant: this.variant,
- onReady: () => {
- window.parent?.postMessage({
- type: SANDBOX_READY,
+ story.value
+ ? grid.value
+ ? h(StoryVariantGrid, {
+ story: story.value,
+ variant: variant.value,
+ onSelect: (variantId) => {
+ synced = false
+
+ gridSelectedVariantId.value = variantId
+
+ window.parent?.postMessage({
+ __histoire: true,
+ type: SELECT_VARIANT,
+ variantId,
+ })
+ },
+ onReady: (variantId) => {
+ window.parent?.postMessage({
+ __histoire: true,
+ type: VARIANT_READY,
+ variantId,
+ })
+ },
+ })
+ : variant.value
+ ? h(GenericRenderStory, {
+ // ref: renderStory,
+ story: story.value,
+ variant: variant.value,
+ onReady: () => {
+ sendReady()
+ },
})
- },
- })
+ : null
: null,
]
},
})
app.use(createPinia())
+app.use(FloatingVue, {
+ overflowPadding: 4,
+ arrowPadding: 8,
+ themes: {
+ tooltip: {
+ distance: 8,
+ },
+ dropdown: {
+ computeTransformOrigin: true,
+ distance: 8,
+ },
+ },
+})
app.mount('#app')
watch(isDark, (value) => {
diff --git a/packages/histoire-app/src/app/stores/story.ts b/packages/histoire-app/src/app/stores/story.ts
index e4e9d484..8d0f2034 100644
--- a/packages/histoire-app/src/app/stores/story.ts
+++ b/packages/histoire-app/src/app/stores/story.ts
@@ -11,7 +11,7 @@ export const useStoryStore = defineStore('story', () => {
const currentStory = computed(() => stories.value.find(s => s.id === router.currentRoute.value.params.storyId))
- const currentVariant = computed(() => currentStory.value?.variants.find(v => v.id === router.currentRoute.value.query.variantId))
+ const currentVariant = computed(() => getCurrentStoryVariantById(String(router.currentRoute.value.query.variantId)))
const maps = computed(() => {
const storyMap = new Map()
@@ -36,6 +36,10 @@ export const useStoryStore = defineStore('story', () => {
return maps.value.variants.get(idWithStoryId)
}
+ function getCurrentStoryVariantById(variantId: string) {
+ return currentStory.value?.variants.find(v => v.id === variantId)
+ }
+
return {
stories,
setStories,
@@ -43,5 +47,6 @@ export const useStoryStore = defineStore('story', () => {
currentVariant,
getStoryById,
getVariantById,
+ getCurrentStoryVariantById,
}
})
diff --git a/packages/histoire-app/src/app/style/main.pcss b/packages/histoire-app/src/app/style/main.pcss
index e4ae21ec..9bc4c57c 100644
--- a/packages/histoire-app/src/app/style/main.pcss
+++ b/packages/histoire-app/src/app/style/main.pcss
@@ -64,11 +64,6 @@ button {
}
}
- .__histoire-render-story:not(.__histoire-render-custom-controls) {
- overflow: auto;
- min-height: 100%;
- }
-
.__histoire-code .shiki {
background: transparent !important;
}
diff --git a/packages/histoire-app/src/app/style/sandbox.css b/packages/histoire-app/src/app/style/sandbox.css
index 8877f168..6732dae1 100644
--- a/packages/histoire-app/src/app/style/sandbox.css
+++ b/packages/histoire-app/src/app/style/sandbox.css
@@ -17,8 +17,3 @@ html {
.htw-sandbox-hidden {
display: none;
}
-
-.__histoire-render-story:not(.__histoire-render-custom-controls) {
- overflow: auto;
- min-height: 100%;
-}
diff --git a/packages/histoire-app/src/app/util/const.ts b/packages/histoire-app/src/app/util/const.ts
index 6be13175..8eb485d1 100644
--- a/packages/histoire-app/src/app/util/const.ts
+++ b/packages/histoire-app/src/app/util/const.ts
@@ -2,3 +2,5 @@ export const STATE_SYNC = '__histoire:state-sync'
export const SANDBOX_READY = '__histoire:sandbox-ready'
export const EVENT_SEND = '__histoire:event'
export const PREVIEW_SETTINGS_SYNC = '__histoire:preview-settings-sync'
+export const SELECT_VARIANT = '__histoire:select-variant'
+export const VARIANT_READY = '__histoire:variant-ready'
diff --git a/packages/histoire-app/src/app/util/events.ts b/packages/histoire-app/src/app/util/events.ts
index c63d726f..abcbcf03 100644
--- a/packages/histoire-app/src/app/util/events.ts
+++ b/packages/histoire-app/src/app/util/events.ts
@@ -1,3 +1,4 @@
+import { parseQuery } from 'vue-router'
import { EVENT_SEND } from './const'
export async function logEvent(name: string, argument) {
@@ -7,9 +8,12 @@ export async function logEvent(name: string, argument) {
argument: JSON.parse(stringifyEvent(argument)), // Needed for HTMLEvent that can't be cloned
}
if (location.href.includes('__sandbox')) {
+ const query = parseQuery(window.location.search)
window.parent?.postMessage({
+ __histoire: true,
type: EVENT_SEND,
event,
+ variantId: query.variantId,
})
}
else {
diff --git a/packages/histoire-app/src/app/util/sandbox.ts b/packages/histoire-app/src/app/util/sandbox.ts
index 572ed271..dd99bae3 100644
--- a/packages/histoire-app/src/app/util/sandbox.ts
+++ b/packages/histoire-app/src/app/util/sandbox.ts
@@ -1,9 +1,14 @@
import { base } from '../router'
import type { Story, Variant } from '../types'
-export function getSandboxUrl(story: Story, variant: Variant) {
+export function getSandboxUrl(story: Story, variant?: Variant) {
const url = new URLSearchParams()
url.append('storyId', story.id)
- url.append('variantId', variant.id)
+ if (variant) {
+ url.append('variantId', variant.id)
+ }
+ else {
+ url.append('grid', 'true')
+ }
return `${base}__sandbox.html?${url.toString()}`
}
diff --git a/packages/histoire-controls/src/components/button/HstButton.story.vue b/packages/histoire-controls/src/components/button/HstButton.story.vue
index 4f2885fe..cd8916a2 100644
--- a/packages/histoire-controls/src/components/button/HstButton.story.vue
+++ b/packages/histoire-controls/src/components/button/HstButton.story.vue
@@ -12,7 +12,7 @@ const variants: Array<{ name: string, bind?: unknown }> = [