-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new
FPageExpandablePanel
(refs SFKUI-6500)
- Loading branch information
Showing
18 changed files
with
865 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,87 @@ | ||
<script setup lang="ts"> | ||
import { FPageExpandablePanel, FPageLayout } from "@fkui/vue"; | ||
</script> | ||
|
||
<template> | ||
<router-view /> | ||
<f-page-layout layout="three-column"> | ||
<template #header> [header] </template> | ||
<template #left> | ||
<f-page-expandable-panel> | ||
<template #header> [panel header] </template> | ||
<template #default> | ||
<p>[panel content]</p> | ||
<p>[panel content]</p> | ||
<p>[panel content]</p> | ||
</template> | ||
<template #footer> [panel footer] </template> | ||
</f-page-expandable-panel> | ||
</template> | ||
<template #right> | ||
<f-page-expandable-panel> | ||
<template #header> [panel header] </template> | ||
<template #default> | ||
<p>[panel content]</p> | ||
<p>[panel content]</p> | ||
<p>[panel content]</p> | ||
</template> | ||
<template #footer> [panel footer] </template> | ||
</f-page-expandable-panel> | ||
</template> | ||
<template #content> | ||
<!-- [html-validate-disable-next no-inline-style -- for testing only]--> | ||
<div style="padding: 0.5rem"> | ||
<h1>Lorem ipsum dolor sit amet</h1> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dictum mauris non urna faucibus | ||
porta. Aenean euismod rutrum finibus. Morbi ultricies, augue ut volutpat dictum, nisi quam consequat | ||
mauris, lacinia aliquam lacus ante et arcu. In non justo dui. Ut dui leo, commodo ut odio at, | ||
ultrices imperdiet enim. Fusce dolor lacus, gravida eget dui sed, dictum elementum magna. Quisque | ||
blandit egestas ultricies. Cras ultricies eget eros ultrices blandit. Interdum et malesuada fames ac | ||
ante ipsum primis in faucibus. Praesent in justo ultrices nunc efficitur mattis at vel lorem. | ||
Maecenas rhoncus felis tincidunt dui faucibus, nec rhoncus tellus mollis. Phasellus vitae magna | ||
turpis. Etiam in mattis mi. Duis at justo finibus, tristique lacus nec, lobortis dui. | ||
</p> | ||
<p> | ||
Ut placerat consectetur pretium. Proin luctus neque vitae consequat pellentesque. Aliquam arcu arcu, | ||
auctor ac ipsum aliquet, bibendum pretium est. Integer sit amet mattis dolor, quis volutpat justo. | ||
Curabitur eu tempus nibh. Aliquam erat volutpat. Phasellus tincidunt suscipit nulla a viverra. Cras | ||
nec felis ut dolor malesuada congue vitae a neque. | ||
</p> | ||
<p> | ||
Vivamus tortor quam, dignissim at aliquet ut, tristique id orci. Nulla fringilla nulla est, quis | ||
tempor risus fermentum non. Ut id ullamcorper tellus. Donec lacinia condimentum neque, eget varius | ||
mi convallis vitae. Nullam ante turpis, egestas ac nibh ut, pretium rutrum metus. Aenean non tellus | ||
nulla. Duis ornare tempor tristique. Etiam tempus nec nisl quis varius. Pellentesque lacinia a | ||
sapien quis ultricies. | ||
</p> | ||
<p> | ||
Donec ut egestas dui. Donec purus nulla, aliquam sed auctor vitae, porta non quam. Nam eros arcu, | ||
tempus a nisi ac, scelerisque cursus diam. Mauris sodales magna at diam semper efficitur. Ut | ||
hendrerit urna vitae massa bibendum pretium. Proin bibendum tortor in nulla maximus, eget laoreet | ||
ipsum ornare. Mauris rutrum massa vel enim imperdiet consequat. Phasellus convallis nunc est, vel | ||
tristique mi sollicitudin sit amet. Aliquam auctor id metus nec interdum. Nam eget sem sed nunc | ||
egestas pretium. | ||
</p> | ||
<p> | ||
Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce vitae quam sapien. Etiam gravida | ||
accumsan enim. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus | ||
mus. In lobortis lobortis pharetra. Curabitur diam sem, posuere nec iaculis vel, convallis sed | ||
augue. Etiam vel urna id lectus lacinia volutpat. Phasellus nec bibendum ex. Nullam magna nibh, | ||
ultrices sit amet felis fringilla, iaculis ultricies justo. Nulla viverra aliquet turpis, quis | ||
hendrerit sapien elementum at. Nunc bibendum in nisl sed blandit. Integer tincidunt augue nec arcu | ||
lacinia tristique. Aenean id mauris venenatis, blandit ligula a, consequat ante. Fusce aliquam mi | ||
sed rutrum posuere. Morbi congue lorem est, elementum suscipit mi ullamcorper vitae. Quisque non | ||
iaculis leo. | ||
</p> | ||
</div> | ||
</template> | ||
<template #footer> [footer] </template> | ||
</f-page-layout> | ||
</template> | ||
|
||
<style> | ||
body { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
@use "@fkui/theme-default"; | ||
@use "@fkui/design"; | ||
@use "@fkui/design/lib/fonts.css"; | ||
@use "@fkui/vue/style.css"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
packages/vue/src/components/FPageClosablePanel/FPageClosablePanel.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<script lang="ts"> | ||
export default defineComponent({ | ||
name: "FPageClosablePanel", | ||
}); | ||
</script> | ||
|
||
<script setup lang="ts" generic="T"> | ||
import { computed, defineComponent, onUnmounted, ref, useTemplateRef } from "vue"; | ||
import { FIcon } from "../FIcon"; | ||
import { useAreaData } from "../FPageLayout/use-area-data"; | ||
import { createClosablePanel } from "./use-panel"; | ||
const root = useTemplateRef("root"); | ||
const { attach } = useAreaData(root); | ||
const props = defineProps<{ | ||
name: string; | ||
}>(); | ||
const panel = createClosablePanel<T>(props.name); | ||
const attachClass = computed(() => { | ||
switch (attach.value) { | ||
case "left": | ||
return "attach-left"; | ||
case "right": | ||
return "attach-right"; | ||
} | ||
return undefined; | ||
}); | ||
onUnmounted(() => { | ||
panel.destroy(); | ||
}); | ||
function onToggle(): void { | ||
panel.close(); | ||
} | ||
function onClose(reason?: string): void { | ||
if (panel.callback.value) { | ||
panel.callback.value({ item: panel.item.value!, reason: reason ?? "close" }); | ||
panel.close(); | ||
} | ||
} | ||
</script> | ||
|
||
<template> | ||
<div v-if="panel.item.value" ref="root" class="panel__wrapper"> | ||
<div class="panel panel--closable" :class="[attachClass]"> | ||
<div class="panel__header"> | ||
<div class="panel__title"> | ||
<slot name="header" v-bind="{ item: panel.item.value, close: onClose }"></slot> | ||
</div> | ||
<div class="panel__collapse"> | ||
<button type="button" @click="onToggle()"> | ||
<f-icon name="close"> <title>Stäng</title> </f-icon> | ||
</button> | ||
</div> | ||
</div> | ||
<div class="panel__content"> | ||
<slot name="default" v-bind="{ item: panel.item.value, close: onClose }"></slot> | ||
</div> | ||
<div class="panel__footer"> | ||
<slot name="footer"></slot> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.panel__wrapper { | ||
flex-grow: 1; | ||
display: flex; | ||
} | ||
.panel { | ||
flex-grow: 1; | ||
background: lightskyblue; | ||
display: flex; | ||
flex-direction: column; | ||
padding: 0.5rem; | ||
gap: 0.5rem; | ||
min-width: 25ch; | ||
@media (width < 640px) { | ||
position: absolute; | ||
top: 0; | ||
bottom: 0; | ||
z-index: 1; | ||
&.attach-left { | ||
left: 0; | ||
} | ||
&.attach-right { | ||
right: 0; | ||
} | ||
} | ||
} | ||
.panel__header { | ||
flex: 0 0 auto; | ||
display: flex; | ||
gap: 0.5rem; | ||
align-items: center; | ||
justify-content: center; | ||
.attach-left & { | ||
flex-direction: row; | ||
} | ||
.attach-right & { | ||
flex-direction: row-reverse; | ||
} | ||
} | ||
.panel__title { | ||
flex: 1 0 auto; | ||
font-weight: 600; | ||
font-size: 1.2em; | ||
} | ||
.panel__content { | ||
flex: 1 0 auto; | ||
} | ||
.panel__footer { | ||
flex: 0 0 auto; | ||
} | ||
button { | ||
appearance: none; | ||
padding: 0; | ||
line-height: 1; | ||
background: transparent; | ||
border: 0; | ||
cursor: pointer; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as FPageClosablePanel } from "./FPageClosablePanel.vue"; |
57 changes: 57 additions & 0 deletions
57
packages/vue/src/components/FPageClosablePanel/use-panel.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { type Ref, ref } from "vue"; | ||
|
||
type PanelCallback<T> = (data: { item: T; reason: string }) => void; | ||
|
||
interface ClosablePanelControl<T> { | ||
readonly name: Readonly<Ref<string>>; | ||
item: Ref<T | null>; | ||
callback: Ref<PanelCallback<T> | null>; | ||
open(item: T, options?: { onClose?: PanelCallback<T> }): void; | ||
close(): void; | ||
destroy(): void; | ||
} | ||
|
||
interface ClosablePanel<T = unknown> { | ||
open(item: T, options?: { onClose?: PanelCallback<T> }): void; | ||
close(): void; | ||
} | ||
|
||
const panels: Array<ClosablePanelControl<unknown>> = []; | ||
|
||
export function createClosablePanel<T>(name: string): ClosablePanelControl<T> { | ||
const control: ClosablePanelControl<unknown> = { | ||
name: ref(name), | ||
item: ref(null), | ||
callback: ref(null), | ||
open(item, options) { | ||
this.item.value = item; | ||
this.callback.value = options?.onClose ?? null; | ||
}, | ||
close() { | ||
this.item.value = null; | ||
this.callback.value = null; | ||
}, | ||
destroy() { | ||
/* do nothing */ | ||
}, | ||
}; | ||
panels.push(control); | ||
return control as ClosablePanelControl<T>; | ||
} | ||
|
||
export function usePanel<T = unknown>(name: string): ClosablePanel<T> { | ||
return { | ||
open(item, options) { | ||
const panel = panels.find((it) => it.name.value === name); | ||
if (panel) { | ||
panel.open(item, options); | ||
} | ||
}, | ||
close() { | ||
const panel = panels.find((it) => it.name.value === name); | ||
if (panel) { | ||
panel.close(); | ||
} | ||
}, | ||
}; | ||
} |
Oops, something went wrong.