-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Expand file tree
/
Copy pathuseLink.ts
More file actions
79 lines (67 loc) · 2.47 KB
/
useLink.ts
File metadata and controls
79 lines (67 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'use client';
import * as React from 'react';
import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities';
import { useBackgroundAppearance } from '@fluentui/react-shared-contexts';
import { useLinkState_unstable } from './useLinkState';
import type { LinkBaseProps, LinkBaseState, LinkProps, LinkState } from './Link.types';
import { useLinkContext } from '../../contexts/linkContext';
/**
* Given user props, defines default props for the Link, calls useLinkState_unstable, and returns processed state.
* @param props - User provided props to the Link component.
* @param ref - User provided ref to be passed to the Link component.
*/
export const useLink_unstable = (
props: LinkProps,
ref: React.Ref<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>,
): LinkState => {
const backgroundAppearance = useBackgroundAppearance();
const { appearance = 'default', ...baseProps } = props;
const state = useLinkBase_unstable(baseProps, ref);
return {
appearance,
backgroundAppearance,
...state,
};
};
/**
* Base hook for Link component, which manages state related to ARIA, keyboard handling,
* disabled behavior, and slot structure. This hook excludes design-specific props (appearance).
*
* @param props - User provided props to the Link component.
* @param ref - User provided ref to be passed to the Link component.
*/
export const useLinkBase_unstable = (
props: LinkBaseProps,
ref: React.Ref<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>,
): LinkBaseState => {
const { inline: inlineContext } = useLinkContext();
const { bold = false, disabled = false, disabledFocusable = false, inline = false } = props;
const elementType = props.as || (props.href ? 'a' : 'button');
// Casting is required here as `as` prop would break the union between `a`, `button` and `span` types
const propsWithAssignedAs = {
role: elementType === 'span' ? 'button' : undefined,
type: elementType === 'button' ? 'button' : undefined,
...props,
as: elementType,
} as LinkBaseProps;
const state: LinkBaseState = {
// Props passed at the top-level
bold,
disabled,
disabledFocusable,
inline: inline ?? !!inlineContext,
// Slots definition
components: {
root: elementType,
},
root: slot.always(
getIntrinsicElementProps<LinkBaseProps>(elementType, {
ref,
...propsWithAssignedAs,
} as const),
{ elementType },
),
};
useLinkState_unstable(state);
return state;
};