├── .github
└── workflows
│ ├── main.yml
│ └── size.yml
├── .gitignore
├── .vscode
└── settings.json
├── CONTRIBUTION.md
├── LICENSE
├── README.md
├── README_API_CHECKLIST.md
├── banner
├── Cover.png
├── example-1.gif
└── high-res-example.gif
├── example
├── .npmignore
├── img
│ ├── Vector.png
│ └── flutter.png
├── index.css
├── index.html
├── index.tsx
├── package-lock.json
├── package.json
├── sample.json
├── tsconfig.json
└── yarn.lock
├── package-lock.json
├── package.json
├── src
├── addProperty.tsx
├── buildDartASTfromAST.tsx
├── clearProperties.tsx
├── config
│ ├── flutter-widgets.ts
│ ├── index.ts
│ ├── layout-props.ts
│ └── text-props.ts
├── index.tsx
└── utils
│ ├── arr.js
│ ├── camel.ts
│ ├── converter.tsx
│ ├── getAlignmentAxis.tsx
│ ├── getBorder.tsx
│ ├── getBorderRadius.tsx
│ ├── getExpanded.tsx
│ ├── getFlex.tsx
│ ├── getFlexDirection.tsx
│ ├── getFontFamily.tsx
│ ├── getFontStyle.tsx
│ ├── getFontWeight.tsx
│ ├── getMargin.tsx
│ ├── getPadding.tsx
│ ├── getPositioned.tsx
│ ├── getTextAlign.tsx
│ ├── num.ts
│ ├── pos.js
│ ├── pushPropToWidget.tsx
│ ├── str.js
│ └── unit.ts
├── test
└── blah.test.tsx
├── tsconfig.json
└── yarn.lock
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [push]
3 | jobs:
4 | build:
5 | name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}
6 |
7 | runs-on: ${{ matrix.os }}
8 | strategy:
9 | matrix:
10 | node: ['10.x', '12.x', '14.x']
11 | os: [ubuntu-latest, windows-latest, macOS-latest]
12 |
13 | steps:
14 | - name: Checkout repo
15 | uses: actions/checkout@v2
16 |
17 | - name: Use Node ${{ matrix.node }}
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: ${{ matrix.node }}
21 |
22 | - name: Install deps and build (with cache)
23 | uses: bahmutov/npm-install@v1
24 |
25 | - name: Lint
26 | run: yarn lint
27 |
28 | - name: Test
29 | run: yarn test --ci --coverage --maxWorkers=2
30 |
31 | - name: Build
32 | run: yarn build
33 |
--------------------------------------------------------------------------------
/.github/workflows/size.yml:
--------------------------------------------------------------------------------
1 | name: size
2 | on: [pull_request]
3 | jobs:
4 | size:
5 | runs-on: ubuntu-latest
6 | env:
7 | CI_JOB_NUMBER: 1
8 | steps:
9 | - uses: actions/checkout@v1
10 | - uses: andresz1/size-limit-action@v1
11 | with:
12 | github_token: ${{ secrets.GITHUB_TOKEN }}
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | .cache
5 | dist
6 | .vercel
7 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "flexbox",
4 | "Funit"
5 | ]
6 | }
--------------------------------------------------------------------------------
/CONTRIBUTION.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We want to make contributing to this project as easy and transparent as possible and we are grateful for, any contributions made by the community.
4 |
5 | ## Reporting Issues and Asking Questions
6 |
7 | Before opening an issue, please search the [issue tracker](https://github.com/GeekyAnts/react-native-to-flutter/issues) to make sure your issue hasn't already been reported.
8 |
9 | ### Bugs and Improvements
10 |
11 | We use the issue tracker to keep track of bugs and improvements to React Native to Flutter Widgets itself, its examples, and the documentation. We encourage you to open issues to discuss improvements, architecture, theory, internal implementation, etc. If a topic has been discussed before, we will ask you to join the previous discussion.
12 |
13 | ## Development
14 |
15 | Visit the [issue tracker](https://github.com/GeekyAnts/react-native-to-flutter/issues) to find a list of open issues that need attention.
16 |
17 | ### Building
18 |
19 |
20 | Clone the repo, run
21 |
22 | ```
23 | git clone https://github.com/GeekyAnts/react-native-to-flutter.git
24 | ```
25 |
26 | Install Dependencies
27 | ```
28 | yarn install
29 | ```
30 |
31 | Run the below command in root folder of the project
32 |
33 | ```
34 | yarn start
35 | ```
36 |
37 | Now to run the example, open new terminal and change your pwd to example folder
38 |
39 | ```
40 | cd example
41 | ```
42 | and then run
43 |
44 | ```
45 | yarn start
46 | ```
47 | Now head to `http://localhost:1234/`, app should be working fine.
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | ### Sending a Pull Request
56 |
57 | For non-trivial changes, please open an issue with a proposal for a new feature or refactoring before starting on the work. We don't want you to waste your efforts on a pull request that we won't want to accept.
58 |
59 | In general, the contribution workflow looks like this:
60 |
61 | - Open a new issue in the [Issue tracker](https://github.com/GeekyAnts/react-native-to-flutter/issues).
62 | - Fork the repo.
63 | - Create a new feature branch based off the `main` branch.
64 | - Make sure all tests pass and there are no linting errors.
65 | - Submit a pull request, referencing any issues it addresses.
66 |
67 | Please try to keep your pull request focused in scope and avoid including unrelated commits.
68 |
69 | After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements.
70 |
71 | Thank you for contributing!
72 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Sanket Sahu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native to Flutter Widgets
2 |
3 | 
4 |
5 | The goal of `React Native to Flutter Widgets` is to convert any React Native Component to Flutter Widget. This could really help the newbies of flutter who has web knowledge to understand the CSS to flutter equivalent code snippet.
6 |
7 |
8 | This tool will take the React Native styling props on the left hand side editor and convert that to the flutter widget on the right hand side.
9 |
10 |
11 | ### List of Working React Native Props
12 |
13 | The entire checklist of which props are being already supported is [here](https://github.com/GeekyAnts/nativebase-theme-to-flutter/blob/main/README_API_CHECKLIST.md)
14 |
15 | ### Working Example
16 |
17 |
18 |
19 |
20 | ### Folder Structure
21 |
22 | ```
23 | .
24 | ├── LICENSE
25 | ├── README.md
26 | ├── README_API_CHECKLIST.md
27 | ├── package-lock.json
28 | ├── package.json
29 | ├── src
30 | │ ├── addProperty.tsx
31 | │ ├── buildDartASTfromAST.tsx
32 | │ ├── clearProperties.tsx
33 | │ ├── config
34 | │ │ ├── flutter-widgets.ts
35 | │ │ ├── index.ts
36 | │ │ ├── layout-props.ts
37 | │ │ └── text-props.ts
38 | │ ├── index.tsx
39 | │ └── utils
40 | │ ├── arr.js
41 | │ ├── camel.ts
42 | │ ├── converter.tsx
43 | │ ├── getAlignmentAxis.tsx
44 | │ ├── getBorder.tsx
45 | │ ├── getBorderRadius.tsx
46 | │ ├── getExpanded.tsx
47 | │ ├── getFlex.tsx
48 | │ ├── getFlexDirection.tsx
49 | │ ├── getFontFamily.tsx
50 | │ ├── getFontStyle.tsx
51 | │ ├── getFontWeight.tsx
52 | │ ├── getMargin.tsx
53 | │ ├── getPadding.tsx
54 | │ ├── getPositioned.tsx
55 | │ ├── getTextAlign.tsx
56 | │ ├── num.ts
57 | │ ├── pos.js
58 | │ ├── pushPropToWidget.tsx
59 | │ ├── str.js
60 | │ └── unit.ts
61 | ├── test
62 | │ └── blah.test.tsx
63 | ├── tsconfig.json
64 | └── yarn.lock
65 |
66 |
67 | ```
68 |
69 | ### Run this project
70 |
71 | Clone the repo, run
72 |
73 | ```
74 | git clone https://github.com/GeekyAnts/react-native-to-flutter.git
75 |
76 | ```
77 |
78 | ### Dependencies
79 |
80 | ```
81 | @babel/parser
82 | @babel/preset-react
83 |
84 | ```
85 |
86 | Install Dependencies
87 | ```
88 | yarn install
89 | ```
90 |
91 | Run the below command in root folder of the project
92 |
93 | ```
94 | yarn start
95 | ```
96 | Now to run the example, open new terminal and change your pwd to example folder
97 |
98 | ```
99 | cd example
100 | ```
101 | and then run
102 | ```
103 | yarn start
104 | ````
105 | Now head to ```http://localhost:1234/``` app should be working fine.
106 |
107 | ### Know Issues
108 | ❌ Deep Nesting of Tags might not work as expected.
109 | ### How to Contribute
110 |
111 | Thank you for your interest in contributing to React Native to Flutter Widgets ! We are lucky to have you 🙂 Head over to [Contribution](https://github.com/GeekyAnts/react-native-to-flutter/blob/main/CONTRIBUTION.md) Guidelines and learn how you can be a part of a wonderful, growing community.
112 |
113 | ### Contributors
114 |
115 |
116 |
117 |
118 |
119 | ### License
120 |
121 | Licensed under the [MIT](https://github.com/GeekyAnts/react-native-to-flutter/blob/main/LICENSE) License, Copyright © 2023 GeekyAnts. See LICENSE for more information.
122 |
123 |
124 | Made with ❤️ by
125 |
--------------------------------------------------------------------------------
/README_API_CHECKLIST.md:
--------------------------------------------------------------------------------
1 | # ReactNative to Flutter Widgets Checklist
2 |
3 | This is the list of React Native Styling props, as per the official [React Native reference](https://reactnative.dev/docs/layout-props). This checklist tracks and work as a road map. Checked Items are already ported and unchecked are yet to be ported to Flutter widgets.
4 |
5 |
6 |
7 | ##### Prop List (*click to expand*)
8 |
9 | Layout Props
10 |
11 | - [x] alignContent
12 |
13 | - [x] alignItems
14 |
15 | - [ ] alignSelf
16 |
17 | - [ ] aspectRatio
18 |
19 | - [x] borderBottomWidth
20 |
21 | - [x] borderEndWidth
22 |
23 | - [x] borderLeftWidth
24 |
25 | - [x] borderRightWidth
26 |
27 | - [x] borderStartWidth
28 |
29 | - [x] borderTopWidth
30 |
31 | - [x] borderWidth
32 |
33 | - [x] bottom
34 |
35 | - [x] direction
36 |
37 | - [ ] display
38 |
39 | - [ ] end
40 |
41 | - [ ] flex
42 |
43 | - [ ] flexBasis
44 |
45 | - [ ] flexDirection
46 |
47 | - [ ] flexGrow
48 |
49 | - [ ] flexShrink
50 |
51 | - [ ] flexWrap
52 |
53 | - [x] height
54 |
55 | - [x] justifyContent
56 |
57 | - [x] left
58 |
59 | - [x] margin
60 |
61 | - [x] marginBottom
62 |
63 | - [x] marginEnd
64 |
65 | - [x] marginHorizontal
66 |
67 | - [x] marginLeft
68 |
69 | - [x] marginRight
70 |
71 | - [x] marginStart
72 |
73 | - [x] marginTop
74 |
75 | - [x] marginVertical
76 |
77 | - [x] maxHeight
78 |
79 | - [x] maxWidth
80 |
81 | - [x] minHeight
82 |
83 | - [x] minWidth
84 |
85 | - [ ] overflow
86 |
87 | - [x] padding
88 |
89 | - [x] paddingBottom
90 |
91 | - [x] paddingEnd
92 |
93 | - [x] paddingHorizontal
94 |
95 | - [x] paddingLeft
96 |
97 | - [x] paddingRight
98 |
99 | - [x] paddingStart
100 |
101 | - [x] paddingTop
102 |
103 | - [x] paddingVertical
104 |
105 | - [x] position
106 |
107 | - [x] right
108 |
109 | - [ ] start
110 |
111 | - [x] top
112 |
113 | - [x] width
114 |
115 | - [ ] zIndex
116 |
117 |
118 |
119 |
120 | Text Props
121 |
122 | - [x] fontFamily
123 |
124 | - [x] fontSize
125 |
126 | - [x] fontStyle
127 |
128 | - [x] fontWeight
129 |
130 | - [ ] includeFontPaddingAndroid
131 |
132 | - [x] fontVariant
133 |
134 | - [x] letterSpacing
135 |
136 | - [x] lineHeight
137 |
138 | - [x] textAlign
139 |
140 | - [ ] textAlignVerticalAndroid
141 |
142 | - [ ] textDecorationColoriOS
143 |
144 | - [ ] textDecorationLine
145 |
146 | - [ ] textDecorationStyleiOS
147 |
148 | - [ ] textShadowColor
149 |
150 | - [ ] textShadowOffset
151 |
152 | - [ ] textShadowRadius
153 |
154 | - [ ] textTransform
155 |
156 | - [ ] writingDirection
157 |
158 |
159 |
160 |
161 | View Style Props
162 |
163 | - [ ] backfaceVisibility
164 |
165 | - [x] backgroundColor
166 |
167 | - [x] borderBottomColor
168 |
169 | - [x] borderBottomEndRadius
170 |
171 | - [x] borderBottomLeftRadius
172 |
173 | - [x] borderBottomRightRadius
174 |
175 | - [x] borderBottomStartRadius
176 |
177 | - [x] borderBottomWidth
178 |
179 | - [x] borderColor
180 |
181 | - [x] borderEndColor
182 |
183 | - [x] borderLeftColor
184 |
185 | - [x] borderLeftWidth
186 |
187 | - [x] borderRadius
188 |
189 | - [x] borderRightColor
190 |
191 | - [x] borderRightWidth
192 |
193 | - [x] borderStartColor
194 |
195 | - [x] borderStyle
196 |
197 | - [x] borderTopColor
198 |
199 | - [x] borderTopEndRadius
200 |
201 | - [x] borderTopLeftRadius
202 |
203 | - [x] borderTopRightRadius
204 |
205 | - [x] borderTopStartRadius
206 |
207 | - [x] borderTopWidth
208 |
209 | - [x] borderWidth
210 |
211 | - [ ] elevationAndroid
212 |
213 | - [ ] opacity
214 |
215 |
216 |
217 |
218 | Image Styles Props
219 |
220 | - [ ] backfaceVisibility
221 |
222 | - [ ] backgroundColor
223 |
224 | - [ ] borderBottomLeftRadius
225 |
226 | - [ ] borderBottomRightRadius
227 |
228 | - [ ] borderColor
229 |
230 | - [ ] borderRadius
231 |
232 | - [ ] borderTopLeftRadius
233 |
234 | - [ ] borderTopRightRadius
235 |
236 | - [ ] borderWidth
237 |
238 | - [ ] opacity
239 |
240 | - [ ] overflow
241 |
242 | - [ ] overlayColorAndroid
243 |
244 | - [ ] resizeMode
245 |
246 | - [ ] tintColor
247 |
248 |
249 |
--------------------------------------------------------------------------------
/banner/Cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekyAnts/react-native-to-flutter/52379b7b7b0449c1ad21bea5fdcef5ee323d9d1a/banner/Cover.png
--------------------------------------------------------------------------------
/banner/example-1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekyAnts/react-native-to-flutter/52379b7b7b0449c1ad21bea5fdcef5ee323d9d1a/banner/example-1.gif
--------------------------------------------------------------------------------
/banner/high-res-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekyAnts/react-native-to-flutter/52379b7b7b0449c1ad21bea5fdcef5ee323d9d1a/banner/high-res-example.gif
--------------------------------------------------------------------------------
/example/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .cache
3 | dist
--------------------------------------------------------------------------------
/example/img/Vector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekyAnts/react-native-to-flutter/52379b7b7b0449c1ad21bea5fdcef5ee323d9d1a/example/img/Vector.png
--------------------------------------------------------------------------------
/example/img/flutter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekyAnts/react-native-to-flutter/52379b7b7b0449c1ad21bea5fdcef5ee323d9d1a/example/img/flutter.png
--------------------------------------------------------------------------------
/example/index.css:
--------------------------------------------------------------------------------
1 | .ribbon {
2 | background-color: #a00;
3 | overflow: hidden;
4 | white-space: nowrap;
5 | position: absolute;
6 | right: -40px;
7 | top: 25px;
8 | -webkit-transform: rotate(45deg);
9 | -moz-transform: rotate(45deg);
10 | -ms-transform: rotate(45deg);
11 | -o-transform: rotate(45deg);
12 | transform: rotate(45deg);
13 | -webkit-box-shadow: 0 0 10px #888;
14 | -moz-box-shadow: 0 0 10px #888;
15 | box-shadow: 0 0 10px #888;
16 | }
17 |
18 | .switch-wrapper{
19 | display: none;
20 | }
21 |
22 | .ribbon a {
23 | border: 1px solid #faa;
24 | color: #fff;
25 | display: block;
26 | font: bold 81.25% 'Helvetica Neue', Helvetica, Arial, sans-serif;
27 | margin: 1px 0;
28 | padding: 10px 30px;
29 | text-align: center;
30 | text-decoration: none;
31 | text-shadow: 0 0 5px #444;
32 | }
33 |
34 | .eclipse1 {
35 | position: absolute;
36 | width: 362px;
37 | height: 362px;
38 | top: -49px;
39 | background: #54C5F8;
40 | filter: blur(150px);
41 | left: -188px;
42 | z-index: 1;
43 | }
44 |
45 | .eclipse2 {
46 | position: absolute;
47 | width: 571px;
48 | height: 439px;
49 | bottom: -165px;
50 | right: -227px;
51 |
52 |
53 | background: #54C5F8;
54 | filter: blur(150px);
55 | }
56 | .switch-code{
57 | display: flex;
58 | border: 1px solid #cfcfcf;
59 | font-size: 12px;
60 | border-radius: 60px;
61 | }
62 |
63 |
64 |
65 | .playground-navbar {
66 | display: flex;
67 | align-items: center;
68 | background-color: #000;
69 | padding:10px 0px;
70 | position: relative;
71 | z-index: 2;
72 | }
73 |
74 | .menu-wrapper {
75 | flex: 1;
76 | justify-content: end;
77 | display: flex;
78 | align-items: center;
79 | margin-right: 30px;
80 | }
81 |
82 | .playground-footer {
83 | display: flex;
84 | background-color: #000;
85 | z-index: 100;
86 | position: absolute;
87 | margin: 0;
88 | padding: 10px;
89 | left: 0;
90 | width: 100%;
91 | bottom: 0;
92 | }
93 |
94 | .playground-footer p {
95 | color: #B6B6B6;
96 | margin: auto;
97 | }
98 |
99 | .playground-footer>p>span {
100 | color: #CF2F2F
101 | }
102 |
103 | .logoName{
104 | margin: 0;
105 | }
106 |
107 | .editor-container {
108 | height: calc(100vh - 295px);
109 | border: 1px solid #cfcfcf47;
110 | }
111 |
112 | .playground-heading {
113 | color: #FFFFFF;
114 | text-align: center;
115 | margin: auto;
116 | margin-top: 20px;
117 | margin-bottom: 20px;
118 | font-size: 24px;
119 | }
120 |
121 | .playground-subheading {
122 | margin: auto;
123 | text-align: center;
124 | max-width: 570px;
125 | color: #858181;
126 | margin-bottom: 20px
127 | }
128 |
129 |
130 | /* Extra small devices (phones, 600px and down) */
131 | @media only screen and (max-width: 600px) {
132 |
133 |
134 | /* .menu-wrapper , a:nth-last-child(0) {
135 | display: none;
136 | } */
137 | .issue {
138 | display: none;
139 | }
140 | .props {
141 | display: none;
142 | }
143 |
144 | .github{
145 | display: block;
146 | }
147 |
148 | .eclipse2 {
149 | display: none;
150 | }
151 |
152 | .playground-heading {
153 | font-size: 14px;
154 | }
155 | .playground-subheading {
156 | display: none;
157 | }
158 | .switch-wrapper{
159 | display: flex;
160 | align-items: center;
161 | justify-content: center;
162 | margin-bottom: 30px;
163 |
164 | }
165 | .active-code{
166 | color: #000000;
167 | background-color: #fff;
168 | border-radius: 60px;
169 | }
170 |
171 | }
172 |
173 | /* Small devices (portrait tablets and large phones, 600px and up) */
174 | @media only screen and (min-width: 600px) {}
175 |
176 | /* Medium devices (landscape tablets, 768px and up) */
177 | @media only screen and (min-width: 768px) {}
178 |
179 | /* Large devices (laptops/desktops, 992px and up) */
180 | @media only screen and (min-width: 992px) {}
181 |
182 | /* Extra large devices (large laptops and desktops, 1200px and up) */
183 | @media only screen and (min-width: 1200px) {}
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Playground
10 |
12 |
13 |
14 |
16 |
18 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/example/index.tsx:
--------------------------------------------------------------------------------
1 | import { convertNativeBaseThemeToFlutterWidgets } from '../.';
2 |
3 | import 'react-app-polyfill/ie11';
4 | import * as ReactDOM from 'react-dom';
5 | import * as React from 'react';
6 | import { useState } from 'react';
7 | import Editor from "@monaco-editor/react";
8 | // @ts-ignore
9 | import flutter from '../example/img/flutter.png'
10 |
11 | //let styles: any = {
12 |
13 | // position:"absolute",
14 | // flexGrow:4,
15 | // minHeight:4,
16 | // width:3,
17 | // height:4,
18 | // borderRadius:4,
19 | // borderWidth:3,
20 | // borderColor:"#fcfcfc",
21 | // paddingHorizontal:30,
22 | // paddingRight:40,
23 | // paddingBottom:50,
24 | // paddingTop:40,
25 | // maxWidth:30,
26 | // minWidth:50,
27 | // maxHeight:50,
28 | // margin:30,
29 | // borderBottomWidth:1,
30 | // borderTopWidth:3,
31 | // borderLeftWidth:4,
32 | // borderRightWidth:5,
33 | // flexDirection:"column",
34 | // alignContent:"space-between",
35 | // alignItems:"stretch",
36 | // // position:"absolute",
37 | // top:10,
38 | // right:20,
39 | // bottom:30,
40 | // left:40,
41 |
42 | // color: "#ffffff",
43 | // fontSize: 23,
44 | // letterSpacing: 4,
45 | // lineHeight: 4,
46 | // fontStyle: "italic",
47 | // fontWeight: 300,
48 | // textAlign: "center",
49 | // fontFamily: "abc"
50 |
51 | //}
52 | let styles = (`
53 |
76 | This Widget is Made from React Native to Flutter Tool
86 |
87 | `)
88 |
89 |
90 | const theme = {
91 | base: 'vs',
92 | inherit: true,
93 | rules: [
94 | { token: 'custom-info', foreground: 'a3a7a9', background: 'ffffff' },
95 | { token: 'custom-error', foreground: 'ee4444' },
96 | { token: 'custom-notice', foreground: '1055af' },
97 | { token: 'custom-date', foreground: '20aa20' },
98 | ],
99 | colors: {
100 | 'editor.foreground': '#FFFFFF',
101 | 'editor.background': '#CFCFCF',
102 | }
103 | }
104 |
105 |
106 |
107 |
108 |
109 | function App() {
110 | const [code, setCode] = useState(styles);
111 | const [output, setOutput]: any = useState('');
112 | const [error, setError]: any = useState(false)
113 | const [isActiveReact,setIsActiveReact]:any = useState(true)
114 | const [isMobile,setIsMobile]:any = useState(false)
115 | const transpileCode = (code: string) => {
116 | setOutput(convertNativeBaseThemeToFlutterWidgets(code));
117 | };
118 |
119 | const editorRef: any = React.useRef(null);
120 | var myMonaco: any;
121 |
122 | // function handleEditorWillMount(monaco) {
123 | // // here is the monaco instance
124 | // // do something before editor is mounted
125 | // myMonaco = monaco;
126 | // monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true);
127 | // monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
128 | // target: monaco.languages.typescript.ScriptTarget.ES2016,
129 | // allowNonTsExtensions: true,
130 | // moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
131 | // module: monaco.languages.typescript.ModuleKind.CommonJS,
132 | // noEmit: true,
133 | // typeRoots: ["node_modules/@types"]
134 | // });
135 | // monaco.editor.defineTheme('myTheme', theme)
136 | // debugger
137 |
138 | // monaco.editor.EditorOptions.automaticLayout;
139 | // monaco.languages.typescript.typescriptDefaults.addExtraLib(
140 | // `export declare function next() : string`,
141 | // 'node_modules/@types/external/index.d.ts');
142 | // monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
143 | // noSemanticValidation: false,
144 | // noSyntaxValidation: false
145 | // })
146 |
147 |
148 |
149 | // }
150 |
151 | function handleEditorDidMount(editor, monaco) {
152 | // here is the editor instance
153 | // you can store it in `useRef` for further usage
154 | editorRef.current = monaco;
155 | }
156 |
157 |
158 |
159 | React.useEffect(() => {
160 | setOutput('')
161 | debugger
162 | console.log(window.innerHeight);
163 | if(window.innerWidth <=600){
164 | setIsMobile(true);
165 | } else {
166 | setIsMobile(false);
167 | }
168 |
169 | }, []);
170 | React.useEffect(() => {
171 |
172 | if (code && !error) {
173 |
174 | transpileCode(code)
175 | }
176 | }, [code]);
177 |
178 | return (
179 |
180 |
181 |
182 |
183 |
186 |
187 |
188 |
RN2Flutter
189 |
194 |
195 |
196 |
197 |
198 |
199 |
209 |
210 |
React Native Component to Flutter Widgets (Alpha)
211 |
Helpful for developers who are familiar with React Native but new to Flutter, as it allows them to leverage their knowledge of React Native styling and apply it to Flutter.
212 |
213 |
214 |
{setIsActiveReact(!isActiveReact);console.log("hello")}} className={`${isActiveReact ? 'active-code':''}`} style={{flex:"1 1 0px" ,padding :"5px",whiteSpace:"nowrap",flexBasis:"100%",width:"100.00px",textAlign:"center",color:`${isActiveReact ?'#000':"#fff"}`}}>React Native
215 |
{setIsActiveReact(!isActiveReact);console.log("hello")}} className={`${!isActiveReact ? 'active-code':''}`} style={{flex:"1 1 0px",padding:"5px",flexBasis:"100%",width:"100.00px",textAlign:"center",color:`${!isActiveReact ?'#000':"#fff"}`}}>Flutter
216 |
217 |
218 |
219 |
220 |
221 |
222 | {isMobile ? isActiveReact? reactEditor():
:reactEditor()}
223 |
224 | {isMobile ? !isActiveReact ? flutterEditor():
:flutterEditor()}
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | );
233 |
234 | function flutterEditor(): string | number | boolean | {} | React.ReactElement> | React.ReactNodeArray | React.ReactPortal | null | undefined {
235 | return
236 |
237 |
Flutter Widget
238 |
239 |
248 |
249 |
250 |
;
251 | }
252 |
253 | function reactEditor(): string | number | boolean | {} | React.ReactElement> | React.ReactNodeArray | React.ReactPortal | null | undefined {
254 | return
255 |
256 |
257 |
React Native Component
258 |
259 | {
270 |
271 | if (e.length > 1) {
272 |
273 | setError(true);
274 | } else {
275 | setError(false);
276 | }
277 | } }
278 | onChange={(e: string) => {
279 | if (!error) {
280 | setCode(e);
281 | setOutput('');
282 | }
283 |
284 |
285 | } } />
286 |
287 |
288 |
289 |
290 |
;
291 | }
292 | }
293 |
294 | ReactDOM.render( , document.getElementById('root'));
295 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "1.0.0",
4 | "main": "./build/index.js",
5 | "license": "MIT",
6 | "scripts": {
7 | "start": "parcel index.html",
8 | "build": "parcel build index.html"
9 | },
10 | "dependencies": {
11 | "@monaco-editor/react": "^4.4.6",
12 | "@uiw/codemirror-extensions-langs": "^4.13.2",
13 | "@uiw/codemirror-theme-sublime": "^4.13.2",
14 | "@uiw/react-codemirror": "^4.13.2",
15 | "prismjs": "^1.29.0",
16 | "react-app-polyfill": "^1.0.0",
17 | "react-simple-code-editor": "^0.13.1"
18 | },
19 | "alias": {
20 | "react": "../node_modules/react",
21 | "react-dom": "../node_modules/react-dom/profiling",
22 | "scheduler/tracing": "../node_modules/scheduler/tracing-profiling"
23 | },
24 | "devDependencies": {
25 | "@babel/core": "^7.20.5",
26 | "@babel/preset-react": "^7.18.6",
27 | "@types/react": "^16.9.11",
28 | "@types/react-dom": "^16.8.4",
29 | "babel-core": "^7.0.0-bridge.0",
30 | "babel-jest": "^29.3.1",
31 | "parcel": "1.12.3",
32 | "regenerator-runtime": "^0.13.11",
33 | "typescript": "^3.4.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/example/sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "components": {
3 | "Button": {
4 |
5 | "baseStyle": {
6 | "borderRadius": "sm",
7 |
8 | "flexDirection": "row",
9 | "justifyContent": "center",
10 | "alignItems": "center",
11 | "_web": {
12 | "_disabled": {
13 | "cursor": "not-allowed"
14 | },
15 | "_loading": {
16 | "cursor": "not-allowed"
17 | },
18 | "cursor": "pointer",
19 | "userSelect": "none"
20 | },
21 | "_focusVisible": {
22 | "_web": {
23 | "outlineWidth": "0",
24 | "style": {
25 | "boxShadow": "#22d3ee 0px 0px 0px 2px"
26 | }
27 | }
28 | },
29 | "_dark": {
30 | "_focusVisible": {
31 | "_web": {
32 | "outlineWidth": "0",
33 | "style": {
34 | "boxShadow": "#06b6d4 0px 0px 0px 2px"
35 | }
36 | }
37 | }
38 | },
39 | "_stack": {
40 | "space": "1.5",
41 | "alignItems": "center"
42 | },
43 | "_loading": {
44 | "opacity": "40"
45 | },
46 | "_disabled": {
47 | "opacity": "40"
48 | },
49 | "_spinner": {
50 | "size": "sm",
51 | "focusable": false
52 | }
53 | },
54 | "variants": {
55 | "ghost": {
56 | "_text": {
57 | "color": "primary.600"
58 | },
59 | "_icon": {
60 | "color": "primary.600"
61 | },
62 | "_spinner": {
63 | "color": "primary.600"
64 | },
65 | "_hover": {
66 | "bg": "primary.600:alpha.10"
67 | },
68 | "_pressed": {
69 | "bg": "primary.600:alpha.20"
70 | },
71 | "_dark": {
72 | "_text": {
73 | "color": "primary.500"
74 | },
75 | "_icon": {
76 | "color": "primary.500"
77 | },
78 | "_spinner": {
79 | "color": "primary.500"
80 | },
81 | "_hover": {
82 | "bg": "primary.500:alpha.10"
83 | },
84 | "_pressed": {
85 | "bg": "primary.500:alpha.20"
86 | }
87 | }
88 | },
89 | "outline": {
90 | "borderWidth": "1px",
91 | "borderColor": "muted.300",
92 | "_text": {
93 | "color": "primary.600"
94 | },
95 | "_icon": {
96 | "color": "primary.600"
97 | },
98 | "_spinner": {
99 | "color": "primary.600"
100 | },
101 | "_hover": {
102 | "bg": "primary.600:alpha.10"
103 | },
104 | "_pressed": {
105 | "bg": "primary.600:alpha.20"
106 | },
107 | "_dark": {
108 | "borderColor": "muted.700",
109 | "_text": {
110 | "color": "primary.500"
111 | },
112 | "_icon": {
113 | "color": "primary.500"
114 | },
115 | "_spinner": {
116 | "color": "primary.500"
117 | },
118 | "_hover": {
119 | "bg": "primary.500:alpha.10"
120 | },
121 | "_pressed": {
122 | "bg": "primary.500:alpha.20"
123 | }
124 | }
125 | },
126 | "solid": {
127 | "_text": {
128 | "color": "text.50"
129 | },
130 | "_icon": {
131 | "color": "text.50"
132 | },
133 | "_spinner": {
134 | "color": "text.50"
135 | },
136 | "bg": "primary.600",
137 | "_hover": {
138 | "bg": "primary.700"
139 | },
140 | "_pressed": {
141 | "bg": "primary.800"
142 | },
143 | "_dark": {
144 | "bg": "primary.600",
145 | "_hover": {
146 | "bg": "primary.700"
147 | },
148 | "_pressed": {
149 | "bg": "primary.800"
150 | }
151 | }
152 | },
153 | "subtle": {
154 | "bg": "primary.100",
155 | "_text": {
156 | "color": "primary.900"
157 | },
158 | "_icon": {
159 | "color": "primary.900"
160 | },
161 | "_spinner": {
162 | "color": "primary.900"
163 | },
164 | "_hover": {
165 | "bg": "primary.200"
166 | },
167 | "_pressed": {
168 | "bg": "primary.300"
169 | },
170 | "_dark": {
171 | "bg": "primary.300",
172 | "_hover": {
173 | "bg": "primary.200"
174 | },
175 | "_pressed": {
176 | "bg": "primary.100"
177 | }
178 | }
179 | },
180 | "link": {
181 | "_icon": {
182 | "color": "primary.600"
183 | },
184 | "_spinner": {
185 | "color": "primary.600"
186 | },
187 | "_hover": {
188 | "_text": {
189 | "textDecorationLine": "underline"
190 | }
191 | },
192 | "_pressed": {
193 | "_text": {
194 | "color": "primary.800",
195 | "textDecorationLine": "underline"
196 | }
197 | },
198 | "_text": {
199 | "color": "primary.600"
200 | },
201 | "_dark": {
202 | "_text": {
203 | "color": "primary.500"
204 | },
205 | "_pressed": {
206 | "_text": {
207 | "color": "primary.300"
208 | }
209 | }
210 | }
211 | }
212 | },
213 | "sizes": {
214 | "lg": {
215 | "px": "3",
216 | "py": "3",
217 | "_text": {
218 | "fontSize": "md"
219 | },
220 | "_icon": {
221 | "size": "md"
222 | }
223 | },
224 | "md": {
225 | "px": "3",
226 | "py": "2.5",
227 | "_text": {
228 | "fontSize": "sm"
229 | },
230 | "_icon": {
231 | "size": "sm"
232 | }
233 | },
234 | "sm": {
235 | "px": "3",
236 | "py": "2",
237 | "_text": {
238 | "fontSize": "xs"
239 | },
240 | "_icon": {
241 | "size": "sm"
242 | }
243 | },
244 | "xs": {
245 | "px": "3",
246 | "py": "2",
247 | "_text": {
248 | "fontSize": "2xs"
249 | },
250 | "_icon": {
251 | "size": "xs"
252 | }
253 | }
254 | },
255 | "defaultProps": {
256 | "variant": "solid",
257 | "size": "md",
258 | "colorScheme": "primary"
259 | }
260 | }
261 | }
262 | }
263 |
264 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": false,
4 | "target": "es5",
5 | "module": "commonjs",
6 | "jsx": "react",
7 | "moduleResolution": "node",
8 | "noImplicitAny": false,
9 | "noUnusedLocals": false,
10 | "noUnusedParameters": false,
11 | "removeComments": true,
12 | "strictNullChecks": true,
13 | "preserveConstEnums": true,
14 | "sourceMap": true,
15 | "lib": ["es2015", "es2016", "dom"],
16 | "types": ["node"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "license": "MIT",
4 | "main": "dist/index.js",
5 | "typings": "dist/index.d.ts",
6 | "files": [
7 | "dist",
8 | "src"
9 | ],
10 | "engines": {
11 | "node": ">=10"
12 | },
13 | "scripts": {
14 | "start": "tsdx watch",
15 | "build": "tsdx build",
16 | "test": "tsdx test --passWithNoTests",
17 | "lint": "tsdx lint",
18 | "prepare": "tsdx build",
19 | "size": "size-limit",
20 | "analyze": "size-limit --why"
21 | },
22 | "peerDependencies": {
23 | "react": ">=16"
24 | },
25 | "husky": {
26 | "hooks": {
27 | "pre-commit": "tsdx lint"
28 | }
29 | },
30 | "prettier": {
31 | "printWidth": 80,
32 | "semi": true,
33 | "singleQuote": true,
34 | "trailingComma": "es5"
35 | },
36 | "name": "nativebase-theme-to-flutter",
37 | "author": "Sanket Sahu",
38 | "module": "dist/nativebase-theme-to-flutter.esm.js",
39 | "size-limit": [
40 | {
41 | "path": "dist/nativebase-theme-to-flutter.cjs.production.min.js",
42 | "limit": "10 KB"
43 | },
44 | {
45 | "path": "dist/nativebase-theme-to-flutter.esm.js",
46 | "limit": "10 KB"
47 | }
48 | ],
49 | "devDependencies": {
50 | "@babel/core": "^7.20.5",
51 | "@babel/parser": "^7.20.5",
52 | "@babel/plugin-proposal-class-properties": "^7.18.6",
53 | "@babel/plugin-syntax-jsx": "^7.18.6",
54 | "@babel/plugin-transform-runtime": "^7.19.6",
55 | "@babel/preset-env": "^7.20.2",
56 | "@babel/preset-flow": "^7.18.6",
57 | "@babel/preset-react": "^7.18.6",
58 | "@babel/preset-typescript": "^7.18.6",
59 | "@size-limit/preset-small-lib": "^8.1.0",
60 | "@types/react": "^18.0.25",
61 | "@types/react-dom": "^18.0.8",
62 | "babel-core": "^7.0.0-bridge.0",
63 | "babel-jest": "^29.3.1",
64 | "babel-preset-react": "^6.24.1",
65 | "husky": "^8.0.2",
66 | "ppo": "^1.3.5",
67 | "react": "^18.2.0",
68 | "react-dom": "^18.2.0",
69 | "regenerator-runtime": "^0.13.11",
70 | "size-limit": "^8.1.0",
71 | "tsdx": "^0.14.1",
72 | "tslib": "^2.4.1",
73 | "typescript": "^4.8.4"
74 | },
75 | "dependencies": {
76 | "@babel/traverse": "^7.20.5",
77 | "@types/color": "^3.0.3",
78 | "@types/lodash": "^4.14.188",
79 | "color": "^4.2.3",
80 | "lodash-es": "^4.17.21"
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/addProperty.tsx:
--------------------------------------------------------------------------------
1 | import { styleSystem } from "./config";
2 |
3 | export function addProperty(myObject: any, val: any, prop: any, style: any, ast: any) {
4 | let newProp: any;
5 | if (styleSystem.hasOwnProperty(prop)) {
6 | if (myObject.type === "constructor" || myObject.type === "enum") {
7 |
8 | newProp = { ...styleSystem[prop].class, namedProp: styleSystem[prop].property };
9 | if (typeof newProp.value === "object") {
10 | newProp.value = { ...newProp.value, value: val };
11 | } else {
12 | if(newProp.hasOwnProperty("value")){
13 | newProp.value = val;
14 | }
15 |
16 | }
17 |
18 |
19 | if (styleSystem[prop].transformer) {
20 |
21 | // newProp.properties = []
22 | newProp = styleSystem[prop].transformer(style, newProp, ast);
23 |
24 | if (newProp.nested) {
25 | return newProp;
26 | }
27 | }
28 |
29 |
30 |
31 |
32 | } else {
33 |
34 | newProp = { ...myObject, value: val, namedProp: styleSystem[prop].property };
35 | }
36 | }
37 |
38 | if (newProp.class !== myObject.class) {
39 | if (styleSystem[prop].hasOwnProperty("partOf")) {
40 |
41 | let index = myObject["properties"].findIndex((data: any) => {
42 | return data.namedProp === newProp.namedProp;
43 |
44 | });
45 |
46 | if (index < 0) {
47 | myObject = { ...myObject, properties: myObject.properties };
48 | myObject.properties.push(newProp);
49 | }
50 | } else {
51 | myObject = newProp;
52 | }
53 |
54 | } else {
55 | myObject = newProp;
56 | }
57 |
58 |
59 | return myObject;
60 | }
61 |
--------------------------------------------------------------------------------
/src/buildDartASTfromAST.tsx:
--------------------------------------------------------------------------------
1 | import { buildDartAST } from "./index";
2 |
3 | export function buildDartASTfromAST(expression: any, myDartAST: any, recursive: boolean = false) {
4 |
5 |
6 |
7 | if (!recursive) {
8 | if (expression.children.length < 2) {
9 | if (myDartAST?.class) {
10 | let index = myDartAST.properties.findIndex((data: any) => (data.namedProp === "child"));
11 | if (myDartAST.properties[index]?.class === "Row" || myDartAST.properties[index]?.class === "Column") {
12 | let i = myDartAST.properties[index].properties.findIndex((data: any) => (data.namedProp === "children"));
13 |
14 | if (i > -1) {
15 | myDartAST.properties[index].properties[i].values = [];
16 | }
17 | }
18 | }
19 | }
20 |
21 | let index = myDartAST?.properties?.findIndex((data: any) => (data.namedProp === "child"));
22 | if (index) {
23 | if (myDartAST?.properties[index]?.class === "Row" || myDartAST?.properties[index]?.class === "Column") {
24 | let i = myDartAST.properties[index].properties.findIndex((data: any) => (data.namedProp === "children"));
25 | if (i > -1) {
26 | myDartAST.properties[index].properties[i].values = [];
27 | }
28 | }
29 | }
30 | }
31 |
32 |
33 |
34 | Object.entries(expression.children).forEach(([k, v]: any) => {
35 |
36 | let a: any = {};
37 |
38 | if (v.type === "JSXElement") {
39 |
40 |
41 |
42 | let style = {};
43 |
44 | let name = v.openingElement.name.name;
45 |
46 | let attributes = v.openingElement.attributes[0];
47 |
48 |
49 |
50 | let properties = attributes?.value?.expression?.properties;
51 | if (properties) {
52 | Object.entries(properties).forEach(([, v]: any) => {
53 |
54 | style = { ...style, [v.key.name]: v.value.value };
55 | });
56 |
57 | }
58 |
59 | if (myDartAST?.class) {
60 | let layout: any = {
61 | type: "constructor",
62 | properties: []
63 | }
64 |
65 |
66 | a = buildDartAST(name, style);
67 |
68 | if (name === "View") {
69 | let index = a.properties.findIndex((data: any) => (data.class === "Row" || data.class === "Column"));
70 | if (index > -1) {
71 |
72 | // layout = { ...layout, "class": a.properties[index].class }
73 | // a.properties.splice(index, 1);
74 | } else {
75 | layout = { ...layout, "class": "Row" }
76 | }
77 |
78 |
79 |
80 |
81 |
82 | let childIndex = a.properties.findIndex((data: any) => (data.namedProp === "child"));
83 | if (childIndex > -1) {
84 | a.properties[childIndex].properties.push({ ...layout, "namedProp": "child" })
85 | } else {
86 | a.properties.push({ ...layout, "namedProp": "child" })
87 | }
88 |
89 | }
90 | if (name === 'Text') {
91 |
92 | a = { ...a, id: k, value: v.children[0]?.value ?? '' };
93 | } else {
94 | a = { ...a, id: k };
95 | }
96 |
97 |
98 |
99 | let index = myDartAST?.properties?.findIndex((data: any) => (data.namedProp === "child"));
100 | if (myDartAST.properties[index]?.class === "Row" || myDartAST.properties[index]?.class === "Column") {
101 |
102 | let i = myDartAST?.properties[index]?.properties.findIndex((data: any) => (data?.namedProp === "children"));
103 |
104 | if (i > -1) {
105 | let ii = myDartAST?.properties[index]?.properties[i]?.values?.findIndex((data: any) => (data.id === a.id));
106 | if (ii > -1) {
107 | myDartAST?.properties[index].properties[i].values.splice(ii, 1);
108 | }
109 | myDartAST?.properties[index].properties[i].values.push(a);
110 |
111 | } else {
112 | myDartAST?.properties[index].properties.push({ namedProp: "children", type: "Array", values: [a] });
113 | }
114 |
115 | } else {
116 |
117 | searchForDeepChildAndPush(myDartAST, a);
118 |
119 | // myDartAST?.properties.push({ "namedProp": "child", ...a });
120 | }
121 |
122 | }
123 |
124 | console.log(style);
125 | console.log(myDartAST);
126 |
127 |
128 | }
129 |
130 | if (v.children) {
131 | if (v.children.length > 0) {
132 | console.log(v);
133 | buildDartASTfromAST(v, a);
134 | }
135 | }
136 |
137 | });
138 |
139 |
140 |
141 | }
142 |
143 | export function searchForDeepChildAndPush(myDartAST: any, a: any) {
144 |
145 | let prop = myDartAST?.properties ?? myDartAST?.values;
146 |
147 | let namedPropIndex = prop.findIndex((data: any) => (data.namedProp === "child" || data.namedProp === "children"));
148 | console.log(namedPropIndex);
149 | if(namedPropIndex < 0){
150 |
151 | if(myDartAST.hasOwnProperty("namedProp")){
152 | Object.entries(prop).forEach(([, v]: any) => {
153 |
154 |
155 | if (v.namedProp === "child") {
156 | if (v.properties.length > 0) {
157 | searchForDeepChildAndPush(v, a);
158 | } else {
159 | pushChildToParent(v, a);
160 | }
161 | } if (v.namedProp === "children") {
162 |
163 | if(a.hasOwnProperty("namedProp")){
164 | if (v.values.length > 0) {
165 | searchForDeepChildAndPush(v, a);
166 | } else {
167 | pushChildToParent(v, a);
168 | }
169 | } else {
170 | v.values.push(a)
171 | }
172 |
173 |
174 | } else {
175 | pushChildToParent(v, a);
176 | }
177 | });
178 |
179 | } else {
180 | pushChildToParent(myDartAST, a);
181 | }
182 | } else {
183 | searchForContainer(myDartAST,a);
184 | }
185 |
186 |
187 | }
188 |
189 | export function pushChildToParent(v: any, a: any) {
190 | if (v.type == "constructor") {
191 |
192 | if (v.class === 'Row' || v.class === 'Column') {
193 | v.properties.push({ namedProp: "children", type: "Array", values: [a] });
194 | } else {
195 | v.properties.push({ "namedProp": "child", ...a });
196 | }
197 |
198 | }
199 | }
200 |
201 |
202 | function searchForContainer(_ast: any,widget:any) {
203 | let prop = _ast?.properties ?? _ast?.values;
204 |
205 | if (prop) {
206 | Object.entries(prop).forEach(([, v]: any) => {
207 |
208 | if (v.class === "Container") {
209 | if(v.hasOwnProperty("properties")){
210 | if(v.properties.length>0){
211 | let childIndex = v.properties.findIndex((data:any)=>data.namedProp==="child"||data.namedProp==="children");
212 | if(childIndex>-1){
213 | let index = v.properties[childIndex].properties.findIndex((data:any)=>data.namedProp==="children");
214 | if(index >-1){
215 | if(v.properties[childIndex].properties[index].hasOwnProperty("namedProp")){
216 |
217 | v.properties[childIndex].properties[index].values.push(widget)
218 |
219 | }
220 | }
221 | else {
222 | v.properties[childIndex].properties.push({ namedProp: "children", type: "Array", values: [widget] });
223 | }
224 |
225 | }
226 | } else {
227 | v.properties.push(widget)
228 | }
229 |
230 |
231 | }
232 |
233 | } else {
234 | searchForContainer(v,widget);
235 | }
236 | });
237 | }
238 |
239 | }
240 |
241 |
--------------------------------------------------------------------------------
/src/clearProperties.tsx:
--------------------------------------------------------------------------------
1 | import { styleSystem } from "./config";
2 |
3 | export function clearProperties(theme: any) {
4 | Object.entries(theme).map(([k,]: any) => {
5 | if (styleSystem.hasOwnProperty(k)) {
6 | if (styleSystem[k].hasOwnProperty("partOf")) {
7 | styleSystem[k].partOf.class.properties = [];
8 | }
9 | }
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/src/config/flutter-widgets.ts:
--------------------------------------------------------------------------------
1 | import { getColor, toDouble, toInt } from "../utils/converter";
2 |
3 |
4 |
5 | export const dartType = {
6 | double: {
7 | type: "double",
8 | transformer: toDouble,
9 | value: "",
10 | },
11 | int: {
12 | type: "int",
13 | transformer: toInt,
14 | value: ""
15 | },
16 | string :{
17 | type:"string",
18 | value:""
19 | }
20 |
21 | }
22 |
23 | export const flutterWidget = {
24 | Container: {
25 | type: "constructor",
26 | class: "Container",
27 | properties: [
28 |
29 |
30 | ],
31 |
32 | },
33 |
34 | Text: {
35 | type: "constructor",
36 | class: "Text",
37 | properties: [],
38 | value:""
39 | },
40 |
41 | MainAxisAlignment :{
42 | type:"enum",
43 | class : "MainAxisAlignment",
44 | value : "",
45 |
46 | },
47 |
48 |
49 |
50 |
51 | Flex :{
52 | type:"constructor",
53 | class:"Flex",
54 | properties:[]
55 | },
56 |
57 | CrossAxisAlignment :{
58 | type:"enum",
59 | class : "CrossAxisAlignment",
60 | value : "",
61 |
62 | },
63 |
64 | Column :{
65 | type: "constructor",
66 | class: "Column",
67 | properties: []
68 | },
69 |
70 |
71 | Stack :{
72 | type: "constructor",
73 | class: "Stack",
74 | properties: []
75 | },
76 |
77 |
78 | Row :{
79 | type: "constructor",
80 | class: "Row",
81 | properties: []
82 | },
83 | Positioned:{
84 | type: "constructor",
85 | class: "Positioned",
86 | properties: []
87 | },
88 |
89 | BoxDecoration: {
90 | type: "constructor",
91 | class: "BoxDecoration",
92 | namedProp: "decoration",
93 | properties: []
94 | },
95 |
96 | Color: {
97 | type: "constructor",
98 | class: "Color",
99 | namedProp: "color",
100 | value: dartType.int,
101 | transformer: getColor
102 |
103 | },
104 | BoxConstraints: {
105 | type: "constructor",
106 | namedProp: "constraints",
107 | class: "BoxConstraints",
108 | properties: []
109 | },
110 |
111 |
112 | Expanded:{
113 | type:"constructor",
114 | class:"Expanded",
115 |
116 | properties: []
117 | },
118 |
119 |
120 |
121 |
122 |
123 | EdgeInsets: {
124 | type: "constructor",
125 | class: "EdgeInsets.all",
126 | properties: [],
127 | value: dartType.double,
128 | },
129 |
130 | EdgeInsetsDirectional: {
131 | type: "constructor",
132 | class: "EdgeInsetsDirectional.all",
133 | properties: [],
134 | value: dartType.double,
135 | },
136 |
137 | RadiusCircular: {
138 | type: "constructor",
139 | class: "Radius.circular",
140 | value: dartType.double
141 | },
142 |
143 |
144 | BorderBottomWidth: {
145 | type: "constructor",
146 | class: "BorderSide",
147 | properties: [
148 |
149 | ],
150 | value: dartType.double,
151 | },
152 |
153 | BorderStartWidth:{
154 | type: "constructor",
155 | class: "BorderSide",
156 | properties: [
157 |
158 | ],
159 | value: dartType.double,
160 | },
161 |
162 | BorderEndWidth:{
163 | type: "constructor",
164 | class: "BorderSide",
165 | properties: [
166 |
167 | ],
168 | value: dartType.double,
169 | },
170 |
171 | BorderTopWidth: {
172 | type: "constructor",
173 | class: "BorderSide",
174 | properties: [
175 |
176 | ],
177 | value: dartType.double,
178 | },
179 |
180 | BorderLeftWidth: {
181 | type: "constructor",
182 | class: "BorderSide",
183 | properties: [
184 |
185 | ],
186 | value: dartType.double,
187 | },
188 |
189 | BorderRightWidth: {
190 | type: "constructor",
191 | class: "BorderSide",
192 | properties: [
193 |
194 | ],
195 | value: dartType.double,
196 | },
197 |
198 | Border: {
199 | type: "constructor",
200 | class: "Border.all",
201 | properties: [
202 |
203 | ],
204 | value: dartType.double,
205 | callee: "Border",
206 |
207 | },
208 |
209 |
210 |
211 | BorderRadius: {
212 | type: "constructor",
213 | class: "BorderRadius.circular",
214 | namedProp: "borderRadius",
215 | properties: [
216 |
217 | ],
218 | value: dartType.double,
219 | },
220 |
221 |
222 |
223 | BorderTopLeftRadius: {
224 | type: "constructor",
225 | class: "BorderRadius.only",
226 | properties: [
227 |
228 | ],
229 | value: dartType.double,
230 | },
231 |
232 |
233 |
234 |
235 |
236 |
237 | BorderBottomLeftRadius: {
238 | type: "constructor",
239 | class: "BorderRadius.only",
240 | properties: [
241 |
242 | ],
243 | value: dartType.double,
244 | },
245 |
246 |
247 | TextStyle :{
248 | type:"constructor",
249 | class:"TextStyle",
250 | namedProp:"style",
251 | properties: [
252 |
253 | ],
254 | },
255 |
256 | FontStyle:{
257 | type:"enum",
258 | class : "FontStyle",
259 | value : "",
260 | },
261 | FontWeight:{
262 | type:"enum",
263 | class : "FontWeight",
264 | value : "",
265 | },
266 | TextAlign :{
267 | type:"enum",
268 | class:"TextAlign",
269 | value:""
270 | },
271 |
272 | FontFamily :{
273 | type:"string",
274 | class:"FontFamily",
275 | value:""
276 | }
277 | } as const
278 |
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
1 | import { layoutProps } from "./layout-props";
2 | import { textProp } from "./text-props";
3 |
4 | export const styleSystem : any = {
5 | ...layoutProps,
6 | ...textProp
7 | }
--------------------------------------------------------------------------------
/src/config/layout-props.ts:
--------------------------------------------------------------------------------
1 | import { getAlignmentAxis } from "../utils/getAlignmentAxis"
2 | import { getBorder } from "../utils/getBorder"
3 | import { getBorderRadius } from "../utils/getBorderRadius"
4 | import { getExpanded } from "../utils/getExpanded"
5 | import { getMargin } from "../utils/getMargin"
6 | import { getPadding } from "../utils/getPadding"
7 | import { getPositioned } from "../utils/getPositioned"
8 | import { toDouble, toInt } from "../utils/converter"
9 | import { flutterWidget } from "./flutter-widgets"
10 |
11 |
12 | export const dartType = {
13 | double: {
14 | type: "double",
15 | transformer: toDouble,
16 | value: "",
17 | },
18 | int: {
19 | type: "int",
20 | transformer: toInt,
21 | value: ""
22 | },
23 |
24 | } as const
25 |
26 |
27 | export const layoutProps = {
28 |
29 |
30 | "minHeight": {
31 | widget: "Container",
32 | "property": "minHeight",
33 | class: dartType.double,
34 | "partOf": {
35 | "class": flutterWidget.BoxConstraints,
36 | "property": "constraints",
37 | }
38 | },
39 |
40 | "minWidth": {
41 | widget: "Container",
42 | "property": "minWidth",
43 | class: dartType.double,
44 | "partOf": {
45 | "class": flutterWidget.BoxConstraints,
46 | "property": "constraints",
47 | }
48 | },
49 |
50 | "maxHeight": {
51 | widget: "Container",
52 | "property": "maxHeight",
53 | class: dartType.double,
54 | "partOf": {
55 | "class": flutterWidget.BoxConstraints,
56 | "property": "constraints",
57 | }
58 | },
59 |
60 | "maxWidth": {
61 | widget: "Container",
62 | "property": "maxWidth",
63 | class: dartType.double,
64 | "partOf": {
65 | "class": flutterWidget.BoxConstraints,
66 | "property": "constraints",
67 | }
68 | },
69 |
70 | "width": {
71 | "widget": "Container",
72 | "property": "width",
73 | class: dartType.double
74 |
75 | },
76 |
77 |
78 | "height": {
79 | "widget": "Container",
80 | "property": "height",
81 | class: dartType.double
82 | },
83 |
84 | "backgroundColor": {
85 | "widget": "Container",
86 | "property": "color",
87 | class: flutterWidget.Color,
88 | "partOf": {
89 | "class": flutterWidget.BoxDecoration,
90 | "property": "decoration",
91 | }
92 | },
93 |
94 | "borderRadius": {
95 | "widget": "Container",
96 | "property": "borderRadius",
97 | class: flutterWidget.BorderRadius,
98 | "partOf": {
99 | "class": flutterWidget.BoxDecoration,
100 | "property": "decoration",
101 | },
102 | transformer: getBorderRadius
103 | },
104 |
105 | "borderTopLeftRadius": {
106 | "widget": "Container",
107 | "property": "borderRadius",
108 | class: flutterWidget.BorderTopLeftRadius,
109 | "partOf": {
110 | "class": flutterWidget.BoxDecoration,
111 | "property": "decoration",
112 | },
113 | transformer: getBorderRadius
114 | },
115 |
116 | "borderTopRightRadius": {
117 | "widget": "Container",
118 | "property": "borderRadius",
119 | class: flutterWidget.BorderTopLeftRadius,
120 | "partOf": {
121 | "class": flutterWidget.BoxDecoration,
122 | "property": "decoration",
123 | },
124 | transformer: getBorderRadius
125 | },
126 |
127 | "borderBottomLeftRadius": {
128 | "widget": "Container",
129 | "property": "borderRadius",
130 | class: flutterWidget.BorderBottomLeftRadius,
131 | "partOf": {
132 | "class": flutterWidget.BoxDecoration,
133 | "property": "decoration",
134 | },
135 | transformer: getBorderRadius
136 | },
137 |
138 |
139 | borderWidth: {
140 | "widget": "Container",
141 | "property": "border",
142 | class: flutterWidget.Border,
143 | "partOf": {
144 | "class": flutterWidget.BoxDecoration,
145 | "property": "decoration",
146 | },
147 |
148 | transformer: getBorder,
149 | },
150 |
151 |
152 | borderStartWidth: {
153 | "widget": "Container",
154 | "property": "border",
155 | class: flutterWidget.Border,
156 | "partOf": {
157 | "class": flutterWidget.BoxDecoration,
158 | "property": "decoration",
159 | },
160 |
161 | transformer: getBorder,
162 | },
163 |
164 | borderEndWidth: {
165 | "widget": "Container",
166 | "property": "border",
167 | class: flutterWidget.Border,
168 | "partOf": {
169 | "class": flutterWidget.BoxDecoration,
170 | "property": "decoration",
171 | },
172 |
173 | transformer: getBorder,
174 | },
175 |
176 | borderBottomWidth :{
177 | "widget": "Container",
178 | "property": "border",
179 | class: flutterWidget.Border,
180 | "partOf": {
181 | "class": flutterWidget.BoxDecoration,
182 | "property": "decoration",
183 | },
184 | transformer: getBorder,
185 | },
186 |
187 | borderTopWidth :{
188 | "widget": "Container",
189 | "property": "border",
190 | class: flutterWidget.Border,
191 | "partOf": {
192 | "class": flutterWidget.BoxDecoration,
193 | "property": "decoration",
194 | },
195 | transformer: getBorder,
196 | },
197 |
198 | borderRightWidth :{
199 | "widget": "Container",
200 | "property": "border",
201 | class: flutterWidget.Border,
202 | "partOf": {
203 | "class": flutterWidget.BoxDecoration,
204 | "property": "decoration",
205 | },
206 | transformer: getBorder,
207 | },
208 |
209 | borderLeftWidth :{
210 | "widget": "Container",
211 | "property": "border",
212 | class: flutterWidget.Border,
213 | "partOf": {
214 | "class": flutterWidget.BoxDecoration,
215 | "property": "decoration",
216 | },
217 | transformer: getBorder,
218 | },
219 |
220 | borderColor: {
221 | "widget": "Container",
222 | "property": "border",
223 | class: flutterWidget.Border,
224 | "partOf": {
225 | "class": flutterWidget.BoxDecoration,
226 | "property": "decoration",
227 | },
228 | transformer: getBorder,
229 | },
230 |
231 | "padding": {
232 | "widget": "Container",
233 | "property": "padding",
234 | class: flutterWidget.EdgeInsets,
235 | transformer: getPadding,
236 |
237 | },
238 | paddingLeft: {
239 | "widget": "Container",
240 | "property": "padding",
241 | class: flutterWidget.EdgeInsets,
242 | transformer: getPadding,
243 | },
244 |
245 | paddingRight: {
246 | "widget": "Container",
247 | "property": "padding",
248 | class: flutterWidget.EdgeInsets,
249 | transformer: getPadding,
250 | },
251 |
252 | paddingTop: {
253 | "widget": "Container",
254 | "property": "padding",
255 | class: flutterWidget.EdgeInsets,
256 | transformer: getPadding,
257 | },
258 |
259 | paddingBottom: {
260 | "widget": "Container",
261 | "property": "padding",
262 | class: flutterWidget.EdgeInsets,
263 | transformer: getPadding,
264 | },
265 |
266 | margin: {
267 | "widget": "Container",
268 | "property": "margin",
269 | class: flutterWidget.EdgeInsets,
270 | transformer: getMargin,
271 | },
272 |
273 | marginLeft: {
274 | "widget": "Container",
275 | "property": "margin",
276 | class: flutterWidget.EdgeInsets,
277 | transformer: getMargin,
278 | },
279 |
280 |
281 | marginStart: {
282 | "widget": "Container",
283 | "property": "margin",
284 | class: flutterWidget.EdgeInsetsDirectional,
285 | transformer: getMargin,
286 | },
287 | marginEnd: {
288 | "widget": "Container",
289 | "property": "margin",
290 | class: flutterWidget.EdgeInsetsDirectional,
291 | transformer: getMargin,
292 | },
293 |
294 | marginRight: {
295 | "widget": "Container",
296 | "property": "margin",
297 | class: flutterWidget.EdgeInsets,
298 | transformer: getMargin,
299 | },
300 |
301 | marginTop: {
302 | "widget": "Container",
303 | "property": "margin",
304 | class: flutterWidget.EdgeInsets,
305 | transformer: getMargin,
306 | },
307 |
308 | marginBottom: {
309 | "widget": "Container",
310 | "property": "margin",
311 | class: flutterWidget.EdgeInsets,
312 | transformer: getMargin,
313 | },
314 |
315 | marginHorizontal :{
316 | "widget": "Container",
317 | "property": "margin",
318 | class: flutterWidget.EdgeInsets,
319 | transformer: getMargin,
320 | },
321 |
322 | marginVertical :{
323 | "widget": "Container",
324 | "property": "margin",
325 | class: flutterWidget.EdgeInsets,
326 | transformer: getMargin,
327 | },
328 |
329 | alignContent:{
330 | widget:"Column",
331 | "property": "mainAxisAlignment",
332 | class : flutterWidget.MainAxisAlignment,
333 | transformer : getAlignmentAxis
334 | },
335 |
336 | flexDirection:{
337 | widget:"Row",
338 | class : flutterWidget.Row,
339 | transformer : getAlignmentAxis
340 | },
341 |
342 | alignItems :{
343 | widget:"Column",
344 | "property": "crossAxisAlignment",
345 | class : flutterWidget.CrossAxisAlignment,
346 | transformer : getAlignmentAxis
347 | },
348 |
349 | justifyContent :{
350 | widget:"Column",
351 | "property": "mainAxisAlignment",
352 | class : flutterWidget.MainAxisAlignment,
353 | transformer : getAlignmentAxis
354 | },
355 |
356 |
357 |
358 | position :{
359 | widget:"Positioned",
360 | class: flutterWidget.Positioned,
361 | transformer : getPositioned
362 | },
363 |
364 | flexGrow:{
365 | widget:"Expanded",
366 | class:flutterWidget.Expanded,
367 | transformer:getExpanded,
368 | },
369 |
370 | flex:{
371 | widget:"Flex",
372 | class: flutterWidget.Expanded,
373 | transformer:getExpanded
374 | },
375 |
376 | top:{
377 | widget:"Positioned",
378 | property:"top",
379 | class:dartType.double,
380 | },
381 |
382 | bottom:{
383 | widget:"Positioned",
384 | property:"bottom",
385 | class:dartType.double,
386 | },
387 |
388 | right:{
389 | widget:"Positioned",
390 | property:"right",
391 | class:dartType.double,
392 | },
393 |
394 | left:{
395 | widget:"Positioned",
396 | property:"left",
397 | class:dartType.double,
398 | },
399 |
400 |
401 | "boxShadow": {
402 | "widget": "Container",
403 | "property": "boxShadow",
404 | "partOf": {
405 | "class": "BoxDecoration",
406 | "property": "decoration",
407 |
408 | }
409 | },
410 |
411 |
412 |
413 |
414 | "fontSize": {
415 | "widget": "Text",
416 | "property": "fontSize",
417 | "partOf": {
418 | "class": "TextStyle",
419 | "property": "style"
420 | }
421 | }
422 | }
423 |
--------------------------------------------------------------------------------
/src/config/text-props.ts:
--------------------------------------------------------------------------------
1 | import { getFontStyle } from "../utils/getFontStyle";
2 | import { getFontWeight } from "../utils/getFontWeight";
3 | import { getFontFamily } from "../utils/getFontFamily";
4 | import { getTextAlign } from "../utils/getTextAlign";
5 | import { dartType, flutterWidget } from "./flutter-widgets";
6 |
7 | export const textProp = {
8 |
9 |
10 | color: {
11 | widget: "Text",
12 | "property": "color",
13 | class: flutterWidget.Color,
14 | "partOf": {
15 | "class": flutterWidget.TextStyle,
16 | "property": "style",
17 | }
18 | },
19 |
20 |
21 | fontSize: {
22 | widget: "Text",
23 | "property": "fontSize",
24 | class: dartType.double,
25 | "partOf": {
26 | "class": flutterWidget.TextStyle,
27 | "property": "style",
28 | }
29 | },
30 |
31 | letterSpacing: {
32 | widget: "Text",
33 | "property": "letterSpacing",
34 | class: dartType.double,
35 | "partOf": {
36 | "class": flutterWidget.TextStyle,
37 | "property": "style",
38 | }
39 | },
40 |
41 | lineHeight: {
42 | widget: "Text",
43 | "property": "height",
44 | class: dartType.double,
45 | "partOf": {
46 | "class": flutterWidget.TextStyle,
47 | "property": "style",
48 | }
49 | },
50 |
51 | fontStyle :{
52 |
53 | widget: "Text",
54 | "property": "fontStyle",
55 | class: flutterWidget.FontStyle,
56 | "partOf": {
57 | "class": flutterWidget.TextStyle,
58 | "property": "style",
59 | },
60 | transformer:getFontStyle
61 | },
62 |
63 | fontWeight :{
64 |
65 | widget: "Text",
66 | "property": "fontWeight",
67 | class: flutterWidget.FontWeight,
68 | "partOf": {
69 | "class": flutterWidget.TextStyle,
70 | "property": "style",
71 | },
72 | transformer:getFontWeight
73 | },
74 |
75 | textAlign :{
76 | widget:"Text",
77 | property:"textAlign",
78 | class : flutterWidget.TextAlign,
79 | transformer:getTextAlign
80 | },
81 | fontFamily : {
82 | widget: "Text",
83 | "property": "fontFamily",
84 | class: flutterWidget.FontFamily,
85 | "partOf": {
86 | "class": flutterWidget.TextStyle,
87 | "property": "style",
88 | },
89 | transformer:getFontFamily
90 | }
91 | }
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | import { styleSystem } from "./config";
4 | import { flutterWidget } from "./config/flutter-widgets";
5 | import { pushPropToWidget } from "./utils/pushPropToWidget";
6 |
7 | import * as parser from '@babel/parser';
8 | //@ts-ignore
9 | import xyz from '@babel/preset-react'
10 | import { buildDartASTfromAST, searchForDeepChildAndPush } from "./buildDartASTfromAST";
11 | import { addProperty } from "./addProperty";
12 | import { clearProperties } from "./clearProperties";
13 |
14 |
15 |
16 | let mapReactComponentToFlutterWidgets: any = {
17 | "View": flutterWidget.Container,
18 | "Text": flutterWidget.Text
19 | };
20 |
21 |
22 | let count = 0;
23 |
24 |
25 | export function buildDartAST(component: any, theme: any) {
26 |
27 | let dartAST: any = {}
28 |
29 | try {
30 | let widget: any = { ...mapReactComponentToFlutterWidgets[component] };
31 |
32 | // delete widget.properties;
33 | widget.properties = []
34 | let a = ''
35 | a = widget;
36 |
37 | clearProperties(theme);
38 |
39 | dartAST = loopStyle(theme, a);
40 |
41 |
42 | } catch (error) {
43 | console.error(error)
44 | return error
45 | } finally {
46 | return dartAST;
47 | // createFlutterWidget(dartAST,count)
48 |
49 | }
50 |
51 |
52 |
53 | }
54 |
55 |
56 | function loopStyle(theme: any, ast: any) {
57 |
58 |
59 | Object.entries(theme).map(([k, v]: any) => {
60 |
61 |
62 |
63 | if (styleSystem.hasOwnProperty(k)) {
64 |
65 | if (styleSystem[k].hasOwnProperty("partOf")) {
66 | if (ast["properties"]) {
67 |
68 | let newVal = { [styleSystem[k].partOf.property]: styleSystem[k].partOf.class };
69 | let myObject = addProperty(newVal[styleSystem[k].partOf.property], v, k, theme, ast);
70 | let widget = styleSystem[k].widget;
71 | if (myObject.nested) {
72 | ast = myObject.object;
73 | } else {
74 | pushPropToWidget(ast, myObject, widget);
75 | }
76 | }
77 | } else {
78 |
79 | let newVal = { ...styleSystem[k].class };
80 | let myObject = addProperty(newVal, v, k, theme, ast);
81 | let widget = styleSystem[k].widget;
82 |
83 | if (myObject.nested) {
84 | ast = myObject.object;
85 | } else {
86 | pushPropToWidget(ast, myObject, widget);
87 | }
88 |
89 |
90 | }
91 | }
92 |
93 | });
94 |
95 | return ast;
96 | }
97 |
98 | let code: string = ""
99 | let tab: string = '\t';
100 | // @ts-ignore
101 |
102 | export function createFlutterWidget(ast: any, c: number) {
103 |
104 | if (ast?.hasOwnProperty("namedProp")) {
105 | if (ast.type === "constructor") {
106 | // if (ast.hasOwnProperty("value")) {
107 |
108 | // code += `${tab.repeat(c)}${ast.namedProp}:${ast.class}('${ast.value}',\n`
109 | // } else {
110 | code += `${tab.repeat(c)}${ast.namedProp}:${ast.class}(\n`
111 | //}
112 |
113 | } else if (ast.type === "Array") {
114 | code += `${tab.repeat(c)}${ast.namedProp}:[\n`
115 | }
116 |
117 | } else {
118 |
119 | if (ast?.hasOwnProperty("value")) {
120 |
121 | code += `${tab.repeat(c)}${ast.class}('${ast.value}',\n`
122 | } else {
123 |
124 | code += `${tab.repeat(c)}${ast?.class}(\n`
125 | }
126 |
127 | }
128 | c++
129 | if (ast?.hasOwnProperty("properties")) {
130 | Object.entries(ast?.properties).forEach(([, v]: any) => {
131 |
132 | if (v.hasOwnProperty("properties") || v.hasOwnProperty("widgets")) {
133 | createFlutterWidget(v, c);
134 | code += `${tab.repeat(c)}),\n`
135 |
136 |
137 | } else {
138 |
139 |
140 | let innerValue = v;
141 | let innerKey
142 |
143 |
144 |
145 |
146 | if (innerValue.class) {
147 | if (innerValue.type === "constructor" || innerValue.type === "enum" || innerValue.type === "string") {
148 | if (innerValue.hasOwnProperty("properties")) {
149 | createFlutterWidget(innerValue, c);
150 |
151 | }
152 |
153 |
154 | if (innerValue.value.transformer) {
155 | innerValue.value.value = innerValue.value.transformer(innerValue.value.value)
156 | } else {
157 | if (innerValue.transformer) {
158 | innerValue.value = innerValue.transformer(innerValue.value)
159 | }
160 | }
161 |
162 | if (innerValue.type === "constructor") {
163 | // Build class when its constrictor
164 | /// for eg Color(0xffffffff)
165 |
166 | code += `${tab.repeat(c)}${innerValue.namedProp}:${innerValue.class}(${innerValue.value.value ?? innerValue.value}),\n`
167 | } else if (innerValue.type === "enum") {
168 | // Build class when its constrictor
169 | /// for eg MainAxisAlignment.center
170 | code += `${tab.repeat(c)}${innerValue.namedProp}:${innerValue.class}.${innerValue.value.value ?? innerValue.value},\n`
171 | } else if (innerValue.type === "string") {
172 |
173 | code += `${tab.repeat(c)}${innerValue.namedProp}: "${innerValue.value.value ?? innerValue.value}", \n`
174 | }
175 |
176 | }
177 |
178 |
179 | } else {
180 |
181 |
182 |
183 |
184 | if (innerValue.type === "nameConstructor") {
185 |
186 | let args: string = ''
187 |
188 | if (innerValue.args) {
189 | Object.entries(innerValue.args[0]).forEach(([k, v]: any, index: number) => {
190 |
191 | if (index == 0) {
192 | args += `\n`;
193 | }
194 | if (v.transformer) {
195 | v.value = v.transformer(v.value);
196 | }
197 | args += `${tab.repeat(c + 1)}${k}:${v.value},\n`
198 | })
199 | code += `${tab.repeat(c)}${innerKey}:${innerValue.callee}.${innerValue.name}(${args}${tab.repeat(c)}),\n`
200 | } else {
201 | code += `${tab.repeat(c)}${innerKey}:${innerValue.callee}.${innerValue.name}(\n${innerValue.value}),\n`
202 | }
203 | } else if (innerValue.type == "Array") {
204 |
205 | code += `${tab.repeat(c)}${innerValue.namedProp}:[\n`
206 | c++;
207 | Object.entries(innerValue.values).forEach(([, v]: any) => {
208 |
209 | createFlutterWidget(v, c);
210 | code += `${tab.repeat(c)}),\n`
211 | });
212 | c--;
213 | code += `${tab.repeat(c)}],\n`
214 | } else {
215 |
216 | if (innerValue.transformer) {
217 |
218 | innerValue.value = innerValue.transformer(innerValue.value ?? innerValue)
219 | }
220 | code += `${tab.repeat(c)}${innerValue.namedProp}:${innerValue.value ?? innerValue},\n`
221 | }
222 | }
223 | }
224 |
225 | });
226 | }
227 |
228 |
229 |
230 | }
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 | export const convertNativeBaseThemeToFlutterWidgets = (styles: any): string => {
244 |
245 |
246 |
247 |
248 |
249 |
250 | try {
251 |
252 | let ast: any;
253 | code = '';
254 |
255 | try {
256 | ast = parser.parse(styles, {
257 | plugins: [
258 | // enable jsx and flow syntax
259 | "jsx",
260 | "flow",
261 | ],
262 | });
263 | console.log(ast);
264 |
265 | let style: any = {};
266 | let myDartAST: any;
267 | let expression = ast.program.body[0].expression;
268 | let name = expression.openingElement.name.name;
269 |
270 | if (expression.type === "JSXElement") {
271 |
272 | let attributes = expression.openingElement.attributes[0];
273 | if (attributes) {
274 | if (attributes?.name?.name === "style") {
275 |
276 | let properties = attributes.value.expression.properties;
277 | Object.entries(properties).forEach(([, v]: any) => {
278 | style[v.key.name] = v.value.value
279 | });
280 | myDartAST = buildDartAST(name, style)
281 | let layout: any = {
282 | type: "constructor",
283 | properties: []
284 | }
285 |
286 | console.log(myDartAST);
287 |
288 | if (name === "View") {
289 |
290 | let index = myDartAST.properties.findIndex((data: any) => (data.class === "Row" || data.class === "Column"));
291 | if (index > -1) {
292 |
293 | // layout = {...layout,"class": myDartAST.properties[index].class}
294 | // myDartAST.properties.splice(index, 1);
295 | } else {
296 | layout = {...layout,"class": "Row"}
297 | }
298 |
299 | // myDartAST.properties.push({ ...layout, "namedProp": "child" })
300 |
301 | searchForDeepChildAndPush(myDartAST,{...layout,"namedProp": "child" });
302 | }
303 |
304 |
305 | }
306 | } else {
307 | myDartAST = buildDartAST(name, style)
308 | let layout: any = {
309 | type: "constructor",
310 | properties: []
311 | }
312 |
313 | if (name === "View") {
314 | let index = myDartAST.properties.findIndex((data: any) => (data.class === "Row" || data.class === "Column"));
315 | if (index > -1) {
316 | // layout = {...layout,"class": myDartAST.properties[index].class}
317 | // myDartAST.properties.splice(index, 1);
318 | } else {
319 | layout = {...layout,"class": "Row"}
320 | }
321 |
322 | //searchForDeepChildAndPush(myDartAST,{});
323 |
324 | searchForDeepChildAndPush(myDartAST,{...layout,"namedProp": "child" });
325 |
326 | // myDartAST.properties.push({ ...layout, "namedProp": "child" })
327 |
328 | }
329 | }
330 |
331 | }
332 |
333 | buildDartASTfromAST(expression, myDartAST);
334 |
335 | createFlutterWidget(myDartAST, count);
336 | } catch (error) {
337 |
338 | console.log(error);
339 | code = error as string;
340 | }
341 | code += ');\n'
342 |
343 | } catch (error) {
344 | code = error as string
345 | }
346 | return code;
347 | }
348 |
349 |
--------------------------------------------------------------------------------
/src/utils/arr.js:
--------------------------------------------------------------------------------
1 | const split2Arr = (val, sign = ")") => {
2 | const arr = val.split(`${sign} `);
3 | for (let i = 0; i < arr.length; i++) {
4 | const str = arr[i];
5 | const reg = new RegExp(`\\${sign}$`, "gi");
6 | if (!reg.test(str)) arr[i] = str + sign;
7 | }
8 | return arr;
9 | };
10 |
11 | export { split2Arr };
12 |
--------------------------------------------------------------------------------
/src/utils/camel.ts:
--------------------------------------------------------------------------------
1 | export const toCamel = (val:any) => {
2 | let re = /-(\w)/g;
3 | return val.replace(re, function ($1:any) {
4 | return $1.toUpperCase();
5 | });
6 | };
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/utils/converter.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | export const getColor = (value: string) => {
4 | let color = value.replace("#", "0xff");
5 | return color
6 |
7 | };
8 |
9 |
10 | export const toDouble = (value: any) => {
11 |
12 | return parseFloat(value).toFixed(1)
13 | }
14 |
15 | export const toInt = (value: any) => {
16 | if(typeof value === "string"){
17 | if (value.indexOf("#") === 0) {
18 | value = value.replace("#", "0xff");
19 | return value
20 | }
21 | } else if(typeof value === "number"){
22 | return value;
23 | }
24 |
25 | return parseInt(value);
26 |
27 | }
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/utils/getAlignmentAxis.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { flutterWidget } from "../config/flutter-widgets";
3 | import { toCamel } from "./camel";
4 | import { pushPropToWidget } from "./pushPropToWidget";
5 |
6 |
7 |
8 | export const getAlignmentAxis = (styles: any, object: any, ast: any) => {
9 |
10 | let layoutWidget: any = { ...flutterWidget.Row };
11 | //layoutWidget.properties = [];
12 | if (styles.hasOwnProperty("flexDirection")) {
13 | if (styles.flexDirection === "column") {
14 |
15 | layoutWidget = { ...flutterWidget.Column };
16 |
17 | }
18 | }
19 |
20 | if (object.hasOwnProperty("value")) {
21 | object = { ...object, value: object.value.replace(/flex-/, "") };
22 |
23 | object = { ...object, value: toCamel(object.value) };
24 | object = { ...object, value: object.value.replace(/-/, "") };
25 | }
26 |
27 |
28 | let index = layoutWidget.properties.findIndex((data: any) => (data.class === object.class));
29 | if (index > -1) {
30 |
31 | layoutWidget.properties.splice(index, 1);
32 | }
33 |
34 |
35 | if (object.hasOwnProperty("value")) {
36 | layoutWidget.properties.push(object);
37 | }
38 |
39 | layoutWidget["namedProp"] = "child";
40 |
41 |
42 | pushPropToWidget(ast, layoutWidget, flutterWidget.Container.class);
43 |
44 |
45 | object = ast;
46 |
47 | return { nested: true, object };
48 | };
49 |
--------------------------------------------------------------------------------
/src/utils/getBorder.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 | import { dartType } from "../config/layout-props";
3 |
4 |
5 |
6 |
7 | export const getBorder = (styles: any, object: any) => {
8 |
9 | object.properties = [];
10 | if (styles.hasOwnProperty("borderWidth")) {
11 |
12 |
13 | let widget: any = dartType.double;
14 | widget.value = styles["borderWidth"];
15 | widget = { ...widget, namedProp: "width" };
16 | object.properties.push(widget);
17 |
18 | if (styles.hasOwnProperty("borderColor")) {
19 | let widget: any = flutterWidget.Color;
20 | widget.value = styles["borderColor"];
21 | object.properties.push(widget);
22 | }
23 |
24 | }
25 |
26 | else if (styles.borderEndWidth || styles.borderStartWidth) {
27 |
28 | object.properties = [];
29 | if (styles.hasOwnProperty("borderEndWidth")) {
30 |
31 | object.class = "BorderDirectional";
32 | let widget: any = flutterWidget.BorderEndWidth;
33 | widget.properties = [];
34 | widget = { ...widget, namedProp: "end" };
35 | let prop: any = dartType.double;
36 | prop.value = styles["borderEndWidth"];
37 | prop = { ...prop, namedProp: "width" };
38 |
39 | if (styles.hasOwnProperty("borderColor")) {
40 | let color: any = flutterWidget.Color;
41 | color.value = styles["borderColor"];
42 | widget.properties.push(color);
43 | }
44 | widget.properties.push(prop);
45 | object.properties.push(widget);
46 | }
47 |
48 | if (styles.hasOwnProperty("borderStartWidth")) {
49 |
50 | object.class = "BorderDirectional";
51 | let widget: any = flutterWidget.BorderStartWidth;
52 | widget.properties = [];
53 | widget = { ...widget, namedProp: "start" };
54 | let prop: any = dartType.double;
55 | prop.value = styles["borderStartWidth"];
56 | prop = { ...prop, namedProp: "width" };
57 |
58 | if (styles.hasOwnProperty("borderColor")) {
59 | let color: any = flutterWidget.Color;
60 | color.value = styles["borderColor"];
61 | widget.properties.push(color);
62 | }
63 | widget.properties.push(prop);
64 | object.properties.push(widget);
65 | }
66 |
67 | if (styles.hasOwnProperty("borderTopWidth")) {
68 |
69 |
70 | object.class = "BorderDirectional";
71 | let widget: any = flutterWidget.BorderTopWidth;
72 | widget.properties = [];
73 | widget = { ...widget, namedProp: "top" };
74 | let prop: any = dartType.double;
75 | prop.value = styles["borderTopWidth"];
76 | prop = { ...prop, namedProp: "width" };
77 |
78 | if (styles.hasOwnProperty("borderColor")) {
79 | let color: any = flutterWidget.Color;
80 | color.value = styles["borderColor"];
81 | widget.properties.push(color);
82 | }
83 | widget.properties.push(prop);
84 | object.properties.push(widget);
85 | }
86 |
87 | if (styles.hasOwnProperty("borderBottomWidth")) {
88 |
89 |
90 | object.class = "BorderDirectional";
91 | let widget: any = flutterWidget.BorderBottomWidth;
92 | widget.properties = [];
93 | widget = { ...widget, namedProp: "bottom" };
94 | let prop: any = dartType.double;
95 | prop.value = styles["borderBottomWidth"];
96 | prop = { ...prop, namedProp: "width" };
97 |
98 | if (styles.hasOwnProperty("borderColor")) {
99 | let color: any = flutterWidget.Color;
100 | color.value = styles["borderColor"];
101 | widget.properties.push(color);
102 | }
103 | widget.properties.push(prop);
104 | object.properties.push(widget);
105 | }
106 |
107 | } else {
108 |
109 | if (styles.hasOwnProperty("borderBottomWidth")) {
110 |
111 | object.properties = [];
112 | object.class = "Border";
113 | let widget: any = flutterWidget.BorderBottomWidth;
114 | widget.properties = [];
115 | widget = { ...widget, namedProp: "bottom" };
116 | let prop: any = dartType.double;
117 | prop.value = styles["borderBottomWidth"];
118 | prop = { ...prop, namedProp: "width" };
119 |
120 | if (styles.hasOwnProperty("borderColor")) {
121 | let color: any = flutterWidget.Color;
122 | color.value = styles["borderColor"];
123 | widget.properties.push(color);
124 | }
125 | widget.properties.push(prop);
126 | object.properties.push(widget);
127 | }
128 |
129 | if (styles.hasOwnProperty("borderTopWidth")) {
130 |
131 |
132 | object.class = "Border";
133 | let widget: any = flutterWidget.BorderBottomWidth;
134 | widget.properties = [];
135 | widget = { ...widget, namedProp: "top" };
136 | let prop: any = dartType.double;
137 | prop.value = styles["borderTopWidth"];
138 | prop = { ...prop, namedProp: "width" };
139 |
140 | if (styles.hasOwnProperty("borderColor")) {
141 | let color: any = flutterWidget.Color;
142 | color.value = styles["borderColor"];
143 | widget.properties.push(color);
144 | }
145 | widget.properties.push(prop);
146 | object.properties.push(widget);
147 | }
148 |
149 | if (styles.hasOwnProperty("borderLeftWidth")) {
150 |
151 |
152 | object.class = "Border";
153 | let widget: any = flutterWidget.BorderBottomWidth;
154 | widget.properties = [];
155 | widget = { ...widget, namedProp: "left" };
156 | let prop: any = dartType.double;
157 | prop.value = styles["borderLeftWidth"];
158 | prop = { ...prop, namedProp: "width" };
159 |
160 | if (styles.hasOwnProperty("borderColor")) {
161 | let color: any = flutterWidget.Color;
162 | color.value = styles["borderColor"];
163 | widget.properties.push(color);
164 | }
165 | widget.properties.push(prop);
166 | object.properties.push(widget);
167 | }
168 |
169 | if (styles.hasOwnProperty("borderRightWidth")) {
170 |
171 |
172 | object.class = "Border";
173 | let widget: any = flutterWidget.BorderBottomWidth;
174 | widget.properties = [];
175 | widget = { ...widget, namedProp: "right" };
176 | let prop: any = dartType.double;
177 | prop.value = styles["borderRightWidth"];
178 | prop = { ...prop, namedProp: "width" };
179 |
180 | if (styles.hasOwnProperty("borderColor")) {
181 | let color: any = flutterWidget.Color;
182 | color.value = styles["borderColor"];
183 | widget.properties.push(color);
184 | }
185 | widget.properties.push(prop);
186 | object.properties.push(widget);
187 | }
188 | }
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | return object;
198 | };
199 |
--------------------------------------------------------------------------------
/src/utils/getBorderRadius.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 |
3 |
4 |
5 |
6 | export const getBorderRadius = (styles: any, object: any) => {
7 |
8 | object.properties = [];
9 |
10 | if (styles.hasOwnProperty("borderRadius")) {
11 |
12 | delete object.properties;
13 | } else if (styles.hasOwnProperty("borderEndWidth") || styles.hasOwnProperty("borderEndWidth")) {
14 | } else {
15 |
16 | if (styles.hasOwnProperty("borderTopLeftRadius")) {
17 | let widget: any = {...flutterWidget.RadiusCircular};
18 | widget = { ...widget, namedProp: "topLeft",value:{value:styles["borderTopLeftRadius"]} };
19 |
20 | object.properties.push(widget);
21 |
22 | }
23 | if (styles.hasOwnProperty("borderTopRightRadius")) {
24 |
25 | let widget: any = flutterWidget.RadiusCircular;
26 | //widget.value.value = styles["borderTopRightRadius"];
27 |
28 | widget = { ...widget, namedProp: "topRight",value:{value:styles["borderTopRightRadius"],...widget.value} };
29 | object.properties.push(widget);
30 | }
31 |
32 | if (styles.hasOwnProperty("borderBottomRightRadius")) {
33 | let widget: any = flutterWidget.RadiusCircular;
34 | widget.value.value = styles["borderBottomRightRadius"];
35 | widget["namedProp"] = "bottomRight";
36 | object.properties.push(widget);
37 |
38 | }
39 |
40 | if (styles.hasOwnProperty("borderBottomLeftRadius")) {
41 |
42 | let widget: any = flutterWidget.RadiusCircular;
43 | widget.value.value = styles["borderBottomLeftRadius"];
44 | widget = { ...widget, namedProp: "bottomLeft" };
45 | object.properties.push(widget);
46 | }
47 | }
48 |
49 |
50 | return object;
51 | };
52 |
--------------------------------------------------------------------------------
/src/utils/getExpanded.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 | import { dartType } from "../config/layout-props";
3 |
4 |
5 |
6 | export const getExpanded = (styles: any, object: any, ast?: any) => {
7 | let widget: any = {};
8 | if (styles.hasOwnProperty("flexGrow")) {
9 |
10 | widget = {...flutterWidget.Expanded};
11 | widget.properties = [];
12 | let flex: any = {};
13 | flex = dartType.int;
14 | flex = { ...flex, value: styles.flexGrow };
15 | flex["namedProp"] = "flex";
16 |
17 | let index = widget.properties.findIndex((data: any) => (data.class === widget.class));
18 | if (index)
19 | if (index > -1) {
20 |
21 | widget.properties.splice(index, 1);
22 | }
23 | widget.properties.push(flex);
24 | console.log(object);
25 | console.log(ast);
26 | if (ast.class === "Container") {
27 | delete widget.namedProp;
28 | //ast = widget;
29 | widget.properties.push({namedProp:"child",...ast})
30 | object = widget;
31 | return { nested: true, object };
32 | } else {
33 | searchForContainer(ast);
34 | }
35 |
36 | ast.properties = [];
37 | ast.properties.push(widget);
38 |
39 | object = ast;
40 | return { nested: true, object };
41 |
42 | } else {
43 | return object;
44 | }
45 |
46 | function searchForContainer(_ast: any) {
47 | if (_ast.properties) {
48 | Object.entries(_ast.properties).forEach(([, v]: any) => {
49 |
50 | if (v.class === "Container") {
51 | widget["namedProp"] = "child";
52 | widget.properties.push(v);
53 | } else {
54 | searchForContainer(v);
55 | }
56 | });
57 | }
58 |
59 | }
60 | };
61 |
--------------------------------------------------------------------------------
/src/utils/getFlex.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 | import { dartType } from "../config/layout-props";
3 |
4 |
5 |
6 | export const getFlex = (styles: any, object: any, ast?: any) => {
7 |
8 | let widget: any = {};
9 | if (styles.hasOwnProperty("flex")) {
10 | widget = {...flutterWidget.Flex};
11 | widget.properties = [];
12 | let flex: any = {};
13 | flex = dartType.double;
14 | flex = { ...flex, value: styles.flex };
15 | flex["namedProp"] = "flex1";
16 | let index = widget.properties.findIndex((data: any) => (data.class === widget.class));
17 |
18 | if (index > -1) {
19 |
20 | widget.properties.splice(index, 1);
21 | }
22 | widget.properties.push(flex);
23 | console.log(object);
24 | console.log(ast);
25 | if (ast.class === "Container") {
26 | delete widget.namedProp;
27 | ast = widget;
28 | object = ast;
29 | return { nested: true, object };
30 | } else {
31 | searchForContainer(ast);
32 | }
33 | ast.properties = [];
34 | ast.properties.push(widget);
35 |
36 | object = ast;
37 | return { nested: true, object };
38 | } else {
39 | return object;
40 | }
41 |
42 | function searchForContainer(_ast: any) {
43 | if (_ast.properties) {
44 | Object.entries(_ast.properties).forEach(([, v]: any) => {
45 |
46 | if (v.class === "Container") {
47 | widget["namedProp"] = "child";
48 | widget.properties.push(v);
49 | } else {
50 | searchForContainer(v);
51 | }
52 | });
53 | }
54 |
55 | }
56 | };
57 |
--------------------------------------------------------------------------------
/src/utils/getFlexDirection.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 | import { pushPropToWidget } from "./pushPropToWidget";
3 |
4 | export const getFlexDirection = (styles: any, object: any={}, ast: any) => {
5 |
6 | let layoutWidget: any = { ...flutterWidget.Row };
7 | layoutWidget.properties = [];
8 | if (styles.hasOwnProperty("flexDirection")) {
9 | if (styles.flexDirection === "column") {
10 |
11 | layoutWidget = { ...flutterWidget.Column };
12 |
13 | }
14 | }
15 |
16 | let index = layoutWidget.properties.findIndex((data: any) => (data.class === object.class));
17 | if (index > -1) {
18 |
19 | layoutWidget.properties.splice(index, 1);
20 | }
21 |
22 |
23 |
24 | layoutWidget.properties.push(object);
25 |
26 |
27 | layoutWidget["namedProp"] = "child";
28 |
29 | let rowOrColIndex = ast.properties.findIndex((data: any) => (data.class === "Row" || data.class === "Column"));
30 | console.log(rowOrColIndex);
31 |
32 | pushPropToWidget(ast, layoutWidget, flutterWidget.Container.class);
33 |
34 |
35 | object = ast;
36 |
37 | return { nested: true, object };
38 | }
39 |
--------------------------------------------------------------------------------
/src/utils/getFontFamily.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | export const getFontFamily = (styles: any, object: any) => {
4 |
5 |
6 | object = { ...object, value: styles.fontFamily };
7 | return object;
8 | };
9 |
--------------------------------------------------------------------------------
/src/utils/getFontStyle.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | export const getFontStyle = (styles: any, object: any) => {
8 | switch (styles.fontStyle) {
9 | case "italic":
10 | object = {...object,value:"italic"}
11 |
12 | break;
13 | case "normal":
14 | object = {...object,value:"normal"}
15 |
16 |
17 | break;
18 | default:
19 | object = {...object,value:"normal"}
20 |
21 |
22 | break;
23 | }
24 |
25 | return object;
26 | };
27 |
--------------------------------------------------------------------------------
/src/utils/getFontWeight.tsx:
--------------------------------------------------------------------------------
1 | import { isNumerical } from "./unit";
2 |
3 |
4 |
5 | export const getFontWeight = (styles: any, object: any) => {
6 |
7 | if (isNumerical(styles.fontWeight)) {
8 | object.value = 'w' + styles.fontWeight;
9 | } else {
10 | object.value = styles.fontWeight;
11 | }
12 | return object;
13 | };
14 |
--------------------------------------------------------------------------------
/src/utils/getMargin.tsx:
--------------------------------------------------------------------------------
1 | import { dartType } from "../config/layout-props";
2 |
3 |
4 |
5 |
6 | export const getMargin = (styles: any, object: any) => {
7 | object.properties = [];
8 |
9 | if (styles.hasOwnProperty("margin")) {
10 |
11 | delete object.properties;
12 | } else if(styles.marginStart || styles.marginEnd){
13 | object.class = "EdgeInsetsDirectional.only";
14 | if (styles.hasOwnProperty("marginStart")) {
15 |
16 | let widget: any = dartType.double;
17 | widget.value = styles["marginStart"];
18 | widget = { ...widget, namedProp: "start" };
19 | object.properties.push(widget);
20 |
21 | }
22 |
23 | if (styles.hasOwnProperty("marginEnd")) {
24 |
25 | let widget: any = dartType.double;
26 | widget.value = styles["marginEnd"];
27 | widget = { ...widget, namedProp: "end" };
28 | object.properties.push(widget);
29 |
30 | }
31 |
32 | if (styles.hasOwnProperty("marginTop")) {
33 |
34 | let widget: any = dartType.double;
35 | widget.value = styles["marginTop"];
36 | widget = { ...widget, namedProp: "top" };
37 | object.properties.push(widget);
38 |
39 | }
40 |
41 | if (styles.hasOwnProperty("marginBottom")) {
42 |
43 | let widget: any = dartType.double;
44 | widget.value = styles["marginBottom"];
45 | widget = { ...widget, namedProp: "bottom" };
46 | object.properties.push(widget);
47 |
48 | }
49 |
50 | }
51 | else {
52 |
53 |
54 | object.class = "EdgeInsets.only";
55 | if (styles.hasOwnProperty("marginLeft") || styles.marginHorizontal) {
56 |
57 | let widget: any = dartType.double;
58 | widget.value = styles["marginLeft"] ?? styles.marginHorizontal;
59 | widget = { ...widget, namedProp: "left" };
60 | object.properties.push(widget);
61 |
62 | }
63 |
64 | if (styles.hasOwnProperty("marginRight") || styles.marginHorizontal) {
65 |
66 | let widget: any = dartType.double;
67 | widget.value = styles["marginRight"] ?? styles.marginHorizontal;
68 | widget = { ...widget, namedProp: "right" };
69 | object.properties.push(widget);
70 |
71 | }
72 |
73 | if (styles.hasOwnProperty("marginTop") || styles.marginVertical) {
74 |
75 | let widget: any = dartType.double;
76 | widget.value = styles["marginTop"] ?? styles.marginVertical;
77 | widget = { ...widget, namedProp: "top" };
78 | object.properties.push(widget);
79 |
80 | }
81 |
82 | if (styles.hasOwnProperty("marginBottom") || styles.marginVertical) {
83 |
84 | let widget: any = dartType.double;
85 | widget.value = styles["marginBottom"] ?? styles.marginVertical;
86 | widget = { ...widget, namedProp: "bottom" };
87 | object.properties.push(widget);
88 |
89 | }
90 |
91 | }
92 |
93 | return object;
94 | };
95 |
--------------------------------------------------------------------------------
/src/utils/getPadding.tsx:
--------------------------------------------------------------------------------
1 | import { dartType } from "../config/layout-props";
2 |
3 |
4 |
5 | export const getPadding = (styles: any, object: any) => {
6 | object.properties = [];
7 |
8 | if (styles.hasOwnProperty("padding")) {
9 |
10 | delete object.properties;
11 | }
12 | else {
13 |
14 | object.class = "EdgeInsets.only";
15 | if (styles.hasOwnProperty("paddingLeft") || styles.hasOwnProperty("paddingHorizontal")) {
16 |
17 | let widget: any = dartType.double;
18 | widget.value = styles["paddingLeft"] ?? styles["paddingHorizontal"];
19 | widget = { ...widget, namedProp: "left" };
20 | object.properties.push(widget);
21 |
22 | }
23 |
24 | if (styles.hasOwnProperty("paddingRight")|| styles.hasOwnProperty("paddingHorizontal")) {
25 |
26 | let widget: any = dartType.double;
27 | widget.value = styles["paddingRight"]?? styles["paddingHorizontal"];;
28 | widget = { ...widget, namedProp: "right" };
29 | object.properties.push(widget);
30 |
31 | }
32 |
33 | if (styles.hasOwnProperty("paddingTop") || styles.hasOwnProperty("paddingVertical")) {
34 |
35 | let widget: any = dartType.double;
36 | widget.value = styles["paddingTop"] ?? styles["paddingVertical"];;
37 | widget = { ...widget, namedProp: "top" };
38 | object.properties.push(widget);
39 |
40 | }
41 |
42 | if (styles.hasOwnProperty("paddingBottom") || styles.hasOwnProperty("paddingVertical")) {
43 |
44 | let widget: any = dartType.double;
45 | widget.value = styles["paddingBottom"]?? styles["paddingVertical"];
46 | widget = { ...widget, namedProp: "bottom" };
47 | object.properties.push(widget);
48 |
49 | }
50 |
51 | }
52 |
53 | return object;
54 | };
55 |
--------------------------------------------------------------------------------
/src/utils/getPositioned.tsx:
--------------------------------------------------------------------------------
1 | import { flutterWidget } from "../config/flutter-widgets";
2 | import { dartType } from "../config/layout-props";
3 |
4 |
5 |
6 | export const getPositioned = (styles: any, object: any, ast?: any) => {
7 |
8 | object.properties = [];
9 | if (styles.hasOwnProperty("position")) {
10 | if (styles["position"] === "absolute") {
11 | console.log(object);
12 | console.log(ast);
13 | ast["namedProp"] = "child";
14 |
15 | delete object.namedProp;
16 |
17 | if (styles.top) {
18 | let top: any = dartType.double;
19 |
20 |
21 | top = { ...top, "namedProp": "top", value: styles.top };
22 | object.properties.push(top);
23 |
24 | }
25 | if (styles.bottom) {
26 | let bottom: any = dartType.double;
27 | bottom = { ...bottom, "namedProp": "bottom", value: styles.bottom };
28 | object.properties.push(bottom);
29 |
30 | }
31 |
32 | if (styles.left) {
33 | let left: any = dartType.double;
34 |
35 | left = { ...left, "namedProp": "left", value: styles.left };
36 | object.properties.push(left);
37 |
38 | }
39 | if (styles.right) {
40 | let right: any = dartType.double;
41 |
42 |
43 | right = { ...right, "namedProp": "right", value: styles.right };
44 | object.properties.push(right);
45 |
46 | }
47 | object.properties.push(ast);
48 | let stack:any = {...flutterWidget.Stack}
49 | stack.properties = [];
50 | stack.properties.push({ namedProp: "children", type: "Array", values: [object] })
51 | object = stack
52 | return { nested: true, object };
53 | }
54 | } else {
55 | return object;
56 | }
57 | };
58 |
--------------------------------------------------------------------------------
/src/utils/getTextAlign.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | export const getTextAlign = (styles: any, object: any) => {
4 | object.value = styles.textAlign;
5 | return object;
6 | };
7 |
--------------------------------------------------------------------------------
/src/utils/num.ts:
--------------------------------------------------------------------------------
1 | import ppo from "ppo";
2 | import toNumber from "lodash/toNumber";
3 | import isNumber from "lodash/isNumber";
4 |
5 | const isMulti = (key:any) => {
6 | if (key.indexOf("|") > 0) return true;
7 | else return false;
8 | };
9 |
10 | const findSimilarNumber = (n:any, rule:any) => {
11 | if (rule[n + ""]) return n;
12 |
13 | const nums = [];
14 | for (let key in rule) {
15 | nums.push(parseInt(key));
16 | }
17 | nums.sort((n1, n2) => n2 - n1);
18 |
19 | for (let i = 0; i < nums.length; i++) {
20 | const num = nums[i];
21 | if (n > num) return num;
22 | }
23 |
24 | return 0;
25 | };
26 |
27 | const isNone = (val:any) => {
28 | if (!val) return true;
29 |
30 | if (typeof val === "string") {
31 | if (val.trim() === "") return true;
32 | if (val === "null") return true;
33 | if (val === "none") return true;
34 | if (val === "inhert") return true;
35 | }
36 |
37 | return false;
38 | };
39 |
40 | const toNum = (val:any) => {
41 | if (isNumber(val)) return val;
42 |
43 | const r = /([-0-9.]+)[a-zA-Z%]/gi.exec(`${val}c`);
44 | if (r && r.length >= 2) {
45 | val = r[1];
46 | val = isNumber(val) ? val : parseFloat(val);
47 | return val;
48 | } else {
49 | return toNumber(val);
50 | }
51 | };
52 |
53 | const toRadian = (val:any, fl = 3) => {
54 | let radian = val.toString().replace(/deg$/g, "");
55 | radian = (radian * Math.PI) / 180;
56 | return ppo.floor(radian, fl);
57 | };
58 |
59 | const toRound = (val:any, n = 3) => {
60 | const d = Math.pow(10, n);
61 | const num = Math.round(val * d);
62 | return num / d;
63 | };
64 |
65 | export { isMulti, isNone, toNum, findSimilarNumber, toRadian, toRound };
66 |
--------------------------------------------------------------------------------
/src/utils/pos.js:
--------------------------------------------------------------------------------
1 | import toCamel from "./camel";
2 |
3 | const isPercentage = val => {
4 | if (val.indexOf("%") > 0) {
5 | return true;
6 | }
7 | return false;
8 | };
9 |
10 | const isName = val => {
11 | const keynames = "left|center|bottom|top|right".split("|");
12 | for (let i = 0; i < keynames.length; i++) {
13 | if (val.indexOf(keynames[i]) === 0) {
14 | return true;
15 | }
16 | }
17 | return false;
18 | };
19 |
20 | // 0% 50% -> leftCenter
21 | // center left -> centerLeft
22 | const toNameVal = val => {
23 | let result = "";
24 | if (isPercentage(val)) {
25 | const arr = val.split(" ");
26 | for (let i = 0; i < arr.length; i++) {
27 | if (i === 0) {
28 | if (arr[i] === "0%") {
29 | result += "top";
30 | } else if (arr[i] === "50%") {
31 | result += "center";
32 | } else {
33 | result += "bottom";
34 | }
35 | } else {
36 | if (arr[i] === "0%") {
37 | result += "-left";
38 | } else if (arr[i] === "50%") {
39 | result += "-center";
40 | } else {
41 | result += "-right";
42 | }
43 | }
44 | }
45 | } else {
46 | result.replace(/\s/gi, "-");
47 | }
48 |
49 | result = toCamel(result);
50 | result = result === "centerCenter" ? "center" : result;
51 | return result;
52 | };
53 |
54 | export { isPercentage, isName, toNameVal };
55 |
--------------------------------------------------------------------------------
/src/utils/pushPropToWidget.tsx:
--------------------------------------------------------------------------------
1 |
2 | export function pushPropToWidget(ast: any, layoutWidget: any,widget:string) {
3 |
4 | if(layoutWidget.nested){
5 | ast = layoutWidget.object;
6 | return ast;
7 | }else {
8 | if (ast.class === widget) {
9 | let index = ast.properties.findIndex((data: any) => (data.namedProp === layoutWidget.namedProp));
10 | if (index < 0) {
11 | ast.properties.push(layoutWidget);
12 | }
13 |
14 | } else {
15 | searchWidgetAndPush(ast.properties);
16 | }
17 | }
18 |
19 |
20 | function searchWidgetAndPush(prop:any) {
21 | Object.entries(prop).forEach(([, v]: any) => {
22 | if (v.class === widget) {
23 |
24 | let index = v.properties.findIndex((data: any) => (data.namedProp === layoutWidget.namedProp));
25 | if (index < 0) {
26 | v.properties.push(layoutWidget);
27 | }
28 | } else {
29 | if(v.hasOwnProperty("properties")){
30 | searchWidgetAndPush(v.properties);
31 | }
32 |
33 | }
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/utils/str.js:
--------------------------------------------------------------------------------
1 | const addQuotes = str => {
2 | if (!/^("|')/gi.test(str)) {
3 | str = `"${str}"`;
4 | }
5 | return str;
6 | };
7 |
8 | const getLast = str => {
9 | return str.charAt(str.length - 1);
10 | };
11 |
12 | export { addQuotes, getLast };
13 |
--------------------------------------------------------------------------------
/src/utils/unit.ts:
--------------------------------------------------------------------------------
1 | const isNumerical = (val:string) => /^([0-9]+)$/gi.test(val.toString()) ;
2 |
3 | const isPercentage = (val:string) => /([0-9]+)%$/gi.test(val);
4 |
5 | const isPixel = (val:string) => /([0-9]+)(px|dpx)$/gi.test(val);
6 |
7 | const isEm = (val:string) => /([0-9]+)em$/gi.test(val);
8 |
9 | const isRem = (val:string) => /([0-9]+)rem$/gi.test(val);
10 |
11 | const isPt = (val:string) => /([0-9]+)pt$/gi.test(val);
12 |
13 | export { isNumerical, isPercentage, isPixel, isPt, isEm, isRem };
14 |
--------------------------------------------------------------------------------
/test/blah.test.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import { Thing } from '../src';
4 |
5 | describe('it', () => {
6 | it('renders without crashing', () => {
7 | const div = document.createElement('div');
8 | ReactDOM.render( , div);
9 | ReactDOM.unmountComponentAtNode(div);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
3 | "include": ["src", "types"],
4 | "compilerOptions": {
5 | "module": "esnext",
6 | "lib": ["dom", "esnext"],
7 | "importHelpers": true,
8 | // output .d.ts declaration files for consumers
9 | "declaration": true,
10 | // output .js.map sourcemap files for consumers
11 | "sourceMap": true,
12 | // match output dir to input dir. e.g. dist/index instead of dist/src/index
13 | "rootDir": "./src",
14 | // stricter type-checking for stronger correctness. Recommended by TS
15 | "strict": true,
16 | // linter checks for common issues
17 | "noImplicitReturns": true,
18 | "noFallthroughCasesInSwitch": true,
19 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | // use Node's module resolution algorithm, instead of the legacy TS one
23 | "moduleResolution": "node",
24 | // transpile JSX to React.createElement
25 | "jsx": "react",
26 | // interop between ESM and CJS modules. Recommended by TS
27 | "esModuleInterop": true,
28 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
29 | "skipLibCheck": true,
30 | // error out if import and file system have a casing mismatch. Recommended by TS
31 | "forceConsistentCasingInFileNames": true,
32 | // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc`
33 | "noEmit": true,
34 | }
35 | }
36 |
--------------------------------------------------------------------------------