first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,8 @@
import * as React from 'react';
import type { IRenderComponent } from '../../Utilities';
import type { IKeytipDataProps } from './KeytipData.types';
/**
* A small element to help the target component correctly read out its aria-describedby for its Keytip
* {@docCategory Keytips}
*/
export declare const KeytipData: React.FunctionComponent<IKeytipDataProps & IRenderComponent<{}>>;
+18
View File
@@ -0,0 +1,18 @@
import { __rest } from "tslib";
import { DATAKTP_TARGET, DATAKTP_EXECUTE_TARGET } from '../../utilities/keytips/index';
import { useKeytipData } from './useKeytipData';
/**
* A small element to help the target component correctly read out its aria-describedby for its Keytip
* {@docCategory Keytips}
*/
export var KeytipData = function (props) {
var _a;
var children = props.children, keytipDataProps = __rest(props, ["children"]);
var _b = useKeytipData(keytipDataProps), keytipId = _b.keytipId, ariaDescribedBy = _b.ariaDescribedBy;
return children((_a = {},
_a[DATAKTP_TARGET] = keytipId,
_a[DATAKTP_EXECUTE_TARGET] = keytipId,
_a['aria-describedby'] = ariaDescribedBy,
_a));
};
//# sourceMappingURL=KeytipData.js.map
@@ -0,0 +1 @@
{"version":3,"file":"KeytipData.js","sourceRoot":"../src/","sources":["components/KeytipData/KeytipData.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD;;;GAGG;AACH,MAAM,CAAC,IAAM,UAAU,GAAqE,UAAA,KAAK;;IACvF,IAAA,QAAQ,GAAyB,KAAK,SAA9B,EAAK,eAAe,UAAK,KAAK,EAAxC,YAAgC,CAAF,CAAW;IACzC,IAAA,KAAgC,aAAa,CAAC,eAAe,CAAC,EAA5D,QAAQ,cAAA,EAAE,eAAe,qBAAmC,CAAC;IAErE,OAAO,QAAQ;QACb,GAAC,cAAc,IAAG,QAAQ;QAC1B,GAAC,sBAAsB,IAAG,QAAQ;QAClC,sBAAkB,GAAE,eAAe;YACnC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { DATAKTP_TARGET, DATAKTP_EXECUTE_TARGET } from '../../utilities/keytips/index';\nimport { useKeytipData } from './useKeytipData';\nimport type { IRenderComponent } from '../../Utilities';\nimport type { IKeytipDataProps } from './KeytipData.types';\n\n/**\n * A small element to help the target component correctly read out its aria-describedby for its Keytip\n * {@docCategory Keytips}\n */\nexport const KeytipData: React.FunctionComponent<IKeytipDataProps & IRenderComponent<{}>> = props => {\n const { children, ...keytipDataProps } = props;\n const { keytipId, ariaDescribedBy } = useKeytipData(keytipDataProps);\n\n return children({\n [DATAKTP_TARGET]: keytipId,\n [DATAKTP_EXECUTE_TARGET]: keytipId,\n 'aria-describedby': ariaDescribedBy,\n });\n};\n"]}
@@ -0,0 +1,18 @@
import type { IKeytipProps } from '../../Keytip';
export interface IKeytipDataProps {
/**
* IKeytipProps to create from this KeytipData
* If no keytipProps are defined, a keytip won't be registered
*/
keytipProps?: IKeytipProps;
/**
* String to add to the aria-describedby generated by this KeytipData
* It will prepend this string to the generated aria-describedby property
*/
ariaDescribedBy?: string;
/**
* T/F if this keytip should be disabled upon creation
*/
disabled?: boolean;
}
export type KeytipDataOptions = IKeytipDataProps;
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=KeytipData.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"KeytipData.types.js","sourceRoot":"../src/","sources":["components/KeytipData/KeytipData.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { IKeytipProps } from '../../Keytip';\n\nexport interface IKeytipDataProps {\n /**\n * IKeytipProps to create from this KeytipData\n * If no keytipProps are defined, a keytip won't be registered\n */\n keytipProps?: IKeytipProps;\n\n /**\n * String to add to the aria-describedby generated by this KeytipData\n * It will prepend this string to the generated aria-describedby property\n */\n ariaDescribedBy?: string;\n\n /**\n * T/F if this keytip should be disabled upon creation\n */\n disabled?: boolean;\n}\n\nexport type KeytipDataOptions = IKeytipDataProps;\n"]}
+3
View File
@@ -0,0 +1,3 @@
export * from './KeytipData';
export * from './KeytipData.types';
export { useKeytipRef } from './useKeytipRef';
+4
View File
@@ -0,0 +1,4 @@
export * from './KeytipData';
export * from './KeytipData.types';
export { useKeytipRef } from './useKeytipRef';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/KeytipData/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export * from './KeytipData';\nexport * from './KeytipData.types';\nexport { useKeytipRef } from './useKeytipRef';\n"]}
@@ -0,0 +1,9 @@
import type { KeytipDataOptions } from './KeytipData.types';
export interface IKeytipData {
ariaDescribedBy: string | undefined;
keytipId: string | undefined;
}
/**
* Hook that creates attributes for components which are enabled with Keytip.
*/
export declare function useKeytipData(options: KeytipDataOptions): IKeytipData;
@@ -0,0 +1,64 @@
import { __assign, __spreadArray } from "tslib";
import * as React from 'react';
import { useConst, useIsomorphicLayoutEffect, usePrevious } from '@fluentui/react-hooks';
import { mergeAriaAttributeValues } from '../../Utilities';
import { KeytipManager, mergeOverflows, sequencesToID, getAriaDescribedBy } from '../../utilities/keytips/index';
/**
* Hook that creates attributes for components which are enabled with Keytip.
*/
export function useKeytipData(options) {
var uniqueId = React.useRef(undefined);
var keytipProps = options.keytipProps
? __assign({ disabled: options.disabled }, options.keytipProps) : undefined;
var keytipManager = useConst(KeytipManager.getInstance());
var prevOptions = usePrevious(options);
// useLayoutEffect used to strictly emulate didUpdate/didMount behavior
useIsomorphicLayoutEffect(function () {
if (uniqueId.current &&
keytipProps &&
((prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.keytipProps) !== options.keytipProps || (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.disabled) !== options.disabled)) {
keytipManager.update(keytipProps, uniqueId.current);
}
});
useIsomorphicLayoutEffect(function () {
// Register Keytip in KeytipManager
if (keytipProps) {
uniqueId.current = keytipManager.register(keytipProps);
}
return function () {
// Unregister Keytip in KeytipManager
keytipProps && keytipManager.unregister(keytipProps, uniqueId.current);
};
// this is meant to run only at mount, and updates are handled separately
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
var nativeKeytipProps = {
ariaDescribedBy: options.ariaDescribedBy,
keytipId: undefined,
};
if (keytipProps) {
nativeKeytipProps = getKeytipData(keytipManager, keytipProps, options.ariaDescribedBy);
}
return nativeKeytipProps;
}
/**
* Gets the aria- and data- attributes to attach to the component
* @param keytipProps - options for Keytip
* @param describedByPrepend - ariaDescribedBy value to prepend
*/
function getKeytipData(keytipManager, keytipProps, describedByPrepend) {
// Add the parent overflow sequence if necessary
var newKeytipProps = keytipManager.addParentOverflow(keytipProps);
// Construct aria-describedby and data-ktp-id attributes
var ariaDescribedBy = mergeAriaAttributeValues(describedByPrepend, getAriaDescribedBy(newKeytipProps.keySequences));
var keySequences = __spreadArray([], newKeytipProps.keySequences, true);
if (newKeytipProps.overflowSetSequence) {
keySequences = mergeOverflows(keySequences, newKeytipProps.overflowSetSequence);
}
var keytipId = sequencesToID(keySequences);
return {
ariaDescribedBy: ariaDescribedBy,
keytipId: keytipId,
};
}
//# sourceMappingURL=useKeytipData.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
import * as React from 'react';
import type { KeytipDataOptions } from './KeytipData.types';
/**
* Hook that creates a ref which is used for passing to Keytip target element.
* The ref will handle setting the attributes needed for Keytip to work.
*/
export declare function useKeytipRef<TElement extends HTMLElement = HTMLElement>(options: KeytipDataOptions): React.Ref<TElement>;
export declare function setAttribute(element: HTMLElement | null, attributeName: string, attributeValue: string | undefined, append?: boolean): void;
+39
View File
@@ -0,0 +1,39 @@
import * as React from 'react';
import { DATAKTP_TARGET, DATAKTP_EXECUTE_TARGET, DATAKTP_ARIA_TARGET } from '../../utilities/keytips/index';
import { useKeytipData } from './useKeytipData';
/**
* Hook that creates a ref which is used for passing to Keytip target element.
* The ref will handle setting the attributes needed for Keytip to work.
*/
export function useKeytipRef(options) {
var _a = useKeytipData(options), keytipId = _a.keytipId, ariaDescribedBy = _a.ariaDescribedBy;
var contentRef = React.useCallback(function (contentElement) {
if (!contentElement) {
return;
}
var targetElement = findFirstElement(contentElement, DATAKTP_TARGET) || contentElement;
var executeElement = findFirstElement(contentElement, DATAKTP_EXECUTE_TARGET) || targetElement;
var ariaElement = findFirstElement(contentElement, DATAKTP_ARIA_TARGET) || executeElement;
setAttribute(targetElement, DATAKTP_TARGET, keytipId);
setAttribute(executeElement, DATAKTP_EXECUTE_TARGET, keytipId);
setAttribute(ariaElement, 'aria-describedby', ariaDescribedBy, true);
}, [keytipId, ariaDescribedBy]);
return contentRef;
}
export function setAttribute(element, attributeName, attributeValue, append) {
if (append === void 0) { append = false; }
if (element && attributeValue) {
var value = attributeValue;
if (append) {
var currentValue = element.getAttribute(attributeName);
if (currentValue && currentValue.indexOf(attributeValue) === -1) {
value = "".concat(currentValue, " ").concat(attributeValue);
}
}
element.setAttribute(attributeName, value);
}
}
function findFirstElement(rootElement, dataAttribute) {
return rootElement.querySelector("[".concat(dataAttribute, "]"));
}
//# sourceMappingURL=useKeytipRef.js.map
@@ -0,0 +1 @@
{"version":3,"file":"useKeytipRef.js","sourceRoot":"../src/","sources":["components/KeytipData/useKeytipRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA0B;IAEpB,IAAA,KAAgC,aAAa,CAAC,OAAO,CAAC,EAApD,QAAQ,cAAA,EAAE,eAAe,qBAA2B,CAAC;IAE7D,IAAM,UAAU,GAAwB,KAAK,CAAC,WAAW,CACvD,UAAC,cAA+B;QAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAM,aAAa,GAAG,gBAAgB,CAAC,cAAc,EAAE,cAAc,CAAC,IAAI,cAAc,CAAC;QACzF,IAAM,cAAc,GAAG,gBAAgB,CAAC,cAAc,EAAE,sBAAsB,CAAC,IAAI,aAAa,CAAC;QACjG,IAAM,WAAW,GAAG,gBAAgB,CAAC,cAAc,EAAE,mBAAmB,CAAC,IAAI,cAAc,CAAC;QAE5F,YAAY,CAAC,aAAa,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;QACtD,YAAY,CAAC,cAAc,EAAE,sBAAsB,EAAE,QAAQ,CAAC,CAAC;QAC/D,YAAY,CAAC,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC,EACD,CAAC,QAAQ,EAAE,eAAe,CAAC,CAC5B,CAAC;IAEF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAA2B,EAC3B,aAAqB,EACrB,cAAkC,EAClC,MAAuB;IAAvB,uBAAA,EAAA,cAAuB;IAEvB,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,IAAI,KAAK,GAAG,cAAc,CAAC;QAC3B,IAAI,MAAM,EAAE,CAAC;YACX,IAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;YACzD,IAAI,YAAY,IAAI,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAChE,KAAK,GAAG,UAAG,YAAY,cAAI,cAAc,CAAE,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAwB,EAAE,aAAqB;IACvE,OAAO,WAAW,CAAC,aAAa,CAAC,WAAI,aAAa,MAAG,CAAC,CAAC;AACzD,CAAC","sourcesContent":["import * as React from 'react';\nimport { DATAKTP_TARGET, DATAKTP_EXECUTE_TARGET, DATAKTP_ARIA_TARGET } from '../../utilities/keytips/index';\nimport { useKeytipData } from './useKeytipData';\nimport type { KeytipDataOptions } from './KeytipData.types';\n\n/**\n * Hook that creates a ref which is used for passing to Keytip target element.\n * The ref will handle setting the attributes needed for Keytip to work.\n */\nexport function useKeytipRef<TElement extends HTMLElement = HTMLElement>(\n options: KeytipDataOptions,\n): React.Ref<TElement> {\n const { keytipId, ariaDescribedBy } = useKeytipData(options);\n\n const contentRef: React.Ref<TElement> = React.useCallback(\n (contentElement: TElement | null): void => {\n if (!contentElement) {\n return;\n }\n\n const targetElement = findFirstElement(contentElement, DATAKTP_TARGET) || contentElement;\n const executeElement = findFirstElement(contentElement, DATAKTP_EXECUTE_TARGET) || targetElement;\n const ariaElement = findFirstElement(contentElement, DATAKTP_ARIA_TARGET) || executeElement;\n\n setAttribute(targetElement, DATAKTP_TARGET, keytipId);\n setAttribute(executeElement, DATAKTP_EXECUTE_TARGET, keytipId);\n setAttribute(ariaElement, 'aria-describedby', ariaDescribedBy, true);\n },\n [keytipId, ariaDescribedBy],\n );\n\n return contentRef;\n}\n\nexport function setAttribute(\n element: HTMLElement | null,\n attributeName: string,\n attributeValue: string | undefined,\n append: boolean = false,\n): void {\n if (element && attributeValue) {\n let value = attributeValue;\n if (append) {\n const currentValue = element.getAttribute(attributeName);\n if (currentValue && currentValue.indexOf(attributeValue) === -1) {\n value = `${currentValue} ${attributeValue}`;\n }\n }\n\n element.setAttribute(attributeName, value);\n }\n}\n\nfunction findFirstElement(rootElement: HTMLElement, dataAttribute: string): HTMLElement | null {\n return rootElement.querySelector(`[${dataAttribute}]`);\n}\n"]}