@tamagui/button 1.2.9 → 1.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,180 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import {
3
+ ButtonNestingContext,
4
+ getVariableValue,
5
+ isRSC,
6
+ spacedChildren,
7
+ styled,
8
+ themeable,
9
+ useMediaPropsActive
10
+ } from "@tamagui/core";
11
+ import { getFontSize } from "@tamagui/font-size";
12
+ import { getButtonSized } from "@tamagui/get-button-sized";
13
+ import { useGetThemedIcon } from "@tamagui/helpers-tamagui";
14
+ import { ThemeableStack } from "@tamagui/stacks";
15
+ import { SizableText, wrapChildrenInText } from "@tamagui/text";
16
+ import { forwardRef, useContext } from "react";
17
+ const NAME = "Button";
18
+ const ButtonFrame = styled(ThemeableStack, {
19
+ name: NAME,
20
+ tag: "button",
21
+ justifyContent: "center",
22
+ alignItems: "center",
23
+ flexWrap: "nowrap",
24
+ flexDirection: "row",
25
+ cursor: "pointer",
26
+ variants: {
27
+ defaultStyle: {
28
+ true: {
29
+ focusable: true,
30
+ hoverTheme: true,
31
+ pressTheme: true,
32
+ backgrounded: true,
33
+ borderWidth: 1,
34
+ borderColor: "transparent",
35
+ pressStyle: {
36
+ borderColor: "transparent"
37
+ },
38
+ hoverStyle: {
39
+ borderColor: "transparent"
40
+ },
41
+ focusStyle: {
42
+ borderColor: "$borderColorFocus"
43
+ }
44
+ }
45
+ },
46
+ size: {
47
+ "...size": getButtonSized
48
+ },
49
+ active: {
50
+ true: {
51
+ hoverStyle: {
52
+ backgroundColor: "$background"
53
+ }
54
+ }
55
+ },
56
+ disabled: {
57
+ true: {
58
+ pointerEvents: "none"
59
+ }
60
+ }
61
+ },
62
+ defaultVariants: {
63
+ size: "$true"
64
+ }
65
+ });
66
+ const ButtonText = styled(SizableText, {
67
+ name: "ButtonText",
68
+ userSelect: "none",
69
+ cursor: "pointer",
70
+ // flexGrow 1 leads to inconsistent native style where text pushes to start of view
71
+ flexGrow: 0,
72
+ flexShrink: 1,
73
+ ellipse: true,
74
+ variants: {
75
+ defaultStyle: {
76
+ true: {
77
+ color: "$color"
78
+ }
79
+ }
80
+ }
81
+ });
82
+ const ButtonComponent = forwardRef(function Button(props, ref) {
83
+ const {
84
+ props: { unstyled, ...buttonProps }
85
+ } = useButton(props);
86
+ return /* @__PURE__ */ jsx(ButtonFrame, { defaultStyle: !unstyled, ...buttonProps, ref });
87
+ });
88
+ const buttonStaticConfig = {
89
+ inlineProps: /* @__PURE__ */ new Set([
90
+ // text props go here (can't really optimize them, but we never fully extract button anyway)
91
+ // may be able to remove this entirely, as the compiler / runtime have gotten better
92
+ "color",
93
+ "fontWeight",
94
+ "fontSize",
95
+ "fontFamily",
96
+ "letterSpacing",
97
+ "textAlign",
98
+ "unstyled"
99
+ ])
100
+ };
101
+ const Button2 = ButtonFrame.extractable(
102
+ themeable(ButtonComponent, ButtonFrame.staticConfig),
103
+ buttonStaticConfig
104
+ );
105
+ function useButton(propsIn, { Text = ButtonText } = { Text: ButtonText }) {
106
+ const {
107
+ children,
108
+ icon,
109
+ iconAfter,
110
+ noTextWrap,
111
+ theme: themeName,
112
+ space,
113
+ spaceFlex,
114
+ scaleIcon = 1,
115
+ scaleSpace = 0.66,
116
+ separator,
117
+ // text props
118
+ color,
119
+ fontWeight,
120
+ letterSpacing,
121
+ fontSize,
122
+ fontFamily,
123
+ textAlign,
124
+ textProps,
125
+ ...rest
126
+ } = propsIn;
127
+ const isNested = isRSC ? false : useContext(ButtonNestingContext);
128
+ const propsActive = useMediaPropsActive(propsIn);
129
+ const size = propsActive.size || "$true";
130
+ const iconSize = (typeof size === "number" ? size * 0.5 : getFontSize(size)) * scaleIcon;
131
+ const getThemedIcon = useGetThemedIcon({ size: iconSize, color });
132
+ const [themedIcon, themedIconAfter] = [icon, iconAfter].map(getThemedIcon);
133
+ const spaceSize = propsActive.space ?? getVariableValue(iconSize) * scaleSpace;
134
+ const contents = wrapChildrenInText(
135
+ Text,
136
+ propsActive,
137
+ Text === ButtonText ? {
138
+ defaultStyle: !propsIn.unstyled
139
+ } : void 0
140
+ );
141
+ const inner = spacedChildren({
142
+ // a bit arbitrary but scaling to font size is necessary so long as button does
143
+ space: spaceSize,
144
+ spaceFlex,
145
+ separator,
146
+ direction: propsActive.flexDirection === "column" || propsActive.flexDirection === "column-reverse" ? "vertical" : "horizontal",
147
+ children: [themedIcon, ...contents, themedIconAfter]
148
+ });
149
+ const tag = isNested ? "span" : (
150
+ // defaults to <a /> when accessibilityRole = link
151
+ // see https://github.com/tamagui/tamagui/issues/505
152
+ propsIn.accessibilityRole === "link" ? "a" : void 0
153
+ );
154
+ const props = {
155
+ ...propsActive.disabled && {
156
+ // in rnw - false still has keyboard tabIndex, undefined = not actually focusable
157
+ focusable: void 0,
158
+ // even with tabIndex unset, it will keep focusStyle on web so disable it here
159
+ focusStyle: {
160
+ borderColor: "$background"
161
+ }
162
+ },
163
+ tag,
164
+ ...rest,
165
+ children: isRSC ? inner : /* @__PURE__ */ jsx(ButtonNestingContext.Provider, { value: true, children: inner })
166
+ };
167
+ return {
168
+ spaceSize,
169
+ isNested,
170
+ props
171
+ };
172
+ }
173
+ export {
174
+ Button2 as Button,
175
+ ButtonFrame,
176
+ ButtonText,
177
+ buttonStaticConfig,
178
+ useButton
179
+ };
180
+ //# sourceMappingURL=Button.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/Button.tsx"],
4
+ "sourcesContent": ["import {\n ButtonNestingContext,\n GetProps,\n TamaguiElement,\n ThemeableProps,\n getVariableValue,\n isRSC,\n spacedChildren,\n styled,\n themeable,\n useMediaPropsActive,\n} from '@tamagui/core'\nimport { getFontSize } from '@tamagui/font-size'\nimport { getButtonSized } from '@tamagui/get-button-sized'\nimport { useGetThemedIcon } from '@tamagui/helpers-tamagui'\nimport { ThemeableStack } from '@tamagui/stacks'\nimport { SizableText, TextParentStyles, wrapChildrenInText } from '@tamagui/text'\nimport { FunctionComponent, forwardRef, useContext } from 'react'\n\ntype ButtonIconProps = { color?: string; size?: number }\ntype IconProp = JSX.Element | FunctionComponent<ButtonIconProps> | null\n\nexport type ButtonProps = Omit<TextParentStyles, 'TextComponent'> &\n GetProps<typeof ButtonFrame> &\n ThemeableProps & {\n /**\n * add icon before, passes color and size automatically if Component\n */\n icon?: IconProp\n /**\n * add icon after, passes color and size automatically if Component\n */\n iconAfter?: IconProp\n /**\n * adjust icon relative to size\n *\n * @default 1\n */\n scaleIcon?: number\n /**\n * make the spacing elements flex\n */\n spaceFlex?: number | boolean\n /**\n * adjust internal space relative to icon size\n */\n scaleSpace?: number\n /**\n *\n */\n unstyled?: boolean\n }\n\nconst NAME = 'Button'\n\nexport const ButtonFrame = styled(ThemeableStack, {\n name: NAME,\n tag: 'button',\n justifyContent: 'center',\n alignItems: 'center',\n flexWrap: 'nowrap',\n flexDirection: 'row',\n cursor: 'pointer',\n\n variants: {\n defaultStyle: {\n true: {\n focusable: true,\n hoverTheme: true,\n pressTheme: true,\n backgrounded: true,\n borderWidth: 1,\n borderColor: 'transparent',\n\n pressStyle: {\n borderColor: 'transparent',\n },\n\n hoverStyle: {\n borderColor: 'transparent',\n },\n\n focusStyle: {\n borderColor: '$borderColorFocus',\n },\n },\n },\n\n size: {\n '...size': getButtonSized,\n },\n\n active: {\n true: {\n hoverStyle: {\n backgroundColor: '$background',\n },\n },\n },\n\n disabled: {\n true: {\n pointerEvents: 'none',\n },\n },\n } as const,\n\n defaultVariants: {\n size: '$true',\n },\n})\n\nexport const ButtonText = styled(SizableText, {\n name: 'ButtonText',\n userSelect: 'none',\n cursor: 'pointer',\n // flexGrow 1 leads to inconsistent native style where text pushes to start of view\n flexGrow: 0,\n flexShrink: 1,\n ellipse: true,\n\n variants: {\n defaultStyle: {\n true: {\n color: '$color',\n },\n },\n },\n})\n\nconst ButtonComponent = forwardRef<TamaguiElement, ButtonProps>(function Button(\n props,\n ref\n) {\n const {\n props: { unstyled, ...buttonProps },\n } = useButton(props)\n return <ButtonFrame defaultStyle={!unstyled} {...buttonProps} ref={ref} />\n})\n\nexport const buttonStaticConfig = {\n inlineProps: new Set([\n // text props go here (can't really optimize them, but we never fully extract button anyway)\n // may be able to remove this entirely, as the compiler / runtime have gotten better\n 'color',\n 'fontWeight',\n 'fontSize',\n 'fontFamily',\n 'letterSpacing',\n 'textAlign',\n 'unstyled',\n ]),\n}\n\nexport const Button = ButtonFrame.extractable(\n themeable(ButtonComponent, ButtonFrame.staticConfig),\n buttonStaticConfig\n)\n\nexport function useButton(\n propsIn: ButtonProps,\n { Text = ButtonText }: { Text: any } = { Text: ButtonText }\n) {\n // careful not to desctructure and re-order props, order is important\n const {\n children,\n icon,\n iconAfter,\n noTextWrap,\n theme: themeName,\n space,\n spaceFlex,\n scaleIcon = 1,\n scaleSpace = 0.66,\n separator,\n\n // text props\n color,\n fontWeight,\n letterSpacing,\n fontSize,\n fontFamily,\n textAlign,\n textProps,\n ...rest\n } = propsIn\n\n const isNested = isRSC ? false : useContext(ButtonNestingContext)\n const propsActive = useMediaPropsActive(propsIn)\n const size = propsActive.size || '$true'\n const iconSize = (typeof size === 'number' ? size * 0.5 : getFontSize(size)) * scaleIcon\n const getThemedIcon = useGetThemedIcon({ size: iconSize, color })\n const [themedIcon, themedIconAfter] = [icon, iconAfter].map(getThemedIcon)\n const spaceSize = propsActive.space ?? getVariableValue(iconSize) * scaleSpace\n const contents = wrapChildrenInText(\n Text,\n propsActive,\n Text === ButtonText\n ? {\n defaultStyle: !propsIn.unstyled,\n }\n : undefined\n )\n const inner = spacedChildren({\n // a bit arbitrary but scaling to font size is necessary so long as button does\n space: spaceSize,\n spaceFlex,\n separator,\n direction:\n propsActive.flexDirection === 'column' ||\n propsActive.flexDirection === 'column-reverse'\n ? 'vertical'\n : 'horizontal',\n children: [themedIcon, ...contents, themedIconAfter],\n })\n\n // fixes SSR issue + DOM nesting issue of not allowing button in button\n const tag = isNested\n ? 'span'\n : // defaults to <a /> when accessibilityRole = link\n // see https://github.com/tamagui/tamagui/issues/505\n propsIn.accessibilityRole === 'link'\n ? 'a'\n : undefined\n\n const props = {\n ...(propsActive.disabled && {\n // in rnw - false still has keyboard tabIndex, undefined = not actually focusable\n focusable: undefined,\n // even with tabIndex unset, it will keep focusStyle on web so disable it here\n focusStyle: {\n borderColor: '$background',\n },\n }),\n tag,\n ...rest,\n children: isRSC ? (\n inner\n ) : (\n <ButtonNestingContext.Provider value={true}>{inner}</ButtonNestingContext.Provider>\n ),\n }\n\n return {\n spaceSize,\n isNested,\n props,\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Button"]
7
+ }
@@ -0,0 +1,11 @@
1
+ process.env.TAMAGUI_TARGET = "web";
2
+ import { getDefaultTamaguiConfig } from "@tamagui/config-default";
3
+ import { createTamagui } from "@tamagui/core";
4
+ import { describe, expect, test } from "vitest";
5
+ const conf = createTamagui(getDefaultTamaguiConfig());
6
+ describe("Button", () => {
7
+ test(`123`, () => {
8
+ expect(true).toBeTruthy();
9
+ });
10
+ });
11
+ //# sourceMappingURL=Button.test.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/Button.test.tsx"],
4
+ "sourcesContent": ["process.env.TAMAGUI_TARGET = 'web'\n\nimport { getDefaultTamaguiConfig } from '@tamagui/config-default'\nimport { TamaguiProvider, createTamagui } from '@tamagui/core'\nimport { render } from '@testing-library/react'\nimport { describe, expect, test } from 'vitest'\n\nimport { Button } from '.'\n\nconst conf = createTamagui(getDefaultTamaguiConfig())\n\ndescribe('Button', () => {\n test(`123`, () => {\n expect(true).toBeTruthy()\n })\n\n // test(`Adapts to a when given accessibilityRole=\"link\"`, async () => {\n // const { container } = render(\n // <TamaguiProvider config={conf} defaultTheme=\"light\">\n // <Button href=\"http://google.com\" accessibilityRole=\"link\" />\n // </TamaguiProvider>\n // )\n\n // expect(container.firstChild).toMatchSnapshot()\n // })\n})\n"],
5
+ "mappings": "AAAA,QAAQ,IAAI,iBAAiB;AAE7B,SAAS,+BAA+B;AACxC,SAA0B,qBAAqB;AAE/C,SAAS,UAAU,QAAQ,YAAY;AAIvC,MAAM,OAAO,cAAc,wBAAwB,CAAC;AAEpD,SAAS,UAAU,MAAM;AACvB,OAAK,OAAO,MAAM;AAChB,WAAO,IAAI,EAAE,WAAW;AAAA,EAC1B,CAAC;AAWH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./Button";
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["export * from './Button'\n"],
5
+ "mappings": "AAAA,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,179 @@
1
+ import {
2
+ ButtonNestingContext,
3
+ getVariableValue,
4
+ isRSC,
5
+ spacedChildren,
6
+ styled,
7
+ themeable,
8
+ useMediaPropsActive
9
+ } from "@tamagui/core";
10
+ import { getFontSize } from "@tamagui/font-size";
11
+ import { getButtonSized } from "@tamagui/get-button-sized";
12
+ import { useGetThemedIcon } from "@tamagui/helpers-tamagui";
13
+ import { ThemeableStack } from "@tamagui/stacks";
14
+ import { SizableText, wrapChildrenInText } from "@tamagui/text";
15
+ import { forwardRef, useContext } from "react";
16
+ const NAME = "Button";
17
+ const ButtonFrame = styled(ThemeableStack, {
18
+ name: NAME,
19
+ tag: "button",
20
+ justifyContent: "center",
21
+ alignItems: "center",
22
+ flexWrap: "nowrap",
23
+ flexDirection: "row",
24
+ cursor: "pointer",
25
+ variants: {
26
+ defaultStyle: {
27
+ true: {
28
+ focusable: true,
29
+ hoverTheme: true,
30
+ pressTheme: true,
31
+ backgrounded: true,
32
+ borderWidth: 1,
33
+ borderColor: "transparent",
34
+ pressStyle: {
35
+ borderColor: "transparent"
36
+ },
37
+ hoverStyle: {
38
+ borderColor: "transparent"
39
+ },
40
+ focusStyle: {
41
+ borderColor: "$borderColorFocus"
42
+ }
43
+ }
44
+ },
45
+ size: {
46
+ "...size": getButtonSized
47
+ },
48
+ active: {
49
+ true: {
50
+ hoverStyle: {
51
+ backgroundColor: "$background"
52
+ }
53
+ }
54
+ },
55
+ disabled: {
56
+ true: {
57
+ pointerEvents: "none"
58
+ }
59
+ }
60
+ },
61
+ defaultVariants: {
62
+ size: "$true"
63
+ }
64
+ });
65
+ const ButtonText = styled(SizableText, {
66
+ name: "ButtonText",
67
+ userSelect: "none",
68
+ cursor: "pointer",
69
+ // flexGrow 1 leads to inconsistent native style where text pushes to start of view
70
+ flexGrow: 0,
71
+ flexShrink: 1,
72
+ ellipse: true,
73
+ variants: {
74
+ defaultStyle: {
75
+ true: {
76
+ color: "$color"
77
+ }
78
+ }
79
+ }
80
+ });
81
+ const ButtonComponent = forwardRef(function Button(props, ref) {
82
+ const {
83
+ props: { unstyled, ...buttonProps }
84
+ } = useButton(props);
85
+ return <ButtonFrame defaultStyle={!unstyled} {...buttonProps} ref={ref} />;
86
+ });
87
+ const buttonStaticConfig = {
88
+ inlineProps: /* @__PURE__ */ new Set([
89
+ // text props go here (can't really optimize them, but we never fully extract button anyway)
90
+ // may be able to remove this entirely, as the compiler / runtime have gotten better
91
+ "color",
92
+ "fontWeight",
93
+ "fontSize",
94
+ "fontFamily",
95
+ "letterSpacing",
96
+ "textAlign",
97
+ "unstyled"
98
+ ])
99
+ };
100
+ const Button2 = ButtonFrame.extractable(
101
+ themeable(ButtonComponent, ButtonFrame.staticConfig),
102
+ buttonStaticConfig
103
+ );
104
+ function useButton(propsIn, { Text = ButtonText } = { Text: ButtonText }) {
105
+ const {
106
+ children,
107
+ icon,
108
+ iconAfter,
109
+ noTextWrap,
110
+ theme: themeName,
111
+ space,
112
+ spaceFlex,
113
+ scaleIcon = 1,
114
+ scaleSpace = 0.66,
115
+ separator,
116
+ // text props
117
+ color,
118
+ fontWeight,
119
+ letterSpacing,
120
+ fontSize,
121
+ fontFamily,
122
+ textAlign,
123
+ textProps,
124
+ ...rest
125
+ } = propsIn;
126
+ const isNested = isRSC ? false : useContext(ButtonNestingContext);
127
+ const propsActive = useMediaPropsActive(propsIn);
128
+ const size = propsActive.size || "$true";
129
+ const iconSize = (typeof size === "number" ? size * 0.5 : getFontSize(size)) * scaleIcon;
130
+ const getThemedIcon = useGetThemedIcon({ size: iconSize, color });
131
+ const [themedIcon, themedIconAfter] = [icon, iconAfter].map(getThemedIcon);
132
+ const spaceSize = propsActive.space ?? getVariableValue(iconSize) * scaleSpace;
133
+ const contents = wrapChildrenInText(
134
+ Text,
135
+ propsActive,
136
+ Text === ButtonText ? {
137
+ defaultStyle: !propsIn.unstyled
138
+ } : void 0
139
+ );
140
+ const inner = spacedChildren({
141
+ // a bit arbitrary but scaling to font size is necessary so long as button does
142
+ space: spaceSize,
143
+ spaceFlex,
144
+ separator,
145
+ direction: propsActive.flexDirection === "column" || propsActive.flexDirection === "column-reverse" ? "vertical" : "horizontal",
146
+ children: [themedIcon, ...contents, themedIconAfter]
147
+ });
148
+ const tag = isNested ? "span" : (
149
+ // defaults to <a /> when accessibilityRole = link
150
+ // see https://github.com/tamagui/tamagui/issues/505
151
+ propsIn.accessibilityRole === "link" ? "a" : void 0
152
+ );
153
+ const props = {
154
+ ...propsActive.disabled && {
155
+ // in rnw - false still has keyboard tabIndex, undefined = not actually focusable
156
+ focusable: void 0,
157
+ // even with tabIndex unset, it will keep focusStyle on web so disable it here
158
+ focusStyle: {
159
+ borderColor: "$background"
160
+ }
161
+ },
162
+ tag,
163
+ ...rest,
164
+ children: isRSC ? inner : <ButtonNestingContext.Provider value={true}>{inner}</ButtonNestingContext.Provider>
165
+ };
166
+ return {
167
+ spaceSize,
168
+ isNested,
169
+ props
170
+ };
171
+ }
172
+ export {
173
+ Button2 as Button,
174
+ ButtonFrame,
175
+ ButtonText,
176
+ buttonStaticConfig,
177
+ useButton
178
+ };
179
+ //# sourceMappingURL=Button.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/Button.tsx"],
4
+ "sourcesContent": ["import {\n ButtonNestingContext,\n GetProps,\n TamaguiElement,\n ThemeableProps,\n getVariableValue,\n isRSC,\n spacedChildren,\n styled,\n themeable,\n useMediaPropsActive,\n} from '@tamagui/core'\nimport { getFontSize } from '@tamagui/font-size'\nimport { getButtonSized } from '@tamagui/get-button-sized'\nimport { useGetThemedIcon } from '@tamagui/helpers-tamagui'\nimport { ThemeableStack } from '@tamagui/stacks'\nimport { SizableText, TextParentStyles, wrapChildrenInText } from '@tamagui/text'\nimport { FunctionComponent, forwardRef, useContext } from 'react'\n\ntype ButtonIconProps = { color?: string; size?: number }\ntype IconProp = JSX.Element | FunctionComponent<ButtonIconProps> | null\n\nexport type ButtonProps = Omit<TextParentStyles, 'TextComponent'> &\n GetProps<typeof ButtonFrame> &\n ThemeableProps & {\n /**\n * add icon before, passes color and size automatically if Component\n */\n icon?: IconProp\n /**\n * add icon after, passes color and size automatically if Component\n */\n iconAfter?: IconProp\n /**\n * adjust icon relative to size\n *\n * @default 1\n */\n scaleIcon?: number\n /**\n * make the spacing elements flex\n */\n spaceFlex?: number | boolean\n /**\n * adjust internal space relative to icon size\n */\n scaleSpace?: number\n /**\n *\n */\n unstyled?: boolean\n }\n\nconst NAME = 'Button'\n\nexport const ButtonFrame = styled(ThemeableStack, {\n name: NAME,\n tag: 'button',\n justifyContent: 'center',\n alignItems: 'center',\n flexWrap: 'nowrap',\n flexDirection: 'row',\n cursor: 'pointer',\n\n variants: {\n defaultStyle: {\n true: {\n focusable: true,\n hoverTheme: true,\n pressTheme: true,\n backgrounded: true,\n borderWidth: 1,\n borderColor: 'transparent',\n\n pressStyle: {\n borderColor: 'transparent',\n },\n\n hoverStyle: {\n borderColor: 'transparent',\n },\n\n focusStyle: {\n borderColor: '$borderColorFocus',\n },\n },\n },\n\n size: {\n '...size': getButtonSized,\n },\n\n active: {\n true: {\n hoverStyle: {\n backgroundColor: '$background',\n },\n },\n },\n\n disabled: {\n true: {\n pointerEvents: 'none',\n },\n },\n } as const,\n\n defaultVariants: {\n size: '$true',\n },\n})\n\nexport const ButtonText = styled(SizableText, {\n name: 'ButtonText',\n userSelect: 'none',\n cursor: 'pointer',\n // flexGrow 1 leads to inconsistent native style where text pushes to start of view\n flexGrow: 0,\n flexShrink: 1,\n ellipse: true,\n\n variants: {\n defaultStyle: {\n true: {\n color: '$color',\n },\n },\n },\n})\n\nconst ButtonComponent = forwardRef<TamaguiElement, ButtonProps>(function Button(\n props,\n ref\n) {\n const {\n props: { unstyled, ...buttonProps },\n } = useButton(props)\n return <ButtonFrame defaultStyle={!unstyled} {...buttonProps} ref={ref} />\n})\n\nexport const buttonStaticConfig = {\n inlineProps: new Set([\n // text props go here (can't really optimize them, but we never fully extract button anyway)\n // may be able to remove this entirely, as the compiler / runtime have gotten better\n 'color',\n 'fontWeight',\n 'fontSize',\n 'fontFamily',\n 'letterSpacing',\n 'textAlign',\n 'unstyled',\n ]),\n}\n\nexport const Button = ButtonFrame.extractable(\n themeable(ButtonComponent, ButtonFrame.staticConfig),\n buttonStaticConfig\n)\n\nexport function useButton(\n propsIn: ButtonProps,\n { Text = ButtonText }: { Text: any } = { Text: ButtonText }\n) {\n // careful not to desctructure and re-order props, order is important\n const {\n children,\n icon,\n iconAfter,\n noTextWrap,\n theme: themeName,\n space,\n spaceFlex,\n scaleIcon = 1,\n scaleSpace = 0.66,\n separator,\n\n // text props\n color,\n fontWeight,\n letterSpacing,\n fontSize,\n fontFamily,\n textAlign,\n textProps,\n ...rest\n } = propsIn\n\n const isNested = isRSC ? false : useContext(ButtonNestingContext)\n const propsActive = useMediaPropsActive(propsIn)\n const size = propsActive.size || '$true'\n const iconSize = (typeof size === 'number' ? size * 0.5 : getFontSize(size)) * scaleIcon\n const getThemedIcon = useGetThemedIcon({ size: iconSize, color })\n const [themedIcon, themedIconAfter] = [icon, iconAfter].map(getThemedIcon)\n const spaceSize = propsActive.space ?? getVariableValue(iconSize) * scaleSpace\n const contents = wrapChildrenInText(\n Text,\n propsActive,\n Text === ButtonText\n ? {\n defaultStyle: !propsIn.unstyled,\n }\n : undefined\n )\n const inner = spacedChildren({\n // a bit arbitrary but scaling to font size is necessary so long as button does\n space: spaceSize,\n spaceFlex,\n separator,\n direction:\n propsActive.flexDirection === 'column' ||\n propsActive.flexDirection === 'column-reverse'\n ? 'vertical'\n : 'horizontal',\n children: [themedIcon, ...contents, themedIconAfter],\n })\n\n // fixes SSR issue + DOM nesting issue of not allowing button in button\n const tag = isNested\n ? 'span'\n : // defaults to <a /> when accessibilityRole = link\n // see https://github.com/tamagui/tamagui/issues/505\n propsIn.accessibilityRole === 'link'\n ? 'a'\n : undefined\n\n const props = {\n ...(propsActive.disabled && {\n // in rnw - false still has keyboard tabIndex, undefined = not actually focusable\n focusable: undefined,\n // even with tabIndex unset, it will keep focusStyle on web so disable it here\n focusStyle: {\n borderColor: '$background',\n },\n }),\n tag,\n ...rest,\n children: isRSC ? (\n inner\n ) : (\n <ButtonNestingContext.Provider value={true}>{inner}</ButtonNestingContext.Provider>\n ),\n }\n\n return {\n spaceSize,\n isNested,\n props,\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Button"]
7
+ }
@@ -0,0 +1,11 @@
1
+ process.env.TAMAGUI_TARGET = "web";
2
+ import { getDefaultTamaguiConfig } from "@tamagui/config-default";
3
+ import { createTamagui } from "@tamagui/core";
4
+ import { describe, expect, test } from "vitest";
5
+ const conf = createTamagui(getDefaultTamaguiConfig());
6
+ describe("Button", () => {
7
+ test(`123`, () => {
8
+ expect(true).toBeTruthy();
9
+ });
10
+ });
11
+ //# sourceMappingURL=Button.test.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/Button.test.tsx"],
4
+ "sourcesContent": ["process.env.TAMAGUI_TARGET = 'web'\n\nimport { getDefaultTamaguiConfig } from '@tamagui/config-default'\nimport { TamaguiProvider, createTamagui } from '@tamagui/core'\nimport { render } from '@testing-library/react'\nimport { describe, expect, test } from 'vitest'\n\nimport { Button } from '.'\n\nconst conf = createTamagui(getDefaultTamaguiConfig())\n\ndescribe('Button', () => {\n test(`123`, () => {\n expect(true).toBeTruthy()\n })\n\n // test(`Adapts to a when given accessibilityRole=\"link\"`, async () => {\n // const { container } = render(\n // <TamaguiProvider config={conf} defaultTheme=\"light\">\n // <Button href=\"http://google.com\" accessibilityRole=\"link\" />\n // </TamaguiProvider>\n // )\n\n // expect(container.firstChild).toMatchSnapshot()\n // })\n})\n"],
5
+ "mappings": "AAAA,QAAQ,IAAI,iBAAiB;AAE7B,SAAS,+BAA+B;AACxC,SAA0B,qBAAqB;AAE/C,SAAS,UAAU,QAAQ,YAAY;AAIvC,MAAM,OAAO,cAAc,wBAAwB,CAAC;AAEpD,SAAS,UAAU,MAAM;AACvB,OAAK,OAAO,MAAM;AAChB,WAAO,IAAI,EAAE,WAAW;AAAA,EAC1B,CAAC;AAWH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./Button";
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["export * from './Button'\n"],
5
+ "mappings": "AAAA,cAAc;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/button",
3
- "version": "1.2.9",
3
+ "version": "1.2.11",
4
4
  "sideEffects": [
5
5
  "*.css"
6
6
  ],
@@ -24,22 +24,22 @@
24
24
  "./package.json": "./package.json",
25
25
  ".": {
26
26
  "types": "./types/index.d.ts",
27
- "import": "./dist/esm/index.js",
27
+ "import": "./dist/esm/index.mjs",
28
28
  "require": "./dist/cjs/index.js"
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@tamagui/core": "^1.2.9",
33
- "@tamagui/font-size": "^1.2.9",
34
- "@tamagui/get-button-sized": "^1.2.9",
35
- "@tamagui/helpers-tamagui": "^1.2.9"
32
+ "@tamagui/core": "^1.2.11",
33
+ "@tamagui/font-size": "^1.2.11",
34
+ "@tamagui/get-button-sized": "^1.2.11",
35
+ "@tamagui/helpers-tamagui": "^1.2.11"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "*",
39
39
  "react-dom": "*"
40
40
  },
41
41
  "devDependencies": {
42
- "@tamagui/build": "^1.2.9",
42
+ "@tamagui/build": "^1.2.11",
43
43
  "react": "^18.2.0",
44
44
  "react-dom": "^18.2.0",
45
45
  "vitest": "^0.26.3"