@spark-web/text-link
Version:
--- title: Text Link storybookPath: navigation-textlink--default isExperimentalPackage: true ---
97 lines (88 loc) • 3.48 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var css = require('@emotion/css');
var box = require('@spark-web/box');
var link = require('@spark-web/link');
var ts = require('@spark-web/utils/ts');
var text = require('@spark-web/text');
var theme = require('@spark-web/theme');
var internal = require('@spark-web/utils/internal');
var jsxRuntime = require('react/jsx-runtime');
var utils = require('@spark-web/utils');
var react = require('react');
var TEXT_LINK_ERROR_MESSAGE = 'TextLink components must be inside `Text`.';
function useTextLink(tag) {
var textContext = text.useTextContext();
// Limit API surface area; expect style inheritance
if (!textContext) {
throw new Error(TEXT_LINK_ERROR_MESSAGE);
}
var theme$1 = theme.useTheme();
var textColor = text.useForegroundTone(textContext.tone);
var resetStyles = internal.resetElementStyles(tag);
var linkStyles = {
color: textColor,
cursor: 'pointer',
textDecoration: 'underline',
fontWeight: theme$1.typography.fontWeight.semibold
};
var styles = [resetStyles, linkStyles];
return styles;
}
var _excluded$1 = ["as", "data"];
/**
* Text links are used as navigational elements. They may appear on their own,
* within a sentence or paragraph, or directly following content.
*
* @note If you are **only** providing "onClick" use `TextLinkButton` instead.
*/
var TextLink = ts.forwardRefWithAs(
// NOTE: we need `forwardRefWithAs` for TS, but we don't want consumers changing the underlying element
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function (_ref, ref) {
_ref.as;
var data = _ref.data,
consumerProps = _objectWithoutProperties(_ref, _excluded$1);
var LinkComponent = link.useLinkComponent(ref);
var styles = useTextLink('a');
return /*#__PURE__*/jsxRuntime.jsx(box.Box, _objectSpread({
as: LinkComponent,
asElement: "a",
ref: ref,
className: css.css(styles),
data: data
}, consumerProps));
});
var _excluded = ["data"];
// NOTE: Rather than a native `button` element, we render a `span` with the ARIA
// role of "button" to avoid issues with text behaviour. Resolves:
// - alignment
// - truncating
// - wrapping
/** The appearance of `TextLink`, with the semantics of a `<button/>`. */
var TextLinkButton = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
var data = _ref.data,
consumerProps = _objectWithoutProperties(_ref, _excluded);
var styles = useTextLink('span');
var internalRef = react.useRef(null);
var ref = utils.useComposedRefs(internalRef, forwardedRef);
var handleKeyDown = react.useCallback(function (event) {
if (event.key === 'Enter' || event.key === ' ') {
var _internalRef$current;
event.preventDefault();
(_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.click();
}
}, [internalRef]);
return /*#__PURE__*/jsxRuntime.jsx("span", _objectSpread(_objectSpread({
role: "button",
ref: ref,
className: css.css(styles),
tabIndex: 0,
onKeyDown: handleKeyDown
}, data ? internal.buildDataAttributes(data) : undefined), consumerProps));
});
TextLinkButton.displayName = 'TextLinkButton';
exports.TextLink = TextLink;
exports.TextLinkButton = TextLinkButton;
;