@tamagui/button 1.26.0 → 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 +19 -51
- 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 +19 -57
- 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 +19 -53
- package/dist/jsx/Button.js.map +1 -1
- package/dist/jsx/Button.mjs +19 -53
- 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 +35 -97
- 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: {
|
|
@@ -81,18 +81,13 @@ const ButtonFrame = styled(ThemeableStack, {
|
|
|
81
81
|
pressTheme: true,
|
|
82
82
|
backgrounded: true,
|
|
83
83
|
borderWidth: 1,
|
|
84
|
-
borderColor: '
|
|
84
|
+
borderColor: '$borderColor',
|
|
85
85
|
|
|
86
86
|
pressStyle: {
|
|
87
|
-
borderColor: '
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
hoverStyle: {
|
|
91
|
-
borderColor: 'transparent',
|
|
87
|
+
borderColor: '$borderColorPress',
|
|
92
88
|
},
|
|
93
89
|
|
|
94
90
|
focusStyle: {
|
|
95
|
-
borderColor: '$borderColorFocus',
|
|
96
91
|
outlineColor: '$borderColorFocus',
|
|
97
92
|
outlineStyle: 'solid',
|
|
98
93
|
outlineWidth: 2,
|
|
@@ -124,9 +119,9 @@ const ButtonFrame = styled(ThemeableStack, {
|
|
|
124
119
|
},
|
|
125
120
|
})
|
|
126
121
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
const ButtonText = styled(SizableText, {
|
|
123
|
+
name: 'ButtonText',
|
|
124
|
+
context: ButtonContext,
|
|
130
125
|
|
|
131
126
|
variants: {
|
|
132
127
|
unstyled: {
|
|
@@ -147,82 +142,22 @@ const ButtonTextFrame = styled(SizableText, {
|
|
|
147
142
|
},
|
|
148
143
|
})
|
|
149
144
|
|
|
150
|
-
|
|
151
|
-
const [createButtonContext, createButtonScope] = createContextScope('Button')
|
|
152
|
-
|
|
153
|
-
type ButtonContextValue = {
|
|
154
|
-
size: SizeTokens
|
|
155
|
-
color: ColorProp
|
|
156
|
-
|
|
157
|
-
// used to keep backward compat with the new Button.Text api
|
|
158
|
-
hasTextComponent: boolean
|
|
159
|
-
registerButtonText: () => () => void
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const [ButtonProvider, useButtonContext] =
|
|
163
|
-
createButtonContext<ButtonContextValue>('Button')
|
|
164
|
-
|
|
165
|
-
const ButtonTextComponent = ButtonTextFrame.extractable(
|
|
166
|
-
forwardRef<TamaguiElement, ScopedProps<GetProps<typeof ButtonTextFrame>>>(
|
|
167
|
-
(props, ref) => {
|
|
168
|
-
const context = useButtonContext(BUTTON_TEXT_NAME, props.__scopeButton)
|
|
169
|
-
|
|
170
|
-
useEffect(() => {
|
|
171
|
-
const unregister = context.registerButtonText()
|
|
172
|
-
return () => unregister()
|
|
173
|
-
}, [context.registerButtonText])
|
|
174
|
-
|
|
175
|
-
return <ButtonTextFrame size={props.size ?? context.size} {...props} ref={ref} />
|
|
176
|
-
}
|
|
177
|
-
)
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
const BUTTON_ICON_NAME = 'ButtonIcon'
|
|
181
|
-
|
|
182
|
-
const ButtonIcon = (
|
|
183
|
-
props: ScopedProps<{
|
|
184
|
-
children: React.ReactNode
|
|
185
|
-
scaleIcon?: number
|
|
186
|
-
}>
|
|
187
|
-
) => {
|
|
145
|
+
const ButtonIcon = (props: { children: React.ReactNode; scaleIcon?: number }) => {
|
|
188
146
|
const { children, scaleIcon = 1 } = props
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
const size = context.size
|
|
192
|
-
const color = context.color
|
|
193
|
-
|
|
147
|
+
const { size, color } = useContext(ButtonContext)
|
|
194
148
|
const iconSize = (typeof size === 'number' ? size * 0.5 : getFontSize(size)) * scaleIcon
|
|
195
149
|
const getThemedIcon = useGetThemedIcon({ size: iconSize, color })
|
|
196
150
|
return getThemedIcon(children)
|
|
197
151
|
}
|
|
198
152
|
|
|
199
|
-
const ButtonComponent = ButtonFrame.styleable<
|
|
200
|
-
props,
|
|
201
|
-
ref
|
|
202
|
-
) {
|
|
153
|
+
const ButtonComponent = ButtonFrame.styleable<ButtonProps>(function Button(props, ref) {
|
|
203
154
|
const { props: buttonProps } = useButton(props)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const registerButtonText = useCallback(() => {
|
|
207
|
-
setButtonTextCount((prev) => prev + 1)
|
|
208
|
-
return () => setButtonTextCount((prev) => prev - 1)
|
|
209
|
-
}, [setButtonTextCount])
|
|
210
|
-
|
|
211
|
-
const hasTextComponent = buttonTextCount > 0
|
|
212
|
-
|
|
213
|
-
return (
|
|
214
|
-
<ButtonProvider
|
|
215
|
-
scope={props.__scopeButton}
|
|
216
|
-
color={props.color}
|
|
217
|
-
hasTextComponent={hasTextComponent}
|
|
218
|
-
size={props.size ?? '$true'}
|
|
219
|
-
registerButtonText={registerButtonText}
|
|
220
|
-
>
|
|
221
|
-
<ButtonFrame {...(hasTextComponent ? props : buttonProps)} ref={ref} />
|
|
222
|
-
</ButtonProvider>
|
|
223
|
-
)
|
|
155
|
+
return <ButtonFrame {...buttonProps} ref={ref} />
|
|
224
156
|
})
|
|
225
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
|
+
*/
|
|
226
161
|
const buttonStaticConfig = {
|
|
227
162
|
inlineProps: new Set([
|
|
228
163
|
// text props go here (can't really optimize them, but we never fully extract button anyway)
|
|
@@ -239,13 +174,16 @@ const buttonStaticConfig = {
|
|
|
239
174
|
}
|
|
240
175
|
|
|
241
176
|
const Button = withStaticProperties(ButtonComponent, {
|
|
242
|
-
Text:
|
|
177
|
+
Text: ButtonText,
|
|
243
178
|
Icon: ButtonIcon,
|
|
244
179
|
})
|
|
245
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
|
+
*/
|
|
246
184
|
function useButton(
|
|
247
185
|
propsIn: ButtonProps,
|
|
248
|
-
{ Text =
|
|
186
|
+
{ Text = ButtonText }: { Text: any } = { Text: ButtonText }
|
|
249
187
|
) {
|
|
250
188
|
// careful not to desctructure and re-order props, order is important
|
|
251
189
|
const {
|
|
@@ -284,12 +222,13 @@ function useButton(
|
|
|
284
222
|
const contents = wrapChildrenInText(
|
|
285
223
|
Text,
|
|
286
224
|
propsActive,
|
|
287
|
-
Text ===
|
|
225
|
+
Text === ButtonText && hasUnstyled
|
|
288
226
|
? {
|
|
289
227
|
unstyled: propsIn.unstyled,
|
|
290
228
|
}
|
|
291
229
|
: undefined
|
|
292
230
|
)
|
|
231
|
+
|
|
293
232
|
const inner = spacedChildren({
|
|
294
233
|
// a bit arbitrary but scaling to font size is necessary so long as button does
|
|
295
234
|
space: spaceSize,
|
|
@@ -338,14 +277,13 @@ function useButton(
|
|
|
338
277
|
}
|
|
339
278
|
|
|
340
279
|
export {
|
|
341
|
-
createButtonScope,
|
|
342
280
|
Button,
|
|
281
|
+
ButtonFrame,
|
|
282
|
+
ButtonText,
|
|
283
|
+
ButtonIcon,
|
|
343
284
|
|
|
344
|
-
// legacy
|
|
285
|
+
// legacy
|
|
345
286
|
useButton,
|
|
346
287
|
buttonStaticConfig,
|
|
347
|
-
ButtonFrame,
|
|
348
|
-
ButtonTextFrame as ButtonText,
|
|
349
288
|
}
|
|
350
|
-
|
|
351
289
|
export type { ButtonProps }
|