@tamagui/button 1.26.1 → 1.27.0-1684163004699
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.
- package/dist/cjs/Button.js +17 -45
- package/dist/cjs/Button.js.map +1 -1
- package/dist/cjs/Button.test.js.map +1 -1
- package/dist/cjs/base.js +29 -0
- package/dist/cjs/base.js.map +6 -0
- package/dist/cjs/themed.js +252 -0
- package/dist/cjs/themed.js.map +6 -0
- package/dist/esm/Button.js +17 -51
- package/dist/esm/Button.js.map +1 -1
- package/dist/esm/Button.test.js.map +1 -1
- package/dist/esm/base.js +5 -0
- package/dist/esm/base.js.map +6 -0
- package/dist/esm/{Button.mjs → themed.js} +77 -77
- package/dist/esm/themed.js.map +6 -0
- package/dist/jsx/Button.js +17 -47
- package/dist/jsx/Button.js.map +1 -1
- package/dist/jsx/Button.mjs +17 -47
- package/dist/jsx/Button.mjs.map +1 -1
- package/dist/jsx/Button.test.js.map +1 -1
- package/dist/jsx/Button.test.mjs.map +1 -1
- package/dist/jsx/base.js +5 -0
- package/dist/jsx/base.js.map +6 -0
- package/dist/jsx/base.mjs.map +6 -0
- package/dist/jsx/themed.js +232 -0
- package/dist/jsx/themed.js.map +6 -0
- package/dist/jsx/themed.mjs.map +6 -0
- package/package.json +7 -7
- package/src/Button.test.tsx +1 -4
- package/src/Button.tsx +33 -90
- package/types/Button.d.ts +91 -80
- package/types/Button.d.ts.map +1 -1
- package/types/base.d.ts.map +1 -0
- package/types/themed.d.ts.map +1 -0
- package/dist/esm/Button.test.mjs +0 -11
- package/dist/esm/index.mjs +0 -2
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { createContextScope } from "@tamagui/create-context";
|
|
2
|
+
import { getFontSize } from "@tamagui/font-size";
|
|
3
|
+
import { getButtonSized } from "@tamagui/get-button-sized";
|
|
4
|
+
import { useGetThemedIcon } from "@tamagui/helpers-tamagui";
|
|
5
|
+
import { wrapChildrenInText } from "@tamagui/text";
|
|
6
|
+
import {
|
|
7
|
+
ButtonNestingContext,
|
|
8
|
+
getConfig,
|
|
9
|
+
getVariableValue,
|
|
10
|
+
isRSC,
|
|
11
|
+
spacedChildren,
|
|
12
|
+
styled,
|
|
13
|
+
useMediaPropsActive,
|
|
14
|
+
withStaticProperties
|
|
15
|
+
} from "@tamagui/web";
|
|
16
|
+
import { useCallback, useContext, useEffect, useState } from "react";
|
|
17
|
+
import {
|
|
18
|
+
BUTTON_ICON_NAME,
|
|
19
|
+
BUTTON_NAME,
|
|
20
|
+
BUTTON_TEXT_NAME,
|
|
21
|
+
Button as BaseButton
|
|
22
|
+
} from "./Button";
|
|
23
|
+
const ButtonFrame = styled(BaseButton, {
|
|
24
|
+
name: BUTTON_NAME,
|
|
25
|
+
variants: {
|
|
26
|
+
unstyled: {
|
|
27
|
+
false: {
|
|
28
|
+
size: "$true",
|
|
29
|
+
justifyContent: "center",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
flexWrap: "nowrap",
|
|
32
|
+
flexDirection: "row",
|
|
33
|
+
cursor: "pointer",
|
|
34
|
+
hoverTheme: true,
|
|
35
|
+
pressTheme: true,
|
|
36
|
+
backgrounded: true,
|
|
37
|
+
borderWidth: 1,
|
|
38
|
+
borderColor: "$borderColor",
|
|
39
|
+
pressStyle: {
|
|
40
|
+
borderColor: "$borderColorPress"
|
|
41
|
+
},
|
|
42
|
+
focusStyle: {
|
|
43
|
+
outlineColor: "$borderColorFocus",
|
|
44
|
+
outlineStyle: "solid",
|
|
45
|
+
outlineWidth: 2
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
size: {
|
|
50
|
+
"...size": getButtonSized
|
|
51
|
+
},
|
|
52
|
+
active: {
|
|
53
|
+
true: {
|
|
54
|
+
hoverStyle: {
|
|
55
|
+
backgroundColor: "$background"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
disabled: {
|
|
60
|
+
true: {
|
|
61
|
+
pointerEvents: "none"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
defaultVariants: {
|
|
66
|
+
unstyled: false
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const [createButtonContext, createButtonScope] = createContextScope(BUTTON_NAME);
|
|
70
|
+
const [ButtonProvider, useButtonContext] = createButtonContext("Button");
|
|
71
|
+
const ButtonTextFrame = styled(BaseButton.Text, {
|
|
72
|
+
name: BUTTON_TEXT_NAME,
|
|
73
|
+
variants: {
|
|
74
|
+
unstyled: {
|
|
75
|
+
false: {
|
|
76
|
+
userSelect: "none",
|
|
77
|
+
cursor: "pointer",
|
|
78
|
+
// flexGrow 1 leads to inconsistent native style where text pushes to start of view
|
|
79
|
+
flexGrow: 0,
|
|
80
|
+
flexShrink: 1,
|
|
81
|
+
ellipse: true,
|
|
82
|
+
color: "$color"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
defaultVariants: {
|
|
87
|
+
unstyled: false
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const ButtonText = ButtonTextFrame.styleable(
|
|
91
|
+
(props, ref) => {
|
|
92
|
+
const context = useButtonContext(BUTTON_TEXT_NAME, props.__scopeButton);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const unregister = context.registerButtonText();
|
|
95
|
+
return () => unregister();
|
|
96
|
+
}, [context.registerButtonText]);
|
|
97
|
+
return <ButtonTextFrame ref={ref} color={context.color} size={context.size} {...props}>{props.children}</ButtonTextFrame>;
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
const ButtonIcon = (props) => {
|
|
101
|
+
const { children, scaleIcon = 1 } = props;
|
|
102
|
+
const context = useButtonContext(BUTTON_ICON_NAME, props.__scopeButton);
|
|
103
|
+
const size = context.size;
|
|
104
|
+
const color = context.color;
|
|
105
|
+
const iconSize = (typeof size === "number" ? size * 0.5 : getFontSize(size)) * scaleIcon;
|
|
106
|
+
const getThemedIcon = useGetThemedIcon({ size: iconSize, color });
|
|
107
|
+
return getThemedIcon(children);
|
|
108
|
+
};
|
|
109
|
+
const ButtonComponent = ButtonFrame.styleable(
|
|
110
|
+
(props, ref) => {
|
|
111
|
+
const buttonApi = props.forceButtonApi ?? getConfig().buttonApi ?? "mixed";
|
|
112
|
+
const { props: buttonProps } = useButton(props);
|
|
113
|
+
const [buttonTextCount, setButtonTextCount] = useState(0);
|
|
114
|
+
const registerButtonText = useCallback(() => {
|
|
115
|
+
if (buttonApi === "simple") {
|
|
116
|
+
console.warn(
|
|
117
|
+
"You are using Button.Text with simple button API. Either remove Button.Text or use either `buttonApi: composable` or `mixed` in your tamagui config."
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
if (buttonApi === "composable")
|
|
121
|
+
return () => {
|
|
122
|
+
};
|
|
123
|
+
setButtonTextCount((prev) => prev + 1);
|
|
124
|
+
return () => setButtonTextCount((prev) => prev - 1);
|
|
125
|
+
}, [setButtonTextCount]);
|
|
126
|
+
const usesComposableApi = buttonApi === "composable" || buttonApi === "mixed" && buttonTextCount > 0;
|
|
127
|
+
return <ButtonProvider
|
|
128
|
+
scope={props.__scopeButton}
|
|
129
|
+
size={props.size ?? "$true"}
|
|
130
|
+
color={props.color}
|
|
131
|
+
usesComposableApi={usesComposableApi}
|
|
132
|
+
registerButtonText={registerButtonText}
|
|
133
|
+
><ButtonFrame unstyled={props.unstyled ?? false} ref={ref} {...buttonProps} /></ButtonProvider>;
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
const Button = withStaticProperties(ButtonComponent, {
|
|
137
|
+
Text: ButtonText,
|
|
138
|
+
Icon: ButtonIcon
|
|
139
|
+
});
|
|
140
|
+
function useButton(propsIn, { Text = ButtonTextFrame } = { Text: ButtonTextFrame }) {
|
|
141
|
+
const {
|
|
142
|
+
children,
|
|
143
|
+
icon,
|
|
144
|
+
iconAfter,
|
|
145
|
+
noTextWrap,
|
|
146
|
+
theme: themeName,
|
|
147
|
+
space,
|
|
148
|
+
spaceFlex,
|
|
149
|
+
scaleIcon = 1,
|
|
150
|
+
scaleSpace = 0.66,
|
|
151
|
+
separator,
|
|
152
|
+
// text props
|
|
153
|
+
color,
|
|
154
|
+
fontWeight,
|
|
155
|
+
letterSpacing,
|
|
156
|
+
fontSize,
|
|
157
|
+
fontFamily,
|
|
158
|
+
fontStyle,
|
|
159
|
+
textAlign,
|
|
160
|
+
unstyled = false,
|
|
161
|
+
textProps,
|
|
162
|
+
...rest
|
|
163
|
+
} = propsIn;
|
|
164
|
+
const isNested = isRSC ? false : useContext(ButtonNestingContext);
|
|
165
|
+
const propsActive = useMediaPropsActive(propsIn);
|
|
166
|
+
const size = propsActive.size || "$true";
|
|
167
|
+
const iconSize = (typeof size === "number" ? size * 0.5 : getFontSize(size)) * scaleIcon;
|
|
168
|
+
const getThemedIcon = useGetThemedIcon({ size: iconSize, color });
|
|
169
|
+
const [themedIcon, themedIconAfter] = [icon, iconAfter].map(getThemedIcon);
|
|
170
|
+
const spaceSize = propsActive.space ?? getVariableValue(iconSize) * scaleSpace;
|
|
171
|
+
const contents = wrapChildrenInText(
|
|
172
|
+
Text,
|
|
173
|
+
propsActive,
|
|
174
|
+
Text === ButtonTextFrame ? {
|
|
175
|
+
unstyled
|
|
176
|
+
} : void 0
|
|
177
|
+
);
|
|
178
|
+
const inner = spacedChildren({
|
|
179
|
+
// a bit arbitrary but scaling to font size is necessary so long as button does
|
|
180
|
+
space: spaceSize,
|
|
181
|
+
spaceFlex,
|
|
182
|
+
separator,
|
|
183
|
+
direction: propsActive.flexDirection === "column" || propsActive.flexDirection === "column-reverse" ? "vertical" : "horizontal",
|
|
184
|
+
children: [themedIcon, ...contents, themedIconAfter]
|
|
185
|
+
});
|
|
186
|
+
const tag = isNested ? "span" : (
|
|
187
|
+
// defaults to <a /> when accessibilityRole = link
|
|
188
|
+
// see https://github.com/tamagui/tamagui/issues/505
|
|
189
|
+
propsIn.accessibilityRole === "link" ? "a" : void 0
|
|
190
|
+
);
|
|
191
|
+
const props = {
|
|
192
|
+
...propsActive.disabled && {
|
|
193
|
+
// in rnw - false still has keyboard tabIndex, undefined = not actually focusable
|
|
194
|
+
focusable: void 0,
|
|
195
|
+
// even with tabIndex unset, it will keep focusStyle on web so disable it here
|
|
196
|
+
focusStyle: {
|
|
197
|
+
borderColor: "$background"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
tag,
|
|
201
|
+
...rest,
|
|
202
|
+
children: isRSC ? inner : <ButtonNestingContext.Provider value={true}>{inner}</ButtonNestingContext.Provider>
|
|
203
|
+
};
|
|
204
|
+
return {
|
|
205
|
+
spaceSize,
|
|
206
|
+
isNested,
|
|
207
|
+
props
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const buttonStaticConfig = {
|
|
211
|
+
inlineProps: /* @__PURE__ */ new Set([
|
|
212
|
+
// text props go here (can't really optimize them, but we never fully extract button anyway)
|
|
213
|
+
// may be able to remove this entirely, as the compiler / runtime have gotten better
|
|
214
|
+
"color",
|
|
215
|
+
"fontWeight",
|
|
216
|
+
"fontSize",
|
|
217
|
+
"fontFamily",
|
|
218
|
+
"fontStyle",
|
|
219
|
+
"letterSpacing",
|
|
220
|
+
"textAlign",
|
|
221
|
+
"unstyled"
|
|
222
|
+
])
|
|
223
|
+
};
|
|
224
|
+
export {
|
|
225
|
+
Button,
|
|
226
|
+
ButtonFrame,
|
|
227
|
+
ButtonTextFrame as ButtonText,
|
|
228
|
+
buttonStaticConfig,
|
|
229
|
+
createButtonScope,
|
|
230
|
+
useButton
|
|
231
|
+
};
|
|
232
|
+
//# sourceMappingURL=themed.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/themed.tsx"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/themed.tsx"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/button",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.0-1684163004699",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"*.css"
|
|
6
6
|
],
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@tamagui/font-size": "1.
|
|
33
|
-
"@tamagui/get-button-sized": "1.
|
|
34
|
-
"@tamagui/helpers-tamagui": "1.
|
|
35
|
-
"@tamagui/text": "1.
|
|
36
|
-
"@tamagui/web": "1.
|
|
32
|
+
"@tamagui/font-size": "1.27.0-1684163004699",
|
|
33
|
+
"@tamagui/get-button-sized": "1.27.0-1684163004699",
|
|
34
|
+
"@tamagui/helpers-tamagui": "1.27.0-1684163004699",
|
|
35
|
+
"@tamagui/text": "1.27.0-1684163004699",
|
|
36
|
+
"@tamagui/web": "1.27.0-1684163004699"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"react": "*"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@tamagui/build": "1.
|
|
42
|
+
"@tamagui/build": "1.27.0-1684163004699",
|
|
43
43
|
"react": "^18.2.0",
|
|
44
44
|
"vitest": "^0.26.3"
|
|
45
45
|
},
|
package/src/Button.test.tsx
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
process.env.TAMAGUI_TARGET = 'web'
|
|
2
2
|
|
|
3
3
|
import { getDefaultTamaguiConfig } from '@tamagui/config-default'
|
|
4
|
-
import {
|
|
5
|
-
import { render } from '@testing-library/react'
|
|
4
|
+
import { createTamagui } from '@tamagui/core'
|
|
6
5
|
import { describe, expect, test } from 'vitest'
|
|
7
6
|
|
|
8
|
-
import { Button } from '.'
|
|
9
|
-
|
|
10
7
|
const conf = createTamagui(getDefaultTamaguiConfig())
|
|
11
8
|
|
|
12
9
|
describe('Button', () => {
|
package/src/Button.tsx
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import type { Scope } from '@tamagui/create-context'
|
|
2
|
-
import { createContextScope } from '@tamagui/create-context'
|
|
3
1
|
import { getFontSize } from '@tamagui/font-size'
|
|
4
2
|
import { getButtonSized } from '@tamagui/get-button-sized'
|
|
5
|
-
import {
|
|
3
|
+
import { useGetThemedIcon } from '@tamagui/helpers-tamagui'
|
|
6
4
|
import { ThemeableStack } from '@tamagui/stacks'
|
|
7
5
|
import { SizableText, TextParentStyles, wrapChildrenInText } from '@tamagui/text'
|
|
8
6
|
import {
|
|
9
7
|
ButtonNestingContext,
|
|
8
|
+
ColorStyleProp,
|
|
10
9
|
GetProps,
|
|
11
10
|
SizeTokens,
|
|
12
|
-
TamaguiElement,
|
|
13
11
|
ThemeableProps,
|
|
12
|
+
createStyledContext,
|
|
14
13
|
getVariableValue,
|
|
15
14
|
isRSC,
|
|
16
15
|
spacedChildren,
|
|
@@ -18,14 +17,14 @@ import {
|
|
|
18
17
|
useProps,
|
|
19
18
|
withStaticProperties,
|
|
20
19
|
} from '@tamagui/web'
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
20
|
+
import { FunctionComponent, useContext } from 'react'
|
|
21
|
+
|
|
22
|
+
export const ButtonContext = createStyledContext<{
|
|
23
|
+
size: SizeTokens
|
|
24
|
+
color?: ColorStyleProp
|
|
25
|
+
}>({
|
|
26
|
+
size: '$true',
|
|
27
|
+
})
|
|
29
28
|
|
|
30
29
|
type ButtonIconProps = { color?: string; size?: number }
|
|
31
30
|
type IconProp = JSX.Element | FunctionComponent<ButtonIconProps> | null
|
|
@@ -66,6 +65,7 @@ const BUTTON_NAME = 'Button'
|
|
|
66
65
|
const ButtonFrame = styled(ThemeableStack, {
|
|
67
66
|
name: BUTTON_NAME,
|
|
68
67
|
tag: 'button',
|
|
68
|
+
context: ButtonContext,
|
|
69
69
|
focusable: true,
|
|
70
70
|
|
|
71
71
|
variants: {
|
|
@@ -119,9 +119,9 @@ const ButtonFrame = styled(ThemeableStack, {
|
|
|
119
119
|
},
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
const ButtonText = styled(SizableText, {
|
|
123
|
+
name: 'ButtonText',
|
|
124
|
+
context: ButtonContext,
|
|
125
125
|
|
|
126
126
|
variants: {
|
|
127
127
|
unstyled: {
|
|
@@ -142,82 +142,22 @@ const ButtonTextFrame = styled(SizableText, {
|
|
|
142
142
|
},
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
const [createButtonContext, createButtonScope] = createContextScope('Button')
|
|
147
|
-
|
|
148
|
-
type ButtonContextValue = {
|
|
149
|
-
size: SizeTokens
|
|
150
|
-
color: ColorProp
|
|
151
|
-
|
|
152
|
-
// used to keep backward compat with the new Button.Text api
|
|
153
|
-
hasTextComponent: boolean
|
|
154
|
-
registerButtonText: () => () => void
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const [ButtonProvider, useButtonContext] =
|
|
158
|
-
createButtonContext<ButtonContextValue>('Button')
|
|
159
|
-
|
|
160
|
-
const ButtonTextComponent = ButtonTextFrame.extractable(
|
|
161
|
-
forwardRef<TamaguiElement, ScopedProps<GetProps<typeof ButtonTextFrame>>>(
|
|
162
|
-
(props, ref) => {
|
|
163
|
-
const context = useButtonContext(BUTTON_TEXT_NAME, props.__scopeButton)
|
|
164
|
-
|
|
165
|
-
useEffect(() => {
|
|
166
|
-
const unregister = context.registerButtonText()
|
|
167
|
-
return () => unregister()
|
|
168
|
-
}, [context.registerButtonText])
|
|
169
|
-
|
|
170
|
-
return <ButtonTextFrame size={props.size ?? context.size} {...props} ref={ref} />
|
|
171
|
-
}
|
|
172
|
-
)
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
const BUTTON_ICON_NAME = 'ButtonIcon'
|
|
176
|
-
|
|
177
|
-
const ButtonIcon = (
|
|
178
|
-
props: ScopedProps<{
|
|
179
|
-
children: React.ReactNode
|
|
180
|
-
scaleIcon?: number
|
|
181
|
-
}>
|
|
182
|
-
) => {
|
|
145
|
+
const ButtonIcon = (props: { children: React.ReactNode; scaleIcon?: number }) => {
|
|
183
146
|
const { children, scaleIcon = 1 } = props
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
const size = context.size
|
|
187
|
-
const color = context.color
|
|
188
|
-
|
|
147
|
+
const { size, color } = useContext(ButtonContext)
|
|
189
148
|
const iconSize = (typeof size === 'number' ? size * 0.5 : getFontSize(size)) * scaleIcon
|
|
190
149
|
const getThemedIcon = useGetThemedIcon({ size: iconSize, color })
|
|
191
150
|
return getThemedIcon(children)
|
|
192
151
|
}
|
|
193
152
|
|
|
194
|
-
const ButtonComponent = ButtonFrame.styleable<
|
|
195
|
-
props,
|
|
196
|
-
ref
|
|
197
|
-
) {
|
|
153
|
+
const ButtonComponent = ButtonFrame.styleable<ButtonProps>(function Button(props, ref) {
|
|
198
154
|
const { props: buttonProps } = useButton(props)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const registerButtonText = useCallback(() => {
|
|
202
|
-
setButtonTextCount((prev) => prev + 1)
|
|
203
|
-
return () => setButtonTextCount((prev) => prev - 1)
|
|
204
|
-
}, [setButtonTextCount])
|
|
205
|
-
|
|
206
|
-
const hasTextComponent = buttonTextCount > 0
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
<ButtonProvider
|
|
210
|
-
scope={props.__scopeButton}
|
|
211
|
-
color={props.color}
|
|
212
|
-
hasTextComponent={hasTextComponent}
|
|
213
|
-
size={props.size ?? '$true'}
|
|
214
|
-
registerButtonText={registerButtonText}
|
|
215
|
-
>
|
|
216
|
-
<ButtonFrame {...(hasTextComponent ? props : buttonProps)} ref={ref} />
|
|
217
|
-
</ButtonProvider>
|
|
218
|
-
)
|
|
155
|
+
return <ButtonFrame {...buttonProps} ref={ref} />
|
|
219
156
|
})
|
|
220
157
|
|
|
158
|
+
/**
|
|
159
|
+
* @deprecated Instead of useButton, see the Button docs for the newer and much improved Advanced customization pattern: https://tamagui.dev/docs/components/button
|
|
160
|
+
*/
|
|
221
161
|
const buttonStaticConfig = {
|
|
222
162
|
inlineProps: new Set([
|
|
223
163
|
// text props go here (can't really optimize them, but we never fully extract button anyway)
|
|
@@ -234,13 +174,16 @@ const buttonStaticConfig = {
|
|
|
234
174
|
}
|
|
235
175
|
|
|
236
176
|
const Button = withStaticProperties(ButtonComponent, {
|
|
237
|
-
Text:
|
|
177
|
+
Text: ButtonText,
|
|
238
178
|
Icon: ButtonIcon,
|
|
239
179
|
})
|
|
240
180
|
|
|
181
|
+
/**
|
|
182
|
+
* @deprecated Instead of useButton, see the Button docs for the newer and much improved Advanced customization pattern: https://tamagui.dev/docs/components/button
|
|
183
|
+
*/
|
|
241
184
|
function useButton(
|
|
242
185
|
propsIn: ButtonProps,
|
|
243
|
-
{ Text =
|
|
186
|
+
{ Text = ButtonText }: { Text: any } = { Text: ButtonText }
|
|
244
187
|
) {
|
|
245
188
|
// careful not to desctructure and re-order props, order is important
|
|
246
189
|
const {
|
|
@@ -279,12 +222,13 @@ function useButton(
|
|
|
279
222
|
const contents = wrapChildrenInText(
|
|
280
223
|
Text,
|
|
281
224
|
propsActive,
|
|
282
|
-
Text ===
|
|
225
|
+
Text === ButtonText && hasUnstyled
|
|
283
226
|
? {
|
|
284
227
|
unstyled: propsIn.unstyled,
|
|
285
228
|
}
|
|
286
229
|
: undefined
|
|
287
230
|
)
|
|
231
|
+
|
|
288
232
|
const inner = spacedChildren({
|
|
289
233
|
// a bit arbitrary but scaling to font size is necessary so long as button does
|
|
290
234
|
space: spaceSize,
|
|
@@ -333,14 +277,13 @@ function useButton(
|
|
|
333
277
|
}
|
|
334
278
|
|
|
335
279
|
export {
|
|
336
|
-
createButtonScope,
|
|
337
280
|
Button,
|
|
281
|
+
ButtonFrame,
|
|
282
|
+
ButtonText,
|
|
283
|
+
ButtonIcon,
|
|
338
284
|
|
|
339
|
-
// legacy
|
|
285
|
+
// legacy
|
|
340
286
|
useButton,
|
|
341
287
|
buttonStaticConfig,
|
|
342
|
-
ButtonFrame,
|
|
343
|
-
ButtonTextFrame as ButtonText,
|
|
344
288
|
}
|
|
345
|
-
|
|
346
289
|
export type { ButtonProps }
|