@tamagui/button
Version:
342 lines (341 loc) • 12.5 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { getFontSize } from "@tamagui/font-size";
import { getButtonSized } from "@tamagui/get-button-sized";
import { withStaticProperties } from "@tamagui/helpers";
import { useGetThemedIcon } from "@tamagui/helpers-tamagui";
import { ButtonNestingContext, ThemeableStack } from "@tamagui/stacks";
import { SizableText, wrapChildrenInText } from "@tamagui/text";
import { createStyledContext, getVariableValue, spacedChildren, styled, useProps } from "@tamagui/web";
import { useContext } from "react";
function _array_like_to_array(arr, len) {
(len == null || len > arr.length) && (len = arr.length);
for (var i = 0, arr2 = new Array(len); i < len; i++)
arr2[i] = arr[i];
return arr2;
}
function _array_with_holes(arr) {
if (Array.isArray(arr))
return arr;
}
function _array_without_holes(arr) {
if (Array.isArray(arr))
return _array_like_to_array(arr);
}
function _define_property(obj, key, value) {
return key in obj ? Object.defineProperty(obj, key, {
value,
enumerable: !0,
configurable: !0,
writable: !0
}) : obj[key] = value, obj;
}
function _iterable_to_array(iter) {
if (typeof Symbol < "u" && iter[Symbol.iterator] != null || iter["@@iterator"] != null)
return Array.from(iter);
}
function _iterable_to_array_limit(arr, i) {
var _i = arr == null ? null : typeof Symbol < "u" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i != null) {
var _arr = [], _n = !0, _d = !1, _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done) && (_arr.push(_s.value), !(i && _arr.length === i)); _n = !0)
;
} catch (err) {
_d = !0, _e = err;
} finally {
try {
!_n && _i.return != null && _i.return();
} finally {
if (_d)
throw _e;
}
}
return _arr;
}
}
function _non_iterable_rest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _non_iterable_spread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _object_spread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {}, ownKeys2 = Object.keys(source);
typeof Object.getOwnPropertySymbols == "function" && (ownKeys2 = ownKeys2.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}))), ownKeys2.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function(sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _object_spread_props(target, source) {
return source = source ?? {}, Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function(key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
}), target;
}
function _object_without_properties(source, excluded) {
if (source == null)
return {};
var target = _object_without_properties_loose(source, excluded), key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++)
key = sourceSymbolKeys[i], !(excluded.indexOf(key) >= 0) && Object.prototype.propertyIsEnumerable.call(source, key) && (target[key] = source[key]);
}
return target;
}
function _object_without_properties_loose(source, excluded) {
if (source == null)
return {};
var target = {}, sourceKeys = Object.keys(source), key, i;
for (i = 0; i < sourceKeys.length; i++)
key = sourceKeys[i], !(excluded.indexOf(key) >= 0) && (target[key] = source[key]);
return target;
}
function _sliced_to_array(arr, i) {
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _to_consumable_array(arr) {
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _unsupported_iterable_to_array(o, minLen) {
if (o) {
if (typeof o == "string")
return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor && (n = o.constructor.name), n === "Map" || n === "Set")
return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
return _array_like_to_array(o, minLen);
}
}
var ButtonContext = createStyledContext({
// keeping these here means they work with styled() passing down color to text
color: void 0,
ellipse: void 0,
fontFamily: void 0,
fontSize: void 0,
fontStyle: void 0,
fontWeight: void 0,
letterSpacing: void 0,
maxFontSizeMultiplier: void 0,
size: void 0,
textAlign: void 0,
variant: void 0
}), BUTTON_NAME = "Button", ButtonFrame = styled(ThemeableStack, {
name: BUTTON_NAME,
tag: "button",
context: ButtonContext,
role: "button",
focusable: !0,
variants: {
unstyled: {
false: {
size: "$true",
justifyContent: "center",
alignItems: "center",
flexWrap: "nowrap",
flexDirection: "row",
cursor: "pointer",
hoverTheme: !0,
pressTheme: !0,
backgrounded: !0,
borderWidth: 1,
borderColor: "transparent",
focusVisibleStyle: {
outlineColor: "$outlineColor",
outlineStyle: "solid",
outlineWidth: 2
}
}
},
variant: {
outlined: {
backgroundColor: "transparent",
borderWidth: 2,
borderColor: "$borderColor",
hoverStyle: {
backgroundColor: "transparent",
borderColor: "$borderColorHover"
},
pressStyle: {
backgroundColor: "transparent",
borderColor: "$borderColorPress"
},
focusVisibleStyle: {
backgroundColor: "transparent",
borderColor: "$borderColorFocus"
}
}
},
size: {
"...size": getButtonSized,
":number": getButtonSized
},
disabled: {
true: {
pointerEvents: "none"
}
}
},
defaultVariants: {
unstyled: process.env.TAMAGUI_HEADLESS === "1"
}
}), ButtonText = styled(SizableText, {
name: "Button",
context: ButtonContext,
variants: {
unstyled: {
false: {
userSelect: "none",
cursor: "pointer",
// flexGrow 1 leads to inconsistent native style where text pushes to start of view
flexGrow: 0,
flexShrink: 1,
ellipse: !0,
color: "$color"
}
}
},
defaultVariants: {
unstyled: process.env.TAMAGUI_HEADLESS === "1"
}
}), ButtonIcon = function(props) {
var children = props.children, _props_scaleIcon = props.scaleIcon, scaleIcon = _props_scaleIcon === void 0 ? 1 : _props_scaleIcon, _useContext = useContext(ButtonContext), size = _useContext.size, color = _useContext.color, iconSize = (typeof size == "number" ? size * 0.5 : getFontSize(size)) * scaleIcon, getThemedIcon = useGetThemedIcon({
size: iconSize,
color
});
return getThemedIcon(children);
}, ButtonComponent = ButtonFrame.styleable(function(props, ref) {
var _useButton = useButton(props), buttonProps = _useButton.props;
return /* @__PURE__ */ _jsx(ButtonFrame, _object_spread_props(_object_spread({}, buttonProps), {
ref
}));
}), buttonStaticConfig = {
inlineProps: /* @__PURE__ */ new Set([
// text props go here (can't really optimize them, but we never fully extract button anyway)
// may be able to remove this entirely, as the compiler / runtime have gotten better
"color",
"fontWeight",
"fontSize",
"fontFamily",
"fontStyle",
"letterSpacing",
"textAlign",
"unstyled"
])
}, Button2 = withStaticProperties(ButtonComponent, {
Text: ButtonText,
Icon: ButtonIcon
});
function useButton(_param) {
var _$_param = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
Text: Button2.Text
}, textProps = _param.textProps, propsIn = _object_without_properties(_param, [
"textProps"
]), _param_Text = _$_param.Text, Text = _param_Text === void 0 ? Button2.Text : _param_Text, isNested = useContext(ButtonNestingContext), propsActive = useProps(propsIn, {
noNormalize: !0,
noExpand: !0
}), icon = propsActive.icon, iconAfter = propsActive.iconAfter, space = propsActive.space, spaceFlex = propsActive.spaceFlex, _propsActive_scaleIcon = propsActive.scaleIcon, scaleIcon = _propsActive_scaleIcon === void 0 ? 1 : _propsActive_scaleIcon, _propsActive_scaleSpace = propsActive.scaleSpace, scaleSpace = _propsActive_scaleSpace === void 0 ? 0.66 : _propsActive_scaleSpace, separator = propsActive.separator, noTextWrap = propsActive.noTextWrap, fontFamily = propsActive.fontFamily, fontSize = propsActive.fontSize, fontWeight = propsActive.fontWeight, fontStyle = propsActive.fontStyle, letterSpacing = propsActive.letterSpacing, tag = propsActive.tag, ellipse = propsActive.ellipse, maxFontSizeMultiplier = propsActive.maxFontSizeMultiplier, restProps = _object_without_properties(propsActive, [
"icon",
"iconAfter",
"space",
"spaceFlex",
"scaleIcon",
"scaleSpace",
"separator",
"noTextWrap",
"fontFamily",
"fontSize",
"fontWeight",
"fontStyle",
"letterSpacing",
"tag",
"ellipse",
"maxFontSizeMultiplier"
]), size = propsActive.size || (propsActive.unstyled ? void 0 : "$true"), color = propsActive.color, iconSize = (typeof size == "number" ? size * 0.5 : getFontSize(size, {
font: (fontFamily == null ? void 0 : fontFamily[0]) === "$" ? fontFamily : void 0
})) * scaleIcon, getThemedIcon = useGetThemedIcon({
size: iconSize,
color
}), _map = _sliced_to_array([
icon,
iconAfter
].map(getThemedIcon), 2), themedIcon = _map[0], themedIconAfter = _map[1], spaceSize = space ?? getVariableValue(iconSize) * scaleSpace, contents = noTextWrap ? [
propsIn.children
] : wrapChildrenInText(Text, {
children: propsIn.children,
fontFamily,
fontSize,
textProps,
fontWeight,
fontStyle,
letterSpacing,
ellipse,
maxFontSizeMultiplier
}, Text === ButtonText && propsActive.unstyled !== !0 ? {
unstyled: process.env.TAMAGUI_HEADLESS === "1",
size
} : void 0), inner = spacedChildren({
// a bit arbitrary but scaling to font size is necessary so long as button does
space: spaceSize,
spaceFlex,
separator,
direction: propsActive.flexDirection === "column" || propsActive.flexDirection === "column-reverse" ? "vertical" : "horizontal",
children: [
themedIcon
].concat(_to_consumable_array(contents), [
themedIconAfter
])
}), props = _object_spread_props(_object_spread(_object_spread_props(_object_spread({
size
}, propsIn.disabled && {
// in rnw - false still has keyboard tabIndex, undefined = not actually focusable
focusable: void 0,
// even with tabIndex unset, it will keep focusVisibleStyle on web so disable it here
focusVisibleStyle: {
borderColor: "$background"
}
}), {
// fixes SSR issue + DOM nesting issue of not allowing button in button
tag: tag ?? (isNested ? "span" : (
// defaults to <a /> when accessibilityRole = link
// see https://github.com/tamagui/tamagui/issues/505
propsActive.accessibilityRole === "link" || propsActive.role === "link" ? "a" : "button"
))
}), restProps), {
children: /* @__PURE__ */ _jsx(ButtonNestingContext.Provider, {
value: !0,
children: inner
}),
// forces it to be a runtime pressStyle so it passes through context text colors
disableClassName: !0
});
return {
spaceSize,
isNested,
props
};
}
export {
Button2 as Button,
ButtonContext,
ButtonFrame,
ButtonIcon,
ButtonText,
buttonStaticConfig,
useButton
};
//# sourceMappingURL=Button.js.map