Skip to content

Commit 8a25ef6

Browse files
committed
Add the as prop (Box)
1 parent 890580c commit 8a25ef6

File tree

9 files changed

+165
-23
lines changed

9 files changed

+165
-23
lines changed

docs/api/components/box.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ const App = () => {
212212
render(<App />)
213213
```
214214

215+
### As
216+
217+
You can use the `as` prop to render another element (for instance `Animated.View`) instead of `View` (available only in TypeScript).
218+
215219
### Props
216220

217221
:::info
@@ -222,6 +226,12 @@ render(<App />)
222226

223227
<Props
224228
data={[
229+
{
230+
name: 'as',
231+
type: 'React.ComponentType',
232+
required: false,
233+
select: ['typescript']
234+
},
225235
{
226236
name: 'alignX',
227237
type: 'responsiveProp<[#left | #center | #right | #top | #bottom | #between | #around | #evenly | #stretch]>',

docs/core/components.js

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ export const Props = props => {
4949
const { data } = props
5050

5151
return data.map(values => {
52-
const { name, type, required, defaultValue, rawTsType } = values
52+
const {
53+
name,
54+
type,
55+
required,
56+
defaultValue,
57+
rawTsType,
58+
select = ['rescript', 'typescript'],
59+
} = values
5360

5461
return (
5562
<Fragment key={name}>
@@ -67,22 +74,26 @@ export const Props = props => {
6774
<li>
6875
type:
6976
<ul>
70-
<li>
71-
<TsLogo
72-
width={17}
73-
height={17}
74-
style={{ marginRight: 8, position: 'relative', top: 3 }}
75-
/>
76-
<code>{rawTsType ? rawTsType : mapType(type)}</code>
77-
</li>
78-
<li>
79-
<ResLogo
80-
width={17}
81-
height={17}
82-
style={{ marginRight: 8, position: 'relative', top: 3 }}
83-
/>
84-
<code>{type}</code>
85-
</li>
77+
{select.includes('typescript') ? (
78+
<li>
79+
<TsLogo
80+
width={17}
81+
height={17}
82+
style={{ marginRight: 8, position: 'relative', top: 3 }}
83+
/>
84+
<code>{rawTsType ? rawTsType : mapType(type)}</code>
85+
</li>
86+
) : null}
87+
{select.includes('rescript') ? (
88+
<li>
89+
<ResLogo
90+
width={17}
91+
height={17}
92+
style={{ marginRight: 8, position: 'relative', top: 3 }}
93+
/>
94+
<code>{type}</code>
95+
</li>
96+
) : null}
8697
</ul>
8798
</li>
8899
<li>

docs/docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ id: changelog
33
title: Changelog
44
---
55

6+
### `v2.2.0`
7+
8+
- ✨ added the [`as`](/api/components/box#as) prop to `Box`, which allows rendering another element (for instance `Animated.View`) instead of `View`
9+
610
### `v2.1.0`
711

812
- ✨ added the [`defaultWidth`](/api/components/columns#default-width) prop to `Columns`, which allows to set a default column width behavior ([@domeknn](https://github.com/domeknn))

src/Stacks_component_Box.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ let make = (
161161
}
162162
}
163163

164-
flatten([
164+
coerce([
165165
padding,
166166
paddingX,
167167
paddingY,

src/Stacks_styles.res

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
open ReactNative.Style
22

3-
open Stacks_externals
4-
53
@module("react-native") @scope("StyleSheet")
64
external compose: (ReactNative.Style.t, ReactNative.Style.t) => ReactNative.Style.t = "compose"
75

@@ -68,8 +66,6 @@ let right = value => ReactNative.Style.unsafeStyle({"right": value})
6866
let bottom = value => ReactNative.Style.unsafeStyle({"bottom": value})
6967
let left = value => ReactNative.Style.unsafeStyle({"left": value})
7068

71-
let flatten = xs => xs->coerce->ReactNative.StyleSheet.flatten
72-
7369
let resolveAlignItemsX = Belt.Option.mapU(_, (. value) =>
7470
switch value {
7571
| #center => styles["alignCenter"]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { API } from 'jscodeshift'
2+
3+
const transform = (source: string, j: API['jscodeshift']): string => {
4+
const root = j(source)
5+
const component = root.find(j.FunctionDeclaration).filter(p => {
6+
if (p.value.id?.type === 'Identifier') {
7+
return /stacks_component_box/i.test(p.value.id.name)
8+
}
9+
10+
return false
11+
})
12+
13+
component.forEach(p => {
14+
const root = j(p.value)
15+
16+
root.find(j.ReturnStatement).forEach(p => {
17+
const statement = j(p.value)
18+
19+
statement
20+
.find(j.CallExpression, {
21+
callee: {
22+
property: {
23+
name: 'createElement',
24+
},
25+
},
26+
})
27+
.forEach(p => {
28+
const arg = p.value.arguments.find(arg => {
29+
return (
30+
arg.type === 'MemberExpression' &&
31+
arg.property.type === 'Identifier' &&
32+
arg.property.name === 'View'
33+
)
34+
})
35+
36+
if (arg && arg.type === 'MemberExpression') {
37+
p.value.arguments = [
38+
j.logicalExpression(
39+
'||',
40+
j.memberExpression(j.identifier('Props'), j.identifier('as')),
41+
arg,
42+
),
43+
...p.value.arguments.slice(1),
44+
]
45+
}
46+
})
47+
})
48+
})
49+
50+
return root.toSource()
51+
}
52+
53+
export default transform

tools/javascript-codemods/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import { API, FileInfo } from 'jscodeshift'
33
import uncurry from './uncurry-functions'
44
import renameLiterals from './rename-literals'
55
import cleanupComponents from './cleanup-components'
6+
import addAsProp from './add-as-prop'
67

78
const transform = (file: FileInfo, api: API) => {
89
const j = api.jscodeshift
9-
const source = [uncurry, renameLiterals, cleanupComponents].reduce((acc, fn) => {
10+
const source = [uncurry, renameLiterals, cleanupComponents, addAsProp].reduce((acc, fn) => {
1011
return fn(acc, j)
1112
}, file.source)
1213

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { API } from 'jscodeshift'
2+
3+
const transform = (source: string, j: API['jscodeshift']): string => {
4+
const root = j(source)
5+
const component = root.find(j.ExportNamedDeclaration).filter(p => {
6+
if (p.value.declaration?.type === 'VariableDeclaration') {
7+
return p.value.declaration.declarations.some(declaration => {
8+
return (
9+
declaration.type === 'VariableDeclarator' &&
10+
declaration.init?.type === 'MemberExpression' &&
11+
declaration.init.object.type === 'Identifier' &&
12+
/stacks_component_box/i.test(declaration.init.object.name)
13+
)
14+
})
15+
}
16+
17+
return false
18+
})
19+
20+
component.forEach(_p => {
21+
root
22+
.find(j.ExportNamedDeclaration, {
23+
declaration: {
24+
id: {
25+
name: 'Props',
26+
},
27+
},
28+
})
29+
.forEach(p => {
30+
if (
31+
p.value.declaration?.type === 'TSTypeAliasDeclaration' &&
32+
p.value.declaration.typeAnnotation.type === 'TSTypeLiteral'
33+
) {
34+
const signature = j.tsPropertySignature(
35+
j.identifier('as'),
36+
j.tsTypeAnnotation(
37+
j.tsTypeReference(
38+
j.tsQualifiedName(j.identifier('React'), j.identifier('ComponentType')),
39+
),
40+
),
41+
)
42+
43+
signature.optional = true
44+
signature.readonly = true
45+
46+
p.value.declaration.typeAnnotation.members = p.value.declaration.typeAnnotation.members
47+
.map(p => {
48+
if (p.type === 'TSPropertySignature' && p.key.type === 'Identifier') {
49+
const signature = j.tsPropertySignature(j.identifier(p.key.name), p.typeAnnotation)
50+
signature.optional = p.optional
51+
signature.readonly = true
52+
return signature
53+
}
54+
55+
return p
56+
})
57+
.concat(signature)
58+
}
59+
})
60+
})
61+
62+
return root.toSource()
63+
}
64+
65+
export default transform

tools/typescript-codemods/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import transformReactNative from './transform-react-native'
44
import prettifyStacksTypes from './prettify-stacks-types'
55
import shrinkComponentType from './shrink-component-type'
66
import renameLiterals from './rename-literals'
7+
import addAsProp from './add-as-prop'
78

89
const transform = (file: FileInfo, api: API) => {
910
const j = api.jscodeshift
@@ -12,6 +13,7 @@ const transform = (file: FileInfo, api: API) => {
1213
prettifyStacksTypes,
1314
shrinkComponentType,
1415
renameLiterals,
16+
addAsProp,
1517
].reduce((acc, fn) => {
1618
return fn(acc, j)
1719
}, file.source)

0 commit comments

Comments
 (0)