Skip to content

Commit

Permalink
feat: add useAreaData() composable (refs SFKUI-6992)
Browse files Browse the repository at this point in the history
  • Loading branch information
ext committed Feb 24, 2025
1 parent bb2d41b commit a20b872
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
63 changes: 63 additions & 0 deletions docs/functions/functions/use-area-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
title: useAreaData() composable
short-title: useAreaData()
name: useAreaData
layout: article
---

Composable för att hämta information om den {@link FPageLayout layout yta} ett element befinner sig i:

- Ytans namn.
- Om paneler ska anslutas till höger eller vänster.
- Vilken riktning innehållet i ytan ska flöda.

## Syntax

```ts nocompile nolint
function useAreaData(element);
```

### Parametrar

`element: HTMLElement`
: Elementet förfrågning om yta ska göras för.

### Returvärde

`area: string`
: Ytans namn.

`attachPanel: "none" | "left" "right"`
: Om paneler ska anslutas till höger eller vänster inom ytan.

`direction: "column" | "row"`
: Vilken riktning innehållet i ytan ska flöda.

## Exempel

Sätter en klass baserat på hur panelen ska fästas:

```ts
import { computed, useTemplateRef } from "vue";
import { useAreaData } from "@fkui/vue";

/* --- cut above -- */

const element = useTemplateRef("my-root-element");
const { attachPanel } = useAreaData(element);

const attachClass = computed(() => {
switch (attachPanel.value) {
case "left":
return "attach-left";
case "right":
return "attach-right";
}
return undefined;
});
```

## Related

- {@link FPageLayout}
- {@link custom-page-layout Egen layout till applikationsmall}
1 change: 1 addition & 0 deletions etc/docs-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ functions/functions/mount-component.html
functions/functions/render-slot-text.html
functions/functions/table-scroll-classes.html
functions/functions/table-scroll.html
functions/functions/use-area-data.html
functions/functions/use-modal.html
functions/helpers/accessibility.html
functions/helpers/densify.html
Expand Down
10 changes: 10 additions & 0 deletions etc/vue.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15648,6 +15648,16 @@ export const UNHANDLED_ERROR_EVENT: "unhandled-error";
// @public (undocumented)
export type UnknownItem = Record<string, unknown>;

// @public (undocumented)
export interface UseAreaData {
readonly area: Readonly<Ref<string | null>>;
readonly attachPanel: Readonly<Ref<LayoutAreaAttachPanel | null>>;
readonly direction: Readonly<Ref<LayoutAreaDirection | null>>;
}

// @public
export function useAreaData(element: Readonly<ShallowRef<HTMLElement | null>>): UseAreaData;

// @public (undocumented)
export function useCombobox(inputRef: Readonly<ShallowRef<HTMLInputElement | null>>, options: Ref<string[] | undefined>, onOptionSelected?: (value: string) => void): {
dropdownId: string;
Expand Down
1 change: 1 addition & 0 deletions packages/vue/src/components/FPageLayout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export {
registerLayout,
} from "./define-layout";
export { default as FPageLayout } from "./FPageLayout.vue";
export { type UseAreaData, useAreaData } from "./use-area-data";
56 changes: 56 additions & 0 deletions packages/vue/src/components/FPageLayout/use-area-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { type Ref, ref, type ShallowRef, watchEffect } from "vue";
import { LayoutAreaAttachPanel, LayoutAreaDirection } from "./define-layout";
import {
VAR_NAME_AREA,
VAR_NAME_ATTACH_PANEL,
VAR_NAME_DIRECTION,
} from "./constants";

/**
* @public
*/
export interface UseAreaData {
/** Name of layout area */
readonly area: Readonly<Ref<string | null>>;
/** Panel attachment */
readonly attachPanel: Readonly<Ref<LayoutAreaAttachPanel | null>>;
/** Direction area content flows */
readonly direction: Readonly<Ref<LayoutAreaDirection | null>>;
}

function getProperty<T>(style: CSSStyleDeclaration, key: string): T | null {
const value = style.getPropertyValue(key);
if (value === "") {
return null;
} else {
return JSON.parse(value);
}
}

/**
* Fetch information about the layout area given element belongs to.
*
* @public
*/
export function useAreaData(
element: Readonly<ShallowRef<HTMLElement | null | undefined>>,
): UseAreaData {
const area = ref<string | null>(null);
const attachPanel = ref<LayoutAreaAttachPanel | null>(null);
const direction = ref<LayoutAreaDirection | null>(null);

watchEffect(() => {
if (element.value) {
const style = getComputedStyle(element.value);
area.value = getProperty(style, VAR_NAME_AREA);
attachPanel.value = getProperty(style, VAR_NAME_ATTACH_PANEL);
direction.value = getProperty(style, VAR_NAME_DIRECTION);
}
});

return {
area,
attachPanel,
direction,
};
}
2 changes: 2 additions & 0 deletions packages/vue/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ export {
type LayoutAreaAttachPanel,
type LayoutAreaDefinition,
type LayoutAreaDirection,
type UseAreaData,
FPageLayout,
registerLayout,
useAreaData,
} from "./FPageLayout";
export { FProgressbar } from "./FProgressbar";
export { FRadioField } from "./FRadioField";
Expand Down

0 comments on commit a20b872

Please sign in to comment.