Skip to content

Commit

Permalink
UNFIN
Browse files Browse the repository at this point in the history
  • Loading branch information
ext committed Jan 28, 2025
1 parent 6223273 commit 451d100
Show file tree
Hide file tree
Showing 10 changed files with 327 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/guides/custom-page-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ registerLayout({
content: {
attachPanel: "none",
direction: "column",
scroll: true,
},
footer: {
attachPanel: "none",
Expand All @@ -39,6 +40,7 @@ där:

- `attachPanel` talar om hur en panel ska fästas. Om ytan inte kan ta paneler sätter man `"none"`.
- `direction` talar om ifall ytan flödar horisontellt eller vertikalt.
- `scroll` talar om ifall ytan ska scrolla (i den riktning som `direction` talar om).

Styling använder [CSS grid](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/CSS_layout/Grids)`::part(grid name)` och kan se ut så här:

Expand Down
141 changes: 141 additions & 0 deletions packages/vue/src/components/FPageClosablePanel/FPageClosablePanel.vue
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";

Check failure on line 8 in packages/vue/src/components/FPageClosablePanel/FPageClosablePanel.vue

View workflow job for this annotation

GitHub Actions / Lint

'ref' is defined but never used
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" });

Check failure on line 42 in packages/vue/src/components/FPageClosablePanel/FPageClosablePanel.vue

View workflow job for this annotation

GitHub Actions / Lint

Forbidden non-null assertion
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>
1 change: 1 addition & 0 deletions packages/vue/src/components/FPageClosablePanel/index.ts
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 packages/vue/src/components/FPageClosablePanel/use-panel.ts
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();
}
},
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<script lang="ts">
export default defineComponent({
name: "FPageExpandablePanel",
});
</script>

<script setup lang="ts">
import { computed, ref, useTemplateRef } from "vue";
import { computed, defineComponent, ref, useTemplateRef } from "vue";
import { FIcon } from "../FIcon";
import { useAreaData } from "../FPageLayout/use-area-data";
import { usePageWidth } from "../../composables";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<script lang="ts">
export default defineComponent({
name: "FPageMenuPanel",
});
</script>

<script setup lang="ts">
import { computed, ref, useTemplateRef } from "vue";
import { computed, defineComponent, ref, useTemplateRef } from "vue";
import { FIcon } from "../FIcon";
import { useAreaData } from "../FPageLayout/use-area-data";
import { usePageWidth } from "../../composables";
Expand Down
1 change: 1 addition & 0 deletions packages/vue/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export { FExpandableParagraph } from "./FExpandableParagraph";
export { FFieldset } from "./FFieldset";
export { type FFileItemIconName, FFileItem } from "./FFileItem";
export * from "./FFileSelector";
export { FPageClosablePanel } from "./FPageClosablePanel";
export { FPageExpandablePanel } from "./FPageExpandablePanel";
export {
type LayoutDefinition,
Expand Down
3 changes: 3 additions & 0 deletions packages/vue/src/vite-dev/ankeborgare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface Ankeborgare {
namn: string;
}
Loading

0 comments on commit 451d100

Please sign in to comment.