@poveste/app 0.15.0 → 0.16.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/dist/app/style/main.pcss +18 -44
- package/dist/bundled/App.vue_vue_type_script_setup_true_lang.js +9 -7
- package/dist/bundled/app.css +80 -17
- package/dist/bundled/components/app/AppActions.vue_vue_type_script_setup_true_lang.js +44 -27
- package/dist/bundled/components/app/ShortcutTooltip.js +5 -0
- package/dist/bundled/components/app/ShortcutTooltip.vue_vue_type_script_setup_true_lang.js +27 -0
- package/dist/bundled/components/base/BaseDropdown.js +6 -0
- package/dist/bundled/components/base/BaseDropdown.vue_vue_type_script_setup_true_lang.js +68 -0
- package/dist/bundled/components/base/BaseOverflowMenu.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/bundled/components/base/BaseSelect.js +1 -0
- package/dist/bundled/components/base/BaseSelect.vue_vue_type_script_setup_true_lang.js +80 -51
- package/dist/bundled/components/base/BaseSplitPane.js +1 -1
- package/dist/bundled/components/base/BaseSplitPane.vue_vue_type_script_setup_true_lang.js +65 -4
- package/dist/bundled/components/panel/ControlsComponentPropItem.vue_vue_type_script_setup_true_lang.js +15 -13
- package/dist/bundled/components/panel/ControlsComponentProps.vue_vue_type_script_setup_true_lang.js +9 -6
- package/dist/bundled/components/panel/ControlsComponentState.vue_vue_type_script_setup_true_lang.js +9 -6
- package/dist/bundled/components/panel/StatePresets.vue_vue_type_script_setup_true_lang.js +69 -54
- package/dist/bundled/components/panel/StoryEvent.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/bundled/components/panel/StorySidePanel.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/bundled/components/panel/StorySourceCode.js +1 -1
- package/dist/bundled/components/panel/StorySourceCode.vue_vue_type_script_setup_true_lang.js +21 -16
- package/dist/bundled/components/story/StoryResponsivePreview.js +1 -1
- package/dist/bundled/components/story/StoryResponsivePreview.vue_vue_type_script_setup_true_lang.js +46 -43
- package/dist/bundled/components/story/StoryVariantGridItem.js +1 -1
- package/dist/bundled/components/story/StoryVariantGridItem.vue_vue_type_script_setup_true_lang.js +21 -19
- package/dist/bundled/components/story/StoryVariantSingle.js +1 -1
- package/dist/bundled/components/story/StoryVariantSingle.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/bundled/components/story/StoryView.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/bundled/components/toolbar/DevOnlyToolbarOpenInEditor.vue_vue_type_script_setup_true_lang.js +15 -12
- package/dist/bundled/components/toolbar/ToolbarBackground.vue_vue_type_script_setup_true_lang.js +20 -16
- package/dist/bundled/components/toolbar/ToolbarNewTab.vue_vue_type_script_setup_true_lang.js +16 -13
- package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue_vue_type_script_setup_true_lang.js +35 -24
- package/dist/bundled/components/toolbar/ToolbarTextDirection.vue_vue_type_script_setup_true_lang.js +15 -12
- package/dist/bundled/index.js +0 -13
- package/dist/bundled/sandbox.js +2 -1
- package/dist/bundled/util/icons.generated.js +4 -2
- package/dist/bundled/util/scroll.js +26 -5
- package/dist/bundled/util/state.js +105 -5
- package/dist/style.css +731 -357
- package/package.json +19 -15
- package/src/__tests__/base-select.spec.ts +25 -0
- package/src/__tests__/reset.spec.ts +53 -0
- package/src/__tests__/state-clone.spec.ts +55 -1
- package/src/__tests__/state-types.spec.ts +175 -0
- package/src/app/App.vue +43 -34
- package/src/app/components/app/AppActions.vue +42 -30
- package/src/app/components/app/ShortcutTooltip.vue +29 -0
- package/src/app/components/base/BaseDropdown.vue +142 -0
- package/src/app/components/base/BaseOverflowMenu.vue +10 -5
- package/src/app/components/base/BaseSelect.vue +133 -60
- package/src/app/components/base/BaseSplitPane.vue +73 -2
- package/src/app/components/panel/ControlsComponentPropItem.vue +18 -17
- package/src/app/components/panel/ControlsComponentProps.vue +7 -5
- package/src/app/components/panel/ControlsComponentState.vue +7 -5
- package/src/app/components/panel/StatePresets.vue +82 -76
- package/src/app/components/panel/StoryEvent.vue +10 -9
- package/src/app/components/panel/StorySidePanel.vue +1 -0
- package/src/app/components/panel/StorySourceCode.vue +47 -41
- package/src/app/components/story/StoryResponsivePreview.vue +55 -27
- package/src/app/components/story/StoryVariantGridItem.vue +19 -18
- package/src/app/components/story/StoryVariantSingle.vue +1 -0
- package/src/app/components/story/StoryView.vue +1 -0
- package/src/app/components/toolbar/DevOnlyToolbarOpenInEditor.vue +14 -12
- package/src/app/components/toolbar/ToolbarBackground.vue +22 -23
- package/src/app/components/toolbar/ToolbarNewTab.vue +14 -12
- package/src/app/components/toolbar/ToolbarResponsiveSize.vue +31 -25
- package/src/app/components/toolbar/ToolbarTextDirection.vue +14 -10
- package/src/app/index.ts +0 -17
- package/src/app/sandbox.ts +8 -1
- package/src/app/style/main.pcss +18 -44
- package/src/app/util/icons.generated.ts +2 -2
- package/src/app/util/scroll.ts +47 -9
- package/src/app/util/state.ts +139 -6
- package/dist/app/style/floating.pcss +0 -40
- package/dist/bundled/util/tooltip.js +0 -14
- package/src/app/style/floating.pcss +0 -40
- package/src/app/util/tooltip.ts +0 -13
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { Story, Variant } from '../../types'
|
|
3
3
|
import { Icon } from '@iconify/vue'
|
|
4
|
+
import { HstTooltip } from '@poveste/controls'
|
|
4
5
|
import { applyState, clone } from '@poveste/shared'
|
|
5
6
|
import { onClickOutside, useLiveAnnouncer, useStorage, useTimeoutFn } from '@vueuse/core'
|
|
6
7
|
import { computed, nextTick, onMounted, ref } from 'vue'
|
|
@@ -188,81 +189,86 @@ onClickOutside(select, () => stopEditing())
|
|
|
188
189
|
@select="id => applyPreset(id)"
|
|
189
190
|
/>
|
|
190
191
|
</div>
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
192
|
+
<HstTooltip :content="canEdit ? 'Rename this preset' : null">
|
|
193
|
+
<button
|
|
194
|
+
type="button"
|
|
195
|
+
data-testid="preset-rename"
|
|
196
|
+
aria-label="Rename preset"
|
|
197
|
+
:disabled="!canEdit"
|
|
198
|
+
class="flex-none flex p-0 bg-transparent border-0 cursor-pointer text-gray-900 dark:text-gray-100 hover:text-primary-500 dark:hover:text-primary-400"
|
|
199
|
+
:class="[
|
|
200
|
+
canEdit ? 'opacity-50 hover:opacity-100 focus-visible:opacity-100' : 'opacity-25 pointer-events-none',
|
|
201
|
+
]"
|
|
202
|
+
@click="startEditing()"
|
|
203
|
+
>
|
|
204
|
+
<Icon
|
|
205
|
+
icon="carbon:edit"
|
|
206
|
+
class="w-4 h-4"
|
|
207
|
+
/>
|
|
208
|
+
</button>
|
|
209
|
+
</HstTooltip>
|
|
210
|
+
<HstTooltip :content="canEdit ? 'Delete this preset' : null">
|
|
211
|
+
<button
|
|
212
|
+
type="button"
|
|
213
|
+
data-testid="preset-delete"
|
|
214
|
+
aria-label="Delete preset"
|
|
215
|
+
:disabled="!canEdit"
|
|
216
|
+
class="flex-none flex p-0 bg-transparent border-0 cursor-pointer text-gray-900 dark:text-gray-100 hover:text-primary-500 dark:hover:text-primary-400"
|
|
217
|
+
:class="[
|
|
218
|
+
canEdit ? 'opacity-50 hover:opacity-100 focus-visible:opacity-100' : 'opacity-25 pointer-events-none',
|
|
219
|
+
]"
|
|
220
|
+
@click="deletePreset(selectedOption)"
|
|
221
|
+
>
|
|
222
|
+
<Icon
|
|
223
|
+
icon="carbon:trash-can"
|
|
224
|
+
class="w-4 h-4"
|
|
225
|
+
/>
|
|
226
|
+
</button>
|
|
227
|
+
</HstTooltip>
|
|
228
|
+
<HstTooltip :content="savedNotif ? 'Saved!' : canEdit ? 'Save to preset' : null">
|
|
229
|
+
<button
|
|
230
|
+
type="button"
|
|
231
|
+
data-testid="preset-save"
|
|
232
|
+
aria-label="Save to preset"
|
|
233
|
+
:disabled="!canEdit"
|
|
234
|
+
class="flex-none flex p-0 bg-transparent border-0 cursor-pointer text-gray-900 dark:text-gray-100 hover:text-primary-500 dark:hover:text-primary-400"
|
|
235
|
+
:class="[
|
|
236
|
+
canEdit ? 'opacity-50 hover:opacity-100 focus-visible:opacity-100' : 'opacity-25 pointer-events-none',
|
|
237
|
+
]"
|
|
238
|
+
@click="savePreset()"
|
|
239
|
+
>
|
|
240
|
+
<Icon
|
|
241
|
+
:icon="savedNotif ? 'carbon:checkmark' : 'carbon:save'"
|
|
242
|
+
class="w-4 h-4"
|
|
243
|
+
/>
|
|
244
|
+
</button>
|
|
245
|
+
</HstTooltip>
|
|
246
|
+
<HstTooltip content="Create new preset">
|
|
247
|
+
<button
|
|
248
|
+
type="button"
|
|
249
|
+
data-testid="preset-create"
|
|
250
|
+
aria-label="Create new preset"
|
|
251
|
+
class="flex-none flex p-0 bg-transparent border-0 cursor-pointer text-gray-900 dark:text-gray-100 hover:text-primary-500 dark:hover:text-primary-400 opacity-50 hover:opacity-100 focus-visible:opacity-100"
|
|
252
|
+
@click="createPreset()"
|
|
253
|
+
>
|
|
254
|
+
<Icon
|
|
255
|
+
icon="carbon:add-alt"
|
|
256
|
+
class="w-4 h-4"
|
|
257
|
+
/>
|
|
258
|
+
</button>
|
|
259
|
+
</HstTooltip>
|
|
260
|
+
<HstTooltip content="Reset to initial state">
|
|
261
|
+
<button
|
|
262
|
+
type="button"
|
|
263
|
+
aria-label="Reset to initial state"
|
|
264
|
+
class="flex-none flex p-0 bg-transparent border-0 cursor-pointer text-gray-900 dark:text-gray-100 hover:text-primary-500 dark:hover:text-primary-400 opacity-50 hover:opacity-100 focus-visible:opacity-100"
|
|
265
|
+
@click="resetState()"
|
|
266
|
+
>
|
|
267
|
+
<Icon
|
|
268
|
+
icon="carbon:reset"
|
|
269
|
+
class="w-4 h-4"
|
|
270
|
+
/>
|
|
271
|
+
</button>
|
|
272
|
+
</HstTooltip>
|
|
267
273
|
</div>
|
|
268
274
|
</template>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { HstEvent } from '../../stores/events'
|
|
3
3
|
import { computed } from 'vue'
|
|
4
|
+
import BaseDropdown from '../base/BaseDropdown.vue'
|
|
4
5
|
|
|
5
6
|
const props = defineProps<{
|
|
6
7
|
event: HstEvent
|
|
@@ -24,21 +25,21 @@ const formattedArgument = computed(() => {
|
|
|
24
25
|
</script>
|
|
25
26
|
|
|
26
27
|
<template>
|
|
27
|
-
<
|
|
28
|
+
<BaseDropdown
|
|
29
|
+
side="right"
|
|
28
30
|
class="poveste-story-event group"
|
|
29
|
-
placement="right"
|
|
30
31
|
data-testid="event-item"
|
|
31
32
|
>
|
|
32
|
-
<template #default="{
|
|
33
|
-
<
|
|
34
|
-
class="group-hover:bg-primary-100 dark:group-hover:bg-primary-700 cursor-pointer py-2 px-4 flex items-baseline gap-1 leading-normal"
|
|
33
|
+
<template #default="{ open }">
|
|
34
|
+
<button
|
|
35
|
+
class="group-hover:bg-primary-100 dark:group-hover:bg-primary-700 cursor-pointer py-2 px-4 w-full text-left flex items-baseline gap-1 leading-normal"
|
|
35
36
|
:class="[
|
|
36
|
-
|
|
37
|
+
open ? 'bg-primary-50 dark:bg-primary-600' : 'group-odd:bg-gray-100/50 dark:group-odd:bg-gray-750/40',
|
|
37
38
|
]"
|
|
38
39
|
>
|
|
39
40
|
<span
|
|
40
41
|
:class="{
|
|
41
|
-
'text-primary-500':
|
|
42
|
+
'text-primary-500': open,
|
|
42
43
|
}"
|
|
43
44
|
>
|
|
44
45
|
{{ event.name }}
|
|
@@ -47,7 +48,7 @@ const formattedArgument = computed(() => {
|
|
|
47
48
|
v-if="event.argument"
|
|
48
49
|
class="text-xs opacity-50 truncate"
|
|
49
50
|
>{{ formattedArgument }}</span>
|
|
50
|
-
</
|
|
51
|
+
</button>
|
|
51
52
|
</template>
|
|
52
53
|
|
|
53
54
|
<template #popper>
|
|
@@ -55,5 +56,5 @@ const formattedArgument = computed(() => {
|
|
|
55
56
|
<pre class="p-4">{{ event.argument }}</pre>
|
|
56
57
|
</div>
|
|
57
58
|
</template>
|
|
58
|
-
</
|
|
59
|
+
</BaseDropdown>
|
|
59
60
|
</template>
|
|
@@ -53,6 +53,7 @@ const panelContentComponent = computed(() => {
|
|
|
53
53
|
<BaseSplitPane
|
|
54
54
|
v-else
|
|
55
55
|
:save-id="`story-sidepane-${innerOrientation}`"
|
|
56
|
+
label="Resize the controls panel"
|
|
56
57
|
:orientation="innerOrientation"
|
|
57
58
|
class="poveste-story-side-panel poveste-loaded h-full"
|
|
58
59
|
data-testid="story-side-panel"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { HighlighterCore } from 'shiki/core'
|
|
3
3
|
import type { Story, Variant } from '../../types'
|
|
4
4
|
import { Icon } from '@iconify/vue'
|
|
5
|
-
import { HstCopyIcon } from '@poveste/controls'
|
|
5
|
+
import { HstCopyIcon, HstTooltip } from '@poveste/controls'
|
|
6
6
|
import { unindent } from '@poveste/shared'
|
|
7
7
|
import { clientSupportPlugins } from 'virtual:$poveste-support-plugins-client'
|
|
8
8
|
import { computed, markRaw, nextTick, onMounted, ref, shallowRef, watch, watchEffect } from 'vue'
|
|
@@ -151,50 +151,56 @@ watch(sourceHtml, async () => {
|
|
|
151
151
|
|
|
152
152
|
<!-- Display source modes -->
|
|
153
153
|
<div class="flex flex-none gap-px h-full py-2">
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
class="flex items-center gap-1 h-full px-1 bg-gray-500/10 rounded-l transition-all ease-[cubic-bezier(0,1,.6,1)] duration-300 overflow-hidden"
|
|
157
|
-
:class="[
|
|
158
|
-
displayedSource !== 'dynamic' ? 'max-w-6 opacity-70' : 'max-w-[82px] text-primary-800 dark:text-primary-400',
|
|
159
|
-
dynamicSourceCode ? 'cursor-pointer hover:bg-gray-500/30 active:bg-gray-600/50' : displayedSource !== 'dynamic' && 'opacity-50',
|
|
160
|
-
]"
|
|
161
|
-
@click="dynamicSourceCode && (displayedSource = 'dynamic')"
|
|
154
|
+
<HstTooltip
|
|
155
|
+
:content="!dynamicSourceCode ? 'Dynamic source code is not available' : displayedSource !== 'dynamic' ? 'Switch to dynamic source' : null"
|
|
162
156
|
>
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
class="
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
'opacity-0': displayedSource !== 'dynamic',
|
|
171
|
-
}"
|
|
157
|
+
<button
|
|
158
|
+
class="flex items-center gap-1 h-full px-1 bg-gray-500/10 rounded-l transition-all ease-[cubic-bezier(0,1,.6,1)] duration-300 overflow-hidden"
|
|
159
|
+
:class="[
|
|
160
|
+
displayedSource !== 'dynamic' ? 'max-w-6 opacity-70' : 'max-w-[82px] text-primary-800 dark:text-primary-400',
|
|
161
|
+
dynamicSourceCode ? 'cursor-pointer hover:bg-gray-500/30 active:bg-gray-600/50' : displayedSource !== 'dynamic' && 'opacity-50',
|
|
162
|
+
]"
|
|
163
|
+
@click="dynamicSourceCode && (displayedSource = 'dynamic')"
|
|
172
164
|
>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
165
|
+
<Icon
|
|
166
|
+
icon="carbon:flash"
|
|
167
|
+
class="w-4 h-4 flex-none"
|
|
168
|
+
/>
|
|
169
|
+
<span
|
|
170
|
+
class="transition-opacity duration-300"
|
|
171
|
+
:class="{
|
|
172
|
+
'opacity-0': displayedSource !== 'dynamic',
|
|
173
|
+
}"
|
|
174
|
+
>
|
|
175
|
+
Dynamic
|
|
176
|
+
</span>
|
|
177
|
+
</button>
|
|
178
|
+
</HstTooltip>
|
|
179
|
+
<HstTooltip
|
|
180
|
+
:content="!staticSourceCode ? 'Static source code is not available' : displayedSource !== 'static' ? 'Switch to static source' : null"
|
|
184
181
|
>
|
|
185
|
-
<
|
|
186
|
-
|
|
187
|
-
class="
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
'opacity-0': displayedSource !== 'static',
|
|
193
|
-
}"
|
|
182
|
+
<button
|
|
183
|
+
class="flex items-center gap-1 h-full px-1 bg-gray-500/10 rounded-r transition-all ease-[cubic-bezier(0,1,.6,1)] duration-300 overflow-hidden"
|
|
184
|
+
:class="[
|
|
185
|
+
displayedSource !== 'static' ? 'max-w-6 opacity-70' : 'max-w-[63px] text-primary-800 dark:text-primary-400',
|
|
186
|
+
staticSourceCode ? 'cursor-pointer hover:bg-gray-500/30 active:bg-gray-600/50' : displayedSource !== 'static' && 'opacity-50',
|
|
187
|
+
]"
|
|
188
|
+
@click="staticSourceCode && (displayedSource = 'static')"
|
|
194
189
|
>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
190
|
+
<Icon
|
|
191
|
+
icon="carbon:document"
|
|
192
|
+
class="w-4 h-4 flex-none"
|
|
193
|
+
/>
|
|
194
|
+
<span
|
|
195
|
+
class="transition-opacity duration-300"
|
|
196
|
+
:class="{
|
|
197
|
+
'opacity-0': displayedSource !== 'static',
|
|
198
|
+
}"
|
|
199
|
+
>
|
|
200
|
+
Static
|
|
201
|
+
</span>
|
|
202
|
+
</button>
|
|
203
|
+
</HstTooltip>
|
|
198
204
|
</div>
|
|
199
205
|
|
|
200
206
|
<HstCopyIcon
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import type { Ref } from 'vue'
|
|
3
3
|
import type { Variant } from '../../types'
|
|
4
4
|
import { Icon } from '@iconify/vue'
|
|
5
|
+
import { HstTooltip } from '@poveste/controls'
|
|
5
6
|
import { useEventListener } from '@vueuse/core'
|
|
6
|
-
import { VTooltip as vTooltip } from 'floating-vue'
|
|
7
7
|
import { computed, onUnmounted, ref } from 'vue'
|
|
8
8
|
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
9
9
|
import CheckerboardPattern from '../misc/CheckerboardPattern.vue'
|
|
@@ -201,9 +201,18 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
|
|
|
201
201
|
preview would otherwise be shown against the bare box below the
|
|
202
202
|
first screenful. The checkerboard is measured against this for the
|
|
203
203
|
same reason — but the draggers are not, since they belong to the
|
|
204
|
-
visible box rather than to the story's full height.
|
|
204
|
+
visible box rather than to the story's full height.
|
|
205
|
+
`flex`, and `flex-1` rather than `h-full` below, because that is the
|
|
206
|
+
half `min-h-full` costs: a percentage height resolves against a
|
|
207
|
+
parent's *specified* height, and this one's is `auto`. So `h-full`
|
|
208
|
+
collapsed all the way down to the iframe, which then fell back to
|
|
209
|
+
its own default of 150px and clipped every story taller than that
|
|
210
|
+
(#949). A flex child reads the used height instead, which
|
|
211
|
+
`min-height` does give it — and with `min-height: auto` it still
|
|
212
|
+
refuses to shrink below its content, so a tall story pushes this box
|
|
213
|
+
taller exactly as it did. -->
|
|
205
214
|
<div
|
|
206
|
-
class="rounded-lg min-h-full relative"
|
|
215
|
+
class="rounded-lg min-h-full relative flex flex-col"
|
|
207
216
|
:class="responsive ? 'bind-preview-bg' : ''"
|
|
208
217
|
:data-testid="responsive ? 'responsive-preview-bg' : undefined"
|
|
209
218
|
>
|
|
@@ -212,10 +221,17 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
|
|
|
212
221
|
class="absolute inset-0 w-full h-full text-gray-500/20"
|
|
213
222
|
/>
|
|
214
223
|
<div
|
|
215
|
-
class="
|
|
224
|
+
class="flex-1 relative flex flex-col"
|
|
216
225
|
:class="responsive ? 'p-8' : ''"
|
|
217
226
|
>
|
|
218
|
-
|
|
227
|
+
<!-- `grid`, so the one in-flow child stretches to this box without
|
|
228
|
+
asking for a percentage of it. `h-full` here read a height that
|
|
229
|
+
is decided by flex, which Chrome treats as indefinite for
|
|
230
|
+
percentage resolution — the same wall one level up. Stretching
|
|
231
|
+
is not shrinking: the child keeps its `min-height: auto`, so an
|
|
232
|
+
inline story taller than the preview still grows this and the
|
|
233
|
+
box above it (#258). -->
|
|
234
|
+
<div class="w-full flex-1 relative grid">
|
|
219
235
|
<div class="absolute inset-0" />
|
|
220
236
|
|
|
221
237
|
<slot
|
|
@@ -243,31 +259,43 @@ const sizeTooltip = computed(() => `${responsiveWidth.value ?? 'Auto'} × ${resp
|
|
|
243
259
|
|
|
244
260
|
<!-- Resize Dragger -->
|
|
245
261
|
<template v-if="isResponsiveEnabled">
|
|
246
|
-
<
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class="absolute w-4 top-0 bottom-4 right-0 hover:bg-primary-500/30 flex items-center justify-center cursor-ew-resize group hover:text-primary-500"
|
|
262
|
+
<HstTooltip
|
|
263
|
+
:content="sizeTooltip"
|
|
264
|
+
side="right"
|
|
250
265
|
>
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
class="w-4
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
266
|
+
<div
|
|
267
|
+
ref="horizontalDragger"
|
|
268
|
+
class="absolute w-4 top-0 bottom-4 right-0 hover:bg-primary-500/30 flex items-center justify-center cursor-ew-resize group hover:text-primary-500"
|
|
269
|
+
>
|
|
270
|
+
<Icon
|
|
271
|
+
icon="mdi:drag-vertical-variant"
|
|
272
|
+
class="w-4 h-4 opacity-20 group-hover:opacity-90"
|
|
273
|
+
/>
|
|
274
|
+
</div>
|
|
275
|
+
</HstTooltip>
|
|
276
|
+
<HstTooltip
|
|
277
|
+
:content="sizeTooltip"
|
|
278
|
+
side="bottom"
|
|
260
279
|
>
|
|
261
|
-
<
|
|
262
|
-
|
|
263
|
-
class="
|
|
280
|
+
<div
|
|
281
|
+
ref="verticalDragger"
|
|
282
|
+
class="absolute h-4 left-0 right-4 bottom-0 hover:bg-primary-500/30 flex items-center justify-center cursor-ns-resize group hover:text-primary-500"
|
|
283
|
+
>
|
|
284
|
+
<Icon
|
|
285
|
+
icon="mdi:drag-horizontal-variant"
|
|
286
|
+
class="w-4 h-4 opacity-20 group-hover:opacity-90"
|
|
287
|
+
/>
|
|
288
|
+
</div>
|
|
289
|
+
</HstTooltip>
|
|
290
|
+
<HstTooltip
|
|
291
|
+
:content="sizeTooltip"
|
|
292
|
+
side="bottom"
|
|
293
|
+
>
|
|
294
|
+
<div
|
|
295
|
+
ref="cornerDragger"
|
|
296
|
+
class="absolute w-4 h-4 right-0 bottom-0 hover:bg-primary-500/30 flex items-center justify-center cursor-nwse-resize group hover:text-primary-500"
|
|
264
297
|
/>
|
|
265
|
-
</
|
|
266
|
-
<div
|
|
267
|
-
ref="cornerDragger"
|
|
268
|
-
v-tooltip.bottom="sizeTooltip"
|
|
269
|
-
class="absolute w-4 h-4 right-0 bottom-0 hover:bg-primary-500/30 flex items-center justify-center cursor-nwse-resize group hover:text-primary-500"
|
|
270
|
-
/>
|
|
298
|
+
</HstTooltip>
|
|
271
299
|
</template>
|
|
272
300
|
</div>
|
|
273
301
|
</div>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { PropType } from 'vue'
|
|
3
3
|
import type { Story, Variant } from '../../types'
|
|
4
4
|
import { Icon } from '@iconify/vue'
|
|
5
|
-
import { HstCopyIcon } from '@poveste/controls'
|
|
5
|
+
import { HstCopyIcon, HstTooltip } from '@poveste/controls'
|
|
6
6
|
import { useResizeObserver } from '@vueuse/core'
|
|
7
7
|
import { computed, nextTick, ref, toRefs, watch } from 'vue'
|
|
8
8
|
import { useRouter } from 'vue-router'
|
|
@@ -111,25 +111,26 @@ const useIframe = computed(() => {
|
|
|
111
111
|
>
|
|
112
112
|
<!-- Header -->
|
|
113
113
|
<div class="flex-none flex items-center">
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
:class="{
|
|
119
|
-
'hover:bg-gray-200 text-gray-500 dark:hover:bg-gray-800': !isActive,
|
|
120
|
-
'bg-primary-200 hover:bg-primary-300 text-primary-800 dark:bg-primary-700 dark:hover:bg-primary-800 dark:text-primary-200': isActive,
|
|
121
|
-
}"
|
|
122
|
-
>
|
|
123
|
-
<Icon
|
|
124
|
-
:icon="variant.icon ?? 'carbon:cube'"
|
|
125
|
-
class="w-4 h-4 opacity-50"
|
|
114
|
+
<HstTooltip :content="variant.title">
|
|
115
|
+
<RouterLink
|
|
116
|
+
:to="targetRoute"
|
|
117
|
+
class="rounded w-max px-2 py-0.5 min-w-16 cursor-pointer flex items-center gap-1 flex-shrink"
|
|
126
118
|
:class="{
|
|
127
|
-
'text-gray-500': !isActive
|
|
128
|
-
'
|
|
119
|
+
'hover:bg-gray-200 text-gray-500 dark:hover:bg-gray-800': !isActive,
|
|
120
|
+
'bg-primary-200 hover:bg-primary-300 text-primary-800 dark:bg-primary-700 dark:hover:bg-primary-800 dark:text-primary-200': isActive,
|
|
129
121
|
}"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
122
|
+
>
|
|
123
|
+
<Icon
|
|
124
|
+
:icon="variant.icon ?? 'carbon:cube'"
|
|
125
|
+
class="w-4 h-4 opacity-50"
|
|
126
|
+
:class="{
|
|
127
|
+
'text-gray-500': !isActive && !variant.iconColor,
|
|
128
|
+
'bind-icon-color': !isActive && variant.iconColor,
|
|
129
|
+
}"
|
|
130
|
+
/>
|
|
131
|
+
<span class="truncate flex-1">{{ variant.title }}</span>
|
|
132
|
+
</RouterLink>
|
|
133
|
+
</HstTooltip>
|
|
133
134
|
|
|
134
135
|
<!-- Toolbar -->
|
|
135
136
|
<div class="flex-none ml-auto hidden group-hover:flex group-focus-within:flex items-center">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { Icon } from '@iconify/vue'
|
|
3
|
+
import { HstTooltip } from '@poveste/controls'
|
|
3
4
|
import { openInEditor } from '../../util/open-in-editor.js'
|
|
4
5
|
import TopBarChipItem from '../app/TopBarChipItem.vue'
|
|
5
6
|
|
|
@@ -10,16 +11,17 @@ defineProps<{
|
|
|
10
11
|
</script>
|
|
11
12
|
|
|
12
13
|
<template>
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
<HstTooltip :content="tooltip">
|
|
15
|
+
<TopBarChipItem
|
|
16
|
+
aria-label="Open story in editor"
|
|
17
|
+
target="_blank"
|
|
18
|
+
class="poveste-toolbar-open-in-editor"
|
|
19
|
+
@click="openInEditor(file)"
|
|
20
|
+
>
|
|
21
|
+
<Icon
|
|
22
|
+
icon="carbon:script-reference"
|
|
23
|
+
class="w-4 h-4"
|
|
24
|
+
/>
|
|
25
|
+
</TopBarChipItem>
|
|
26
|
+
</HstTooltip>
|
|
25
27
|
</template>
|
|
@@ -4,6 +4,7 @@ import { Icon } from '@iconify/vue'
|
|
|
4
4
|
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
5
5
|
import { povesteConfig } from '../../util/config'
|
|
6
6
|
import BaseCheckbox from '../base/BaseCheckbox.vue'
|
|
7
|
+
import BaseDropdown from '../base/BaseDropdown.vue'
|
|
7
8
|
|
|
8
9
|
const previewSettings = usePreviewSettingsStore()
|
|
9
10
|
const settings = previewSettings.currentSettings
|
|
@@ -21,32 +22,30 @@ const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets?.lengt
|
|
|
21
22
|
</script>
|
|
22
23
|
|
|
23
24
|
<template>
|
|
24
|
-
<
|
|
25
|
+
<BaseDropdown
|
|
25
26
|
v-if="showDropdown"
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
side="bottom"
|
|
28
|
+
align="end"
|
|
29
|
+
:align-offset="6"
|
|
30
|
+
tooltip="Preview appearance"
|
|
28
31
|
class="poveste-toolbar-background flex-none"
|
|
29
32
|
data-testid="toolbar-background"
|
|
30
33
|
>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class="w-3 h-3 opacity-40 group-hover:opacity-70"
|
|
45
|
-
/>
|
|
46
|
-
</div>
|
|
47
|
-
</template>
|
|
34
|
+
<button
|
|
35
|
+
class="flex items-center gap-1 px-2.5 py-1.5 hover:bg-white/50 dark:hover:bg-white/10 hover:text-primary-500 dark:hover:text-primary-400 cursor-pointer text-gray-900 dark:text-gray-100 transition-colors group"
|
|
36
|
+
aria-label="Preview appearance"
|
|
37
|
+
>
|
|
38
|
+
<Icon
|
|
39
|
+
icon="carbon:color-palette"
|
|
40
|
+
class="w-4 h-4"
|
|
41
|
+
/>
|
|
42
|
+
<Icon
|
|
43
|
+
icon="carbon:chevron-down"
|
|
44
|
+
class="w-3 h-3 opacity-40 group-hover:opacity-70"
|
|
45
|
+
/>
|
|
46
|
+
</button>
|
|
48
47
|
|
|
49
|
-
<template #popper="{
|
|
48
|
+
<template #popper="{ close }">
|
|
50
49
|
<div
|
|
51
50
|
class="flex flex-col items-stretch"
|
|
52
51
|
data-testid="background-popper"
|
|
@@ -89,7 +88,7 @@ const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets?.lengt
|
|
|
89
88
|
? 'bg-primary-500 hover:bg-primary-600 text-white dark:text-black'
|
|
90
89
|
: 'bg-transparent hover:bg-primary-100 dark:hover:bg-primary-700',
|
|
91
90
|
]"
|
|
92
|
-
@click="previewSettings.setBackgroundColor(option.color);
|
|
91
|
+
@click="previewSettings.setBackgroundColor(option.color);close()"
|
|
93
92
|
>
|
|
94
93
|
<span class="mr-auto">{{ option.label }}</span>
|
|
95
94
|
<template v-if="option.color !== '$checkerboard'">
|
|
@@ -107,5 +106,5 @@ const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets?.lengt
|
|
|
107
106
|
</button>
|
|
108
107
|
</div>
|
|
109
108
|
</template>
|
|
110
|
-
</
|
|
109
|
+
</BaseDropdown>
|
|
111
110
|
</template>
|