@tamagui/button 2.7.7 → 3.0.0-beta.643.1
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.cjs +180 -266
- package/dist/cjs/Button.native.cjs +224 -0
- package/dist/cjs/Button.native.js +200 -271
- package/dist/cjs/Button.native.js.map +1 -1
- package/dist/cjs/index.cjs +10 -11
- package/dist/cjs/index.native.cjs +21 -0
- package/dist/cjs/index.native.js +10 -10
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/Button.mjs +168 -255
- package/dist/esm/Button.mjs.map +1 -1
- package/dist/esm/Button.native.js +188 -261
- package/dist/esm/Button.native.js.map +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.mjs +1 -2
- package/dist/esm/index.native.js +1 -2
- package/dist/jsx/Button.mjs +168 -255
- package/dist/jsx/Button.mjs.map +1 -1
- package/dist/jsx/Button.native.cjs +224 -0
- package/dist/jsx/Button.native.js +200 -271
- package/dist/jsx/Button.native.js.map +1 -1
- package/dist/jsx/index.js +1 -2
- package/dist/jsx/index.mjs +1 -2
- package/dist/jsx/index.native.cjs +21 -0
- package/dist/jsx/index.native.js +10 -10
- package/dist/jsx/index.native.js.map +1 -1
- package/package.json +11 -12
- package/src/Button.tsx +222 -280
- package/types/Button.d.ts +218 -114
- package/types/Button.d.ts.map +1 -1
- package/dist/cjs/Button.test.cjs +0 -37
- package/dist/cjs/Button.test.native.js +0 -40
- package/dist/cjs/Button.test.native.js.map +0 -1
- package/dist/esm/Button.test.mjs +0 -38
- package/dist/esm/Button.test.mjs.map +0 -1
- package/dist/esm/Button.test.native.js +0 -38
- package/dist/esm/Button.test.native.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/dist/jsx/Button.test.mjs +0 -38
- package/dist/jsx/Button.test.mjs.map +0 -1
- package/dist/jsx/Button.test.native.js +0 -40
- package/dist/jsx/Button.test.native.js.map +0 -1
- package/dist/jsx/index.js.map +0 -1
- package/dist/jsx/index.mjs.map +0 -1
- package/src/Button.test.tsx +0 -45
- package/types/Button.test.d.ts +0 -2
- package/types/Button.test.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"index.native.js","names":[],"sources":["jsx/index.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, \"default\"), secondTarget && __copyProps(secondTarget, mod, \"default\"));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar index_exports = {};\nmodule.exports = __toCommonJS(index_exports);\n__reExport(index_exports, require(\"./Button\"), module.exports);\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;;AACA,IAAI,YAAY,OAAO;AACvB,IAAI,mBAAmB,OAAO;AAC9B,IAAI,oBAAoB,OAAO;AAC/B,IAAI,eAAe,OAAO,UAAU;AACpC,IAAI,eAAe,IAAI,MAAM,QAAQ,SAAS;CAC5C,IAAI,QAAQ,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY;EAClE,KAAK,IAAI,OAAO,kBAAkB,IAAI,GACpC,IAAI,CAAC,aAAa,KAAK,IAAI,GAAG,KAAK,QAAQ,QACzC,UAAU,IAAI,KAAK;GAAE,WAAW,KAAK;GAAM,YAAY,EAAE,OAAO,iBAAiB,MAAM,GAAG,MAAM,KAAK;EAAW,CAAC;CACvH;CACA,OAAO;AACT;AACA,IAAI,cAAc,QAAQ,KAAK,kBAAkB,YAAY,QAAQ,KAAK,SAAS,GAAG,gBAAgB,YAAY,cAAc,KAAK,SAAS;AAC9I,IAAI,gBAAgB,QAAQ,YAAY,UAAU,CAAC,GAAG,cAAc,EAAE,OAAO,KAAK,CAAC,GAAG,GAAG;AACzF,IAAI,gBAAgB,CAAC;AACrB,OAAO,UAAU,aAAa,aAAa;AAC3C,WAAW,eAAe,QAAQ,oBAAU,GAAG,OAAO,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/button",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.643.1",
|
|
4
4
|
"gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"files": [
|
|
@@ -35,19 +35,18 @@
|
|
|
35
35
|
"clean:build": "tamagui-build clean:build"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@tamagui/config-default": "
|
|
39
|
-
"@tamagui/core": "
|
|
40
|
-
"@tamagui/
|
|
41
|
-
"@tamagui/helpers": "
|
|
42
|
-
"@tamagui/
|
|
43
|
-
"@tamagui/
|
|
44
|
-
"@tamagui/
|
|
45
|
-
"@tamagui/
|
|
46
|
-
"@tamagui/
|
|
47
|
-
"@tamagui/web": "2.7.7"
|
|
38
|
+
"@tamagui/config-default": "3.0.0-beta.643.1",
|
|
39
|
+
"@tamagui/core": "3.0.0-beta.643.1",
|
|
40
|
+
"@tamagui/helpers": "3.0.0-beta.643.1",
|
|
41
|
+
"@tamagui/helpers-tamagui": "3.0.0-beta.643.1",
|
|
42
|
+
"@tamagui/spacer": "3.0.0-beta.643.1",
|
|
43
|
+
"@tamagui/stacks": "3.0.0-beta.643.1",
|
|
44
|
+
"@tamagui/text": "3.0.0-beta.643.1",
|
|
45
|
+
"@tamagui/font-size": "3.0.0-beta.643.1",
|
|
46
|
+
"@tamagui/web": "3.0.0-beta.643.1"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
|
-
"@tamagui/build": "
|
|
49
|
+
"@tamagui/build": "3.0.0-beta.643.1",
|
|
51
50
|
"react": ">=19",
|
|
52
51
|
"vitest": "4.0.4"
|
|
53
52
|
},
|
package/src/Button.tsx
CHANGED
|
@@ -1,224 +1,109 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { getIcon, useCurrentColor } from '@tamagui/helpers-tamagui'
|
|
4
|
-
import { ButtonNestingContext, getElevation, themeableVariants } from '@tamagui/stacks'
|
|
1
|
+
import { useGetThemedIcon } from '@tamagui/helpers-tamagui'
|
|
2
|
+
import { ButtonNestingContext } from '@tamagui/stacks'
|
|
5
3
|
import type { TextContextStyles, TextParentStyles } from '@tamagui/text'
|
|
6
|
-
import {
|
|
7
|
-
import type { GetProps
|
|
4
|
+
import { wrapChildrenInText } from '@tamagui/text'
|
|
5
|
+
import type { GetProps } from '@tamagui/web'
|
|
8
6
|
import {
|
|
9
7
|
createStyledContext,
|
|
10
|
-
|
|
8
|
+
createStyledHOC,
|
|
11
9
|
styled,
|
|
10
|
+
Text,
|
|
12
11
|
useProps,
|
|
13
12
|
View,
|
|
14
13
|
withStaticProperties,
|
|
15
14
|
} from '@tamagui/web'
|
|
16
|
-
import type { FunctionComponent, JSX } from 'react'
|
|
15
|
+
import type { FunctionComponent, JSX, ReactNode } from 'react'
|
|
17
16
|
import { useContext } from 'react'
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
18
|
+
const buttonContextKeys = [
|
|
19
|
+
'color',
|
|
20
|
+
'ellipsis',
|
|
21
|
+
'fontFamily',
|
|
22
|
+
'fontSize',
|
|
23
|
+
'fontStyle',
|
|
24
|
+
'fontWeight',
|
|
25
|
+
'letterSpacing',
|
|
26
|
+
'maxFontSizeMultiplier',
|
|
27
|
+
'textAlign',
|
|
28
|
+
] as const
|
|
29
|
+
|
|
30
|
+
export const ButtonContext = createStyledContext<
|
|
31
|
+
TextContextStyles,
|
|
32
|
+
(typeof buttonContextKeys)[number]
|
|
33
|
+
>(
|
|
34
|
+
{
|
|
35
|
+
color: undefined,
|
|
36
|
+
ellipsis: undefined,
|
|
37
|
+
fontFamily: undefined,
|
|
38
|
+
fontSize: undefined,
|
|
39
|
+
fontStyle: undefined,
|
|
40
|
+
fontWeight: undefined,
|
|
41
|
+
letterSpacing: undefined,
|
|
42
|
+
maxFontSizeMultiplier: undefined,
|
|
43
|
+
textAlign: undefined,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
keys: buttonContextKeys,
|
|
47
|
+
}
|
|
48
|
+
)
|
|
41
49
|
|
|
42
|
-
const
|
|
43
|
-
context,
|
|
44
|
-
|
|
50
|
+
export const ButtonFrame = styled(View, {
|
|
51
|
+
context: ButtonContext,
|
|
52
|
+
displayName: 'ButtonFrame',
|
|
45
53
|
role: 'button',
|
|
46
54
|
render: <button type="button" />,
|
|
47
55
|
tabIndex: 0,
|
|
56
|
+
alignItems: 'center',
|
|
57
|
+
flexDirection: 'row',
|
|
58
|
+
flexWrap: 'nowrap',
|
|
59
|
+
justifyContent: 'center',
|
|
48
60
|
|
|
49
61
|
variants: {
|
|
50
|
-
unstyled: {
|
|
51
|
-
true: {
|
|
52
|
-
// reset browser <button> defaults
|
|
53
|
-
outlineWidth: 0,
|
|
54
|
-
borderWidth: 0,
|
|
55
|
-
backgroundColor: 'transparent',
|
|
56
|
-
},
|
|
57
|
-
false: {
|
|
58
|
-
size: '$true',
|
|
59
|
-
justifyContent: 'center',
|
|
60
|
-
alignItems: 'center',
|
|
61
|
-
flexWrap: 'nowrap',
|
|
62
|
-
flexDirection: 'row',
|
|
63
|
-
backgroundColor: '$background',
|
|
64
|
-
borderWidth: 1,
|
|
65
|
-
borderColor: 'transparent',
|
|
66
|
-
|
|
67
|
-
'$platform-web': {
|
|
68
|
-
cursor: 'pointer',
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
hoverStyle: {
|
|
72
|
-
backgroundColor: '$backgroundHover',
|
|
73
|
-
borderColor: '$borderColorHover',
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
pressStyle: {
|
|
77
|
-
backgroundColor: '$backgroundPress',
|
|
78
|
-
borderColor: '$borderColorHover',
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
focusVisibleStyle: {
|
|
82
|
-
outlineColor: '$outlineColor',
|
|
83
|
-
outlineStyle: 'solid',
|
|
84
|
-
outlineWidth: 2,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
variant: {
|
|
90
|
-
outlined:
|
|
91
|
-
process.env.TAMAGUI_HEADLESS === '1'
|
|
92
|
-
? {}
|
|
93
|
-
: {
|
|
94
|
-
backgroundColor: 'transparent',
|
|
95
|
-
borderWidth: 1,
|
|
96
|
-
borderColor: '$borderColor',
|
|
97
|
-
|
|
98
|
-
hoverStyle: {
|
|
99
|
-
backgroundColor: 'transparent',
|
|
100
|
-
borderColor: '$borderColorHover',
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
pressStyle: {
|
|
104
|
-
backgroundColor: 'transparent',
|
|
105
|
-
borderColor: '$borderColorPress',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
circular: themeableVariants.circular,
|
|
111
|
-
|
|
112
|
-
chromeless: themeableVariants.chromeless,
|
|
113
|
-
|
|
114
|
-
size: {
|
|
115
|
-
'...size': (val, extras) => {
|
|
116
|
-
const buttonStyle = getButtonSized(val, extras)
|
|
117
|
-
const gap = getTokenValue(val as Token)
|
|
118
|
-
return {
|
|
119
|
-
...buttonStyle,
|
|
120
|
-
gap,
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
':number': (val, extras) => {
|
|
124
|
-
const buttonStyle = getButtonSized(val, extras)
|
|
125
|
-
const gap = val * 0.4
|
|
126
|
-
return {
|
|
127
|
-
...buttonStyle,
|
|
128
|
-
gap,
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
elevation: {
|
|
134
|
-
'...size': getElevation,
|
|
135
|
-
':number': getElevation,
|
|
136
|
-
},
|
|
137
|
-
|
|
138
62
|
disabled: {
|
|
139
63
|
true: {
|
|
140
64
|
pointerEvents: 'none',
|
|
141
|
-
// @ts-ignore
|
|
142
|
-
'aria-disabled': true,
|
|
143
65
|
},
|
|
144
66
|
},
|
|
145
67
|
} as const,
|
|
146
|
-
|
|
147
|
-
defaultVariants: {
|
|
148
|
-
unstyled: process.env.TAMAGUI_HEADLESS === '1',
|
|
149
|
-
},
|
|
150
68
|
})
|
|
151
69
|
|
|
152
|
-
const
|
|
153
|
-
context,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
userSelect: 'none',
|
|
159
|
-
// flexGrow 1 leads to inconsistent native style where text pushes to start of view
|
|
160
|
-
flexGrow: 0,
|
|
161
|
-
flexShrink: 1,
|
|
162
|
-
ellipsis: true,
|
|
163
|
-
color: '$color',
|
|
164
|
-
|
|
165
|
-
'$platform-web': {
|
|
166
|
-
cursor: 'pointer',
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
} as const,
|
|
171
|
-
|
|
172
|
-
defaultVariants: {
|
|
173
|
-
unstyled: process.env.TAMAGUI_HEADLESS === '1',
|
|
174
|
-
},
|
|
70
|
+
export const ButtonText = styled(Text, {
|
|
71
|
+
context: ButtonContext,
|
|
72
|
+
displayName: 'ButtonText',
|
|
73
|
+
// flexGrow 1 pushes text to the start of its parent on native
|
|
74
|
+
flexGrow: 0,
|
|
75
|
+
flexShrink: 1,
|
|
175
76
|
})
|
|
176
77
|
|
|
177
|
-
|
|
178
|
-
children:
|
|
78
|
+
export type ButtonIconProps = {
|
|
79
|
+
children: ReactNode
|
|
80
|
+
color?: TextContextStyles['color']
|
|
179
81
|
scaleIcon?: number
|
|
180
|
-
size?:
|
|
181
|
-
}
|
|
182
|
-
const { children, scaleIcon = 1, size } = props
|
|
183
|
-
const styledContext = context.useStyledContext()
|
|
184
|
-
if (!styledContext) {
|
|
185
|
-
throw new Error('Button.Icon must be used within a Button')
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const sizeToken = size ?? styledContext.size
|
|
189
|
-
const iconColorProp =
|
|
190
|
-
styledContext.color === 'unset' || typeof styledContext.color === 'number'
|
|
191
|
-
? undefined
|
|
192
|
-
: styledContext.color
|
|
193
|
-
const iconColor = useCurrentColor(iconColorProp)
|
|
194
|
-
|
|
195
|
-
const iconSize =
|
|
196
|
-
(typeof sizeToken === 'number' ? sizeToken * 0.5 : getFontSize(sizeToken as Token)) *
|
|
197
|
-
scaleIcon
|
|
82
|
+
size?: number
|
|
83
|
+
}
|
|
198
84
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
85
|
+
export const ButtonIcon = ({ children, color, scaleIcon = 1, size }: ButtonIconProps) => {
|
|
86
|
+
const styledContext = ButtonContext.useStyledContext()
|
|
87
|
+
const iconColor = color ?? styledContext?.color
|
|
88
|
+
const getThemedIcon = useGetThemedIcon({
|
|
89
|
+
color: iconColor === 'unset' || typeof iconColor === 'number' ? undefined : iconColor,
|
|
90
|
+
size: size === undefined ? undefined : size * scaleIcon,
|
|
202
91
|
})
|
|
203
|
-
}
|
|
204
92
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
variant?: ButtonVariant
|
|
208
|
-
color?: ButtonContextStyles['color']
|
|
209
|
-
}>({
|
|
210
|
-
size: undefined,
|
|
211
|
-
variant: undefined,
|
|
212
|
-
color: undefined,
|
|
213
|
-
})
|
|
93
|
+
return getThemedIcon(children)
|
|
94
|
+
}
|
|
214
95
|
|
|
215
|
-
type
|
|
96
|
+
type ButtonIconInput =
|
|
97
|
+
| JSX.Element
|
|
98
|
+
| FunctionComponent<{ color?: any; size?: any }>
|
|
99
|
+
| ((props: { color?: any; size?: any }) => ReactNode)
|
|
100
|
+
| null
|
|
216
101
|
|
|
217
|
-
type
|
|
218
|
-
icon?:
|
|
219
|
-
iconAfter?:
|
|
102
|
+
export type ButtonBehaviorProps = TextParentStyles & {
|
|
103
|
+
icon?: ButtonIconInput
|
|
104
|
+
iconAfter?: ButtonIconInput
|
|
105
|
+
iconSize?: number
|
|
220
106
|
scaleIcon?: number
|
|
221
|
-
iconSize?: SizeTokens
|
|
222
107
|
|
|
223
108
|
// native button html props
|
|
224
109
|
type?: 'submit' | 'reset' | 'button'
|
|
@@ -232,132 +117,189 @@ type ButtonExtraProps = TextParentStyles & {
|
|
|
232
117
|
value?: string | readonly string[] | number
|
|
233
118
|
}
|
|
234
119
|
|
|
235
|
-
|
|
236
|
-
|
|
120
|
+
export type UseButtonOptions = {
|
|
121
|
+
Text?: any
|
|
122
|
+
iconColor?: TextContextStyles['color']
|
|
123
|
+
iconSize?: number
|
|
124
|
+
textProps?: Record<string, unknown>
|
|
125
|
+
}
|
|
237
126
|
|
|
238
|
-
|
|
127
|
+
const buttonInternalPropNames = [
|
|
128
|
+
'children',
|
|
129
|
+
'color',
|
|
130
|
+
'disabled',
|
|
131
|
+
'ellipsis',
|
|
132
|
+
'fontFamily',
|
|
133
|
+
'fontSize',
|
|
134
|
+
'fontStyle',
|
|
135
|
+
'fontWeight',
|
|
136
|
+
'icon',
|
|
137
|
+
'iconAfter',
|
|
138
|
+
'iconSize',
|
|
139
|
+
'letterSpacing',
|
|
140
|
+
'maxFontSizeMultiplier',
|
|
141
|
+
'noTextWrap',
|
|
142
|
+
'render',
|
|
143
|
+
'scaleIcon',
|
|
144
|
+
'textAlign',
|
|
145
|
+
'textProps',
|
|
146
|
+
] as const
|
|
147
|
+
|
|
148
|
+
export function useButton<Props extends ButtonBehaviorProps>(
|
|
149
|
+
propsIn: Props,
|
|
150
|
+
{
|
|
151
|
+
Text = ButtonText,
|
|
152
|
+
iconColor: iconColorOption,
|
|
153
|
+
iconSize: iconSizeOption,
|
|
154
|
+
textProps: textPropsOption,
|
|
155
|
+
}: UseButtonOptions = {}
|
|
156
|
+
) {
|
|
157
|
+
const isNested = useContext(ButtonNestingContext)
|
|
158
|
+
const styledContext = ButtonContext.useStyledContext()
|
|
239
159
|
const processedProps = useProps(propsIn, {
|
|
240
160
|
noNormalize: true,
|
|
241
161
|
noExpand: true,
|
|
242
|
-
})
|
|
162
|
+
}) as Props & {
|
|
163
|
+
accessibilityRole?: string
|
|
164
|
+
children?: ReactNode
|
|
165
|
+
color?: TextContextStyles['color']
|
|
166
|
+
disabled?: boolean
|
|
167
|
+
render?: unknown
|
|
168
|
+
role?: string
|
|
169
|
+
size?: unknown
|
|
170
|
+
}
|
|
243
171
|
|
|
244
172
|
const {
|
|
245
173
|
children,
|
|
246
|
-
iconSize,
|
|
247
|
-
icon,
|
|
248
|
-
iconAfter,
|
|
249
|
-
scaleIcon = 1,
|
|
250
|
-
noTextWrap,
|
|
251
|
-
textProps,
|
|
252
174
|
color,
|
|
175
|
+
disabled,
|
|
253
176
|
ellipsis,
|
|
254
177
|
fontFamily,
|
|
255
178
|
fontSize,
|
|
256
179
|
fontStyle,
|
|
257
180
|
fontWeight,
|
|
181
|
+
icon,
|
|
182
|
+
iconAfter,
|
|
183
|
+
iconSize,
|
|
258
184
|
letterSpacing,
|
|
259
185
|
maxFontSizeMultiplier,
|
|
186
|
+
noTextWrap,
|
|
187
|
+
render,
|
|
188
|
+
scaleIcon = 1,
|
|
260
189
|
textAlign,
|
|
261
|
-
|
|
190
|
+
textProps,
|
|
262
191
|
} = processedProps
|
|
263
192
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
: contextColor
|
|
272
|
-
const iconColor = useCurrentColor(iconColorProp)
|
|
273
|
-
const finalSize = iconSize ?? size ?? styledContext?.size
|
|
274
|
-
const iconSizeNumber =
|
|
275
|
-
(typeof finalSize === 'number' ? finalSize * 0.5 : getFontSize(finalSize as Token)) *
|
|
276
|
-
scaleIcon
|
|
193
|
+
// useProps resolves styles for the component running the hook. This behavior
|
|
194
|
+
// HOC renders a styled frame, so its frame styles must keep the raw flat
|
|
195
|
+
// programs for the frame's own hover/press/focus state and merge pass.
|
|
196
|
+
const frameProps = { ...propsIn }
|
|
197
|
+
for (const key of buttonInternalPropNames) {
|
|
198
|
+
delete (frameProps as Record<string, any>)[key]
|
|
199
|
+
}
|
|
277
200
|
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
201
|
+
const contextColor = color ?? styledContext?.color
|
|
202
|
+
const iconColor = iconColorOption ?? contextColor
|
|
203
|
+
const resolvedIconSize = iconSize ?? iconSizeOption
|
|
204
|
+
const getThemedIcon = useGetThemedIcon({
|
|
205
|
+
color: iconColor === 'unset' || typeof iconColor === 'number' ? undefined : iconColor,
|
|
206
|
+
size: resolvedIconSize === undefined ? undefined : resolvedIconSize * scaleIcon,
|
|
207
|
+
})
|
|
208
|
+
const [themedIcon, themedIconAfter] = [icon, iconAfter].map((item) => {
|
|
209
|
+
return item ? getThemedIcon(item) : null
|
|
285
210
|
})
|
|
286
211
|
|
|
212
|
+
const textContext: TextContextStyles = {
|
|
213
|
+
color: contextColor,
|
|
214
|
+
ellipsis: ellipsis ?? styledContext?.ellipsis,
|
|
215
|
+
fontFamily: fontFamily ?? styledContext?.fontFamily,
|
|
216
|
+
fontSize: fontSize ?? styledContext?.fontSize,
|
|
217
|
+
fontStyle: fontStyle ?? styledContext?.fontStyle,
|
|
218
|
+
fontWeight: fontWeight ?? styledContext?.fontWeight,
|
|
219
|
+
letterSpacing: letterSpacing ?? styledContext?.letterSpacing,
|
|
220
|
+
maxFontSizeMultiplier: maxFontSizeMultiplier ?? styledContext?.maxFontSizeMultiplier,
|
|
221
|
+
textAlign: textAlign ?? styledContext?.textAlign,
|
|
222
|
+
}
|
|
287
223
|
const wrappedChildren = wrapChildrenInText(
|
|
288
224
|
Text,
|
|
289
225
|
{
|
|
290
226
|
children,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
fontSize: fontSize ?? propsIn.fontSize ?? styledContext?.fontSize,
|
|
295
|
-
fontStyle: fontStyle ?? propsIn.fontStyle ?? styledContext?.fontStyle,
|
|
296
|
-
fontWeight: fontWeight ?? propsIn.fontWeight ?? styledContext?.fontWeight,
|
|
297
|
-
letterSpacing:
|
|
298
|
-
letterSpacing ?? propsIn.letterSpacing ?? styledContext?.letterSpacing,
|
|
299
|
-
maxFontSizeMultiplier:
|
|
300
|
-
maxFontSizeMultiplier ??
|
|
301
|
-
propsIn.maxFontSizeMultiplier ??
|
|
302
|
-
styledContext?.maxFontSizeMultiplier,
|
|
303
|
-
noTextWrap: noTextWrap ?? propsIn.noTextWrap,
|
|
304
|
-
textAlign: textAlign ?? propsIn.textAlign ?? styledContext?.textAlign,
|
|
305
|
-
textProps: textProps ?? propsIn.textProps,
|
|
227
|
+
...textContext,
|
|
228
|
+
noTextWrap,
|
|
229
|
+
textProps,
|
|
306
230
|
},
|
|
307
231
|
{
|
|
308
|
-
|
|
309
|
-
size:
|
|
232
|
+
...textPropsOption,
|
|
233
|
+
...(processedProps.size === undefined ? null : { size: processedProps.size }),
|
|
310
234
|
}
|
|
311
235
|
)
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
...
|
|
330
|
-
...
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
236
|
+
const resolvedRender =
|
|
237
|
+
render ??
|
|
238
|
+
(isNested ? (
|
|
239
|
+
'span'
|
|
240
|
+
) : processedProps.accessibilityRole === 'link' || processedProps.role === 'link' ? (
|
|
241
|
+
'a'
|
|
242
|
+
) : disabled ? (
|
|
243
|
+
<button type="button" disabled />
|
|
244
|
+
) : undefined)
|
|
245
|
+
|
|
246
|
+
const props = {
|
|
247
|
+
...frameProps,
|
|
248
|
+
...(disabled && {
|
|
249
|
+
'aria-disabled': true,
|
|
250
|
+
disabled: true,
|
|
251
|
+
tabIndex: -1,
|
|
252
|
+
}),
|
|
253
|
+
...(resolvedRender === undefined ? null : { render: resolvedRender }),
|
|
254
|
+
...(isNested && {
|
|
255
|
+
// a nested Button is a presentation part, not a control: strip the
|
|
256
|
+
// interactive semantics so we never place a focusable role=button (with
|
|
257
|
+
// its own press/keyboard handlers) inside the outer native <button>. that
|
|
258
|
+
// nesting is invalid html, adds an extra focus stop, and bubbles
|
|
259
|
+
// activation to the outer control. resolvedRender already makes it a span.
|
|
260
|
+
role: 'none',
|
|
261
|
+
tabIndex: -1,
|
|
262
|
+
'aria-disabled': undefined,
|
|
263
|
+
disabled: undefined,
|
|
264
|
+
onPress: undefined,
|
|
265
|
+
onPressIn: undefined,
|
|
266
|
+
onPressOut: undefined,
|
|
267
|
+
onLongPress: undefined,
|
|
268
|
+
onClick: undefined,
|
|
269
|
+
onKeyDown: undefined,
|
|
270
|
+
onKeyUp: undefined,
|
|
271
|
+
}),
|
|
272
|
+
children: (
|
|
273
|
+
<ButtonNestingContext.Provider value={true}>
|
|
274
|
+
<ButtonContext.Provider {...textContext}>
|
|
347
275
|
{themedIcon}
|
|
348
276
|
{wrappedChildren}
|
|
349
277
|
{themedIconAfter}
|
|
350
|
-
</
|
|
351
|
-
</
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
278
|
+
</ButtonContext.Provider>
|
|
279
|
+
</ButtonNestingContext.Provider>
|
|
280
|
+
),
|
|
281
|
+
} as Props
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
isNested,
|
|
285
|
+
props,
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const ButtonComponent = createStyledHOC(
|
|
290
|
+
ButtonFrame,
|
|
291
|
+
function Button(props: ButtonBehaviorProps, ref) {
|
|
292
|
+
const { props: buttonProps } = useButton(props)
|
|
293
|
+
|
|
294
|
+
return <ButtonFrame ref={ref} {...buttonProps} />
|
|
295
|
+
}
|
|
296
|
+
)
|
|
355
297
|
|
|
356
298
|
export const Button = withStaticProperties(ButtonComponent, {
|
|
357
|
-
Apply:
|
|
358
|
-
Frame,
|
|
359
|
-
|
|
360
|
-
|
|
299
|
+
Apply: ButtonContext.Provider,
|
|
300
|
+
Frame: ButtonFrame,
|
|
301
|
+
Icon: ButtonIcon,
|
|
302
|
+
Text: ButtonText,
|
|
361
303
|
})
|
|
362
304
|
|
|
363
305
|
export type ButtonProps = GetProps<typeof ButtonComponent>
|