Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #616 from Parabeac/release/2.5.0
Browse files Browse the repository at this point in the history
Release/2.5.0
  • Loading branch information
ivan-015 committed Mar 13, 2022
2 parents b498860 + bc7b649 commit c13cbf4
Show file tree
Hide file tree
Showing 62 changed files with 1,051 additions and 396 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "pbdl"]
path = pbdl
url = https://github.com/Parabeac/pbdl
63 changes: 31 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,66 +44,61 @@ The handoff between designers & developers is one of the most costly and frustra

### Dependencies

- [Dart](https://dart.dev/get-dart)
- [Flutter](https://flutter.dev/docs/get-started/install)
- [node.js](https://nodejs.org/en/download/)
- [Figma File](https://figma.com) - [Sample](https://www.figma.com/file/Ysnjcij14HaE98ucq1iwW1/Parabeac-Counter-App-Demo?node-id=0%3A1)
- [Dart](https://dart.dev/get-dart)
- [Flutter](https://flutter.dev/docs/get-started/install)
- [node.js](https://nodejs.org/en/download/)
- [Figma File](https://figma.com) - [Sample](https://www.figma.com/file/Ysnjcij14HaE98ucq1iwW1/Parabeac-Counter-App-Demo?node-id=0%3A1)

## Cloning parabeac_core
Because parabeac_core contains submodules, it is easiest to clone using the following command:
```
git clone --recurse-submodules https://github.com/Parabeac/parabeac_core.git
```

If you have already cloned you may need to pull the submodules:
```
git submodule update --init
```

**_Run the following command to update the submodules:_**

```
git pull --recurse-submodules
```
## Running parabeac_core

### Figma
In your terminal, change your directory to the root parabeac_core directory and run:

``` bash
In your terminal, change your directory to the root parabeac_core directory and run:

```bash
$ pub get
$ dart parabeac.dart -f <Figma File ID> -k <Figma API Key> -o <Absolute Path To Output Directory>
$ dart parabeac.dart -f <Figma File ID> -k <Figma API Key> -o <Absolute Path To Output Directory>
```

#### Figma File ID (Required): -f

1. Visit https://figma.com and log in.
2. Select your Design File
3. The file ID is contained in the URL of your design file immediately after figma.com/file/`<fileID>`/.

*Example: The file ID for ```https://www.figma.com/file/Ysnjcij14HaE98ucq1iwW1/Parabeac-Counter-App-Demo``` is ```Ysnjcij14HaE98ucq1iwW1```*
3. The file ID is contained in the URL of your design file immediately after figma.com/file/`<fileID>`/.

_Example: The file ID for `https://www.figma.com/file/Ysnjcij14HaE98ucq1iwW1/Parabeac-Counter-App-Demo` is `Ysnjcij14HaE98ucq1iwW1`_

#### Figma API Key (Required): -k

1. Visit https://figma.com and log in.
2. Navigate to your user profile and select `Settings`
3. Scroll Down to the "Create a new Personal Access Token"
4. Create a new Personal Access Token and copy your new API key. (It should look something like this: ```64522-a0e5509a-d5ce-47a8-880b-c295f9cb27ed```)
4. Create a new Personal Access Token and copy your new API key. (It should look something like this: `64522-a0e5509a-d5ce-47a8-880b-c295f9cb27ed`)

#### Name (Optional): -n
Sets the name of the exported project. For instance, if you want to name your project "cool_project", set the `-n` flag to `cool_project`. *Note: parabeac_core can only use [valid Flutter project names](https://dart.dev/tools/pub/pubspec#name).*

Sets the name of the exported project. For instance, if you want to name your project "cool_project", set the `-n` flag to `cool_project`. _Note: parabeac_core can only use [valid Flutter project names](https://dart.dev/tools/pub/pubspec#name)._

#### Absolute Path (Optional): -o

Specifies the absolute path of the exported Flutter Project to be created. For instance, to export your Flutter project in the Documents folder, set your `-o` flag to `/Users/ParabeacUser/Documents/` Not setting this will export the project in the parabeac_core directory.

### Sketch
Due to the lack of requested support for Sketch and the major updates to this project, we temporarily stopped support for Sketch.

Due to the lack of requested support for Sketch and the major updates to this project, we temporarily stopped support for Sketch.

# Running the generated code
We recommend following our [Hello World guide](https://docs.parabeac.com/docs/hello-world-guide) but if you feel experienced enough with Flutter, feel free to jump right in here:

We recommend following our [Hello World guide](https://docs.parabeac.com/docs/hello-world-guide) but if you feel experienced enough with Flutter, feel free to jump right in here:

### Running a Figma Frame/Screen
![Figma Frame Example](https://github.com/Parabeac/parabeac_core/blob/stable/repo_assets/figma_frame_example.png?raw=true)
#### Steps

1. Open your generated project (Will be at the absolute path you set or in the parabeac_core directory)
2. If your frame was designed to be a screen, you can quickly test it by editing the MaterialApp widget in main.dart like the following:
``` class MyApp extends StatelessWidget {

```class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
Expand All @@ -116,12 +111,15 @@ We recommend following our [Hello World guide](https://docs.parabeac.com/docs/he
}
}
```
3. Save `main.dart` and execute `flutter run`

3. Save `main.dart` and execute `flutter run`

### Running a Figma Component
![Figma Component Example](https://raw.githubusercontent.com/Parabeac/parabeac_core/stable/repo_assets/figma_component_example.png)

1. Navigate to a widget/screen where you can add in your component as a child.
2. Reference the component by providing a LayoutBuilder widget like the following:

```
Container(
child: LayoutBuilder(builder: (context, constraints) {
Expand All @@ -131,6 +129,7 @@ Container(
})
)
```

1. Save the class and execute `flutter run` in your terminal & navigate your app to the expected location where the component should show up.


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class WidgetBookFolder extends IsolationNode {
WidgetbookFolder(
name: '$name',
${genWidgets.isNotEmpty ? 'widgets: [\n$genWidgets\n],\n' : ''}
)
),
''';
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart';
import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/container.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart';
import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart';

class PBBoxDecorationHelper extends PBAttributesHelper {
Expand All @@ -15,30 +13,49 @@ class PBBoxDecorationHelper extends PBAttributesHelper {
final buffer = StringBuffer();
buffer.write('decoration: BoxDecoration(');
var borderInfo = source.auxiliaryData.borderInfo;
if (source.auxiliaryData.color != null) {
var effectsInfo = source.auxiliaryData.effects;
var colors = source.auxiliaryData.colors;
if (colors != null && colors.isNotEmpty) {
buffer.write(PBColorGenHelper().generate(source, generatorContext));
}
if (borderInfo != null) {
if (borderInfo.shape == 'circle') {
buffer.write('shape: BoxShape.circle,');
} else if (borderInfo.borderRadius != null) {
if (borderInfo.borderRadius != null) {
// Write border radius if it exists
buffer.write(
'borderRadius: BorderRadius.all(Radius.circular(${borderInfo.borderRadius})),');
// Write border outline properties if applicable
if (borderInfo.isBorderOutlineVisible &&
(borderInfo.color != null || borderInfo.thickness != null)) {
buffer.write('border: Border.all(');
if (borderInfo.color != null) {
buffer.write('color: Color(${borderInfo.color.toString()}),');
}
if (borderInfo.thickness != null) {
buffer.write('width: ${borderInfo.thickness},');
}
buffer.write('),'); // end of Border.all(
} else if (borderInfo.type == 'circle') {
buffer.write('shape: BoxShape.circle,');
}

// Write border outline properties if applicable
if (borderInfo.thickness > 0 && borderInfo.visible) {
buffer.write('border: Border.all(');
if (borderInfo.color != null) {
buffer.write('color: Color(${borderInfo.color.toString()}),');
}
buffer.write('width: ${borderInfo.thickness},');
buffer.write('),'); // end of Border.all(
}
}

if (effectsInfo != null &&
effectsInfo.isNotEmpty &&
effectsInfo.first.type.toLowerCase().contains('shadow')) {
buffer.write('boxShadow: [');

for (var effect in effectsInfo) {
buffer.write('''
BoxShadow(
${PBColorGenHelper().getHexColor(effect.color)}
spreadRadius: ${effect.radius},
blurRadius: ${effect.radius},
offset: Offset(${effect.offset['x']}, ${effect.offset['y']}),
),
''');
}

buffer.write('],');
}
buffer.write('),');

return buffer.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribut
import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart';
import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart';
import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart';
import 'package:parabeac_core/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_fill.dart';

class PBColorGenHelper extends PBAttributesHelper {
PBColorGenHelper() : super();
Expand All @@ -13,6 +15,13 @@ class PBColorGenHelper extends PBAttributesHelper {
return '';
}

if (source.auxiliaryData.colors != null &&
source.auxiliaryData.colors.first.type
.toLowerCase()
.contains('gradient')) {
return _gradientColor(source.auxiliaryData.colors.first);
}

var color = source.auxiliaryData.color?.toString();
if (color == null) {
return '';
Expand Down Expand Up @@ -41,6 +50,54 @@ class PBColorGenHelper extends PBAttributesHelper {
}
}

/// Generate gradient for decoration box
String _gradientColor(PBFill gradient) {
var beginX = _roundNumber(gradient.gradientHandlePositions[0].x);
var beginY = _roundNumber(gradient.gradientHandlePositions[0].y);
var endX = _roundNumber(gradient.gradientHandlePositions[1].x);
var endY = _roundNumber(gradient.gradientHandlePositions[1].y);

var gradientInfo = _getGradientInfo(gradient);

return '''
gradient: LinearGradient(
begin: Alignment($beginX,$beginY),
end: Alignment($endX,$endY),
colors: <Color>[
${gradientInfo[0]}
],
stops: [
${gradientInfo[1]}
],
tileMode: TileMode.clamp,
),
''';
}

/// Gradient info is a list
/// 0 is for gradient color
/// 1 is for gradient stop position
List<String> _getGradientInfo(PBFill gradient) {
var gradientInfo = <String>['', ''];
for (var stop in gradient.gradientStops) {
gradientInfo[0] += 'Color(${stop.color.toString()}),';
gradientInfo[1] += '${stop.position},';
}
return gradientInfo;
}

num _roundNumber(num coordinate) {
return (2 * coordinate) - 1;
}

/// Get String from Color
String getHexColor(PBColor color) {
if (color == null) {
return '';
}
return 'color : Color(${color.toString()}),';
}

/// Finds default color based on common hex patterns.
///
/// Returns `null` if no pattern was found
Expand Down
11 changes: 11 additions & 0 deletions lib/generation/generators/attribute-helper/pb_size_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ class PBSizeHelper extends PBAttributesHelper {

heightString =
'height: constraints.maxHeight * ${relativeHeight.toStringAsFixed(3)},';
} else if (context.sizingContext ==
SizingValueContext.LayoutBuilderStatefulValue) {
relativeWidth = relativeWidth / screenWidth;
relativeHeight = relativeHeight / screenHeight;

// Size for LayoutBuilder
widthString =
'width: widget.constraints.maxWidth * ${relativeWidth.toStringAsFixed(3)},';

heightString =
'height: widget.constraints.maxHeight * ${relativeHeight.toStringAsFixed(3)},';
} else {
// Size for constants value
widthString = 'width: ${relativeWidth.toStringAsFixed(3)},';
Expand Down
2 changes: 1 addition & 1 deletion lib/generation/generators/pb_flutter_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class PBFlutterGenerator extends PBGenerationManager {
var it = data.globalVariables;
while (it.moveNext()) {
param = it.current;
stringBuffer.write(param.type +
stringBuffer.write(param.pbdlType +
' ' +
param.variableName +
(param.defaultValue == null ? '' : ' = ${param.defaultValue}') +
Expand Down
45 changes: 44 additions & 1 deletion lib/generation/generators/plugins/pb_plugin_node.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart';

import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart';
Expand Down Expand Up @@ -29,4 +31,45 @@ abstract class PBTag extends PBVisualIntermediateNode {
PBIntermediateTree tree);

void extractInformation(PBIntermediateNode incomingNode);

/// Handles `iNode` to convert into a [PBTag].
///
/// Returns the [PBIntermediateNode] that should go into the [PBIntermediateTree]
PBIntermediateNode handleIntermediateNode(
PBIntermediateNode iNode,
PBIntermediateNode parent,
PBTag tag,
PBIntermediateTree tree,
) {
iNode.name = iNode.name.replaceAll(tag.semanticName, '');

// If `iNode` is [PBSharedMasterNode] we need to place the [CustomEgg] betweeen the
// [PBSharedMasterNode] and the [PBSharedMasterNode]'s children. That is why we are returing
// `iNode` at the end.
if (iNode is PBSharedMasterNode) {
return iNode;
} else if (iNode is PBSharedInstanceIntermediateNode) {
iNode.parent = parent;

tree.replaceNode(iNode, tag);

tree.addEdges(tag, [iNode]);

return tag;
} else {
// [iNode] needs a parent and has not been added to the [tree] by [tree.addEdges]
iNode.parent = parent;
// If `iNode` has no children, it likely means we want to wrap `iNode` in [CustomEgg]
if (tree.childrenOf(iNode).isEmpty || iNode is PBLayoutIntermediateNode) {
/// Wrap `iNode` in `newTag` and make `newTag` child of `parent`.
tree.removeEdges(iNode.parent, [iNode]);
tree.addEdges(tag, [iNode]);
tree.addEdges(parent, [tag]);
return tag;
}
tree.replaceNode(iNode, tag, acceptChildren: true);

return tag;
}
}
}
1 change: 0 additions & 1 deletion lib/generation/generators/symbols/pb_instancesym_gen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:parabeac_core/generation/generators/pb_generator.dart';
import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart';
import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart';
Expand Down
6 changes: 3 additions & 3 deletions lib/generation/generators/symbols/pb_mastersym_gen.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import 'package:parabeac_core/generation/generators/pb_generator.dart';
import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart';
import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart';
import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart';
import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart';
import 'package:quick_log/quick_log.dart';

class PBMasterSymbolGenerator extends PBGenerator {
PBMasterSymbolGenerator() : super(strategy: StatelessTemplateStrategy());
PBMasterSymbolGenerator() : super(strategy: StatefulTemplateStrategy());

var log = Logger('Symbol Master Generator');
@override
String generate(PBIntermediateNode source, PBContext context) {
context.sizingContext = SizingValueContext.LayoutBuilderValue;
context.sizingContext = SizingValueContext.LayoutBuilderStatefulValue;
var children = context.tree.childrenOf(source);
var sourceChild = children.isNotEmpty ? children.first : null;
var buffer = StringBuffer();
Expand Down
Loading

0 comments on commit c13cbf4

Please sign in to comment.