Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The generator creates the following elements:
- Colors
- Border Widths and helper functions to create borders
- Border Radii
- Shadows and helper functions to create box shadows
- Spatials (spacing)
- Screensizes (Breakpoints) and a responsive helper function
- Text Styles (Typography)
Expand Down
7 changes: 7 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ builders:
build_extensions: { '.design-system.json': ['.icon_sizes.dart'] }
auto_apply: root_package
build_to: source

shadows:
import: 'package:design_system_generator/builder.dart'
builder_factories: ['shadowBuilder']
build_extensions: { '.design-system.json': ['.shadows.dart'] }
auto_apply: root_package
build_to: source
48 changes: 48 additions & 0 deletions design-system.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@
},
{ "const": false }
]
},
"shadows": {
"title": "Shadows",
"description": "A map of box shadow definitions.",
"oneOf": [
{
"type": "object",
"minProperties": 0,
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z][a-zA-Z0-9]*$": {
"$ref": "#/$defs/shadow"
}
}
},
{
"const": false
}
]
}
},
"$defs": {
Expand Down Expand Up @@ -210,6 +229,35 @@
}
}
},
"shadow": {
"title": "Shadow",
"description": "A box shadow definition.",
"type": "object",
"required": ["blurRadius", "spreadRadius", "offset"],
"additionalProperties": false,
"properties": {
"blurRadius": {
"type": "number",
"minimum": 0
},
"spreadRadius": {
"type": "number"
},
"offset": {
"type": "object",
"required": ["dx", "dy"],
"additionalProperties": false,
"properties": {
"dx": {
"type": "number"
},
"dy": {
"type": "number"
}
}
}
}
},
"iconSizes": {
"title": "Icon sizes",
"description": "A definition of the icon sizes in px.",
Expand Down
12 changes: 12 additions & 0 deletions example/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ Note that colors are in the format `#RRGGBB` or `#RRGGBBAA` (with alpha).
"normal": 8,
"full": 9999
},
"shadows": {
"small": {
"blurRadius": 4,
"spreadRadius": 0,
"offset": { "dx": 0, "dy": 2 }
},
"large": {
"blurRadius": 12,
"spreadRadius": -2,
"offset": { "dx": 0, "dy": 8 }
}
},
"typography": {
"root": {
"family": "Arial",
Expand Down
12 changes: 12 additions & 0 deletions example/lib/app.design-system.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@
"normal": 8,
"full": 9999
},
"shadows": {
"small": {
"blurRadius": 4,
"spreadRadius": 0,
"offset": { "dx": 0, "dy": 2 }
},
"large": {
"blurRadius": 12,
"spreadRadius": -2,
"offset": { "dx": 0, "dy": 8 }
}
},
"typography": {
"root": {
"family": "Arial",
Expand Down
48 changes: 48 additions & 0 deletions example/lib/app.shadows.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions lib/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'src/builder/color_builder.dart';
import 'src/builder/icon_size_builder.dart';
import 'src/builder/radius_builder.dart';
import 'src/builder/screen_builder.dart';
import 'src/builder/shadow_builder.dart';
import 'src/builder/spatial_builder.dart';
import 'src/builder/typography_builder.dart';

Expand Down Expand Up @@ -48,3 +49,8 @@ Builder screenBuilder(BuilderOptions options) => ScreenBuilder();
///
/// This builder generates icon size-related design tokens.
Builder iconSizeBuilder(BuilderOptions options) => IconSizeBuilder();

/// Creates a [ShadowBuilder] instance.
///
/// This builder generates box shadow-related design tokens.
Builder shadowBuilder(BuilderOptions options) => ShadowBuilder();
177 changes: 177 additions & 0 deletions lib/src/builder/shadow_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import 'package:code_builder/code_builder.dart';

import '../config/config.dart';
import 'base_builder.dart';

/// A builder that generates shadow-related design system code.
final class ShadowBuilder extends DesignSystemBuilder {
/// Creates a [ShadowBuilder] instance.
ShadowBuilder() : super('shadows');

@override
Library buildLibrary(DesignSystemConfig config) {
if (config.shadows.isEmpty) {
return Library();
}

final boxShadowRef = refer('BoxShadow', 'package:flutter/widgets.dart');
final offsetRef = refer('Offset', 'package:flutter/widgets.dart');
final colorRef = refer('Color', 'dart:ui');
final colorsRef = refer('AppColors', './${config.name}.colors.dart');

return Library(
(b) => b
..body.add(
Class(
(b) => b
..name = 'AppShadows'
..modifier = ClassModifier.final$
..abstract = true
..methods.addAll(
config.shadows.map(
(shadow) => Method(
(b) => b
..name = shadow.validName
..static = true
..returns = boxShadowRef
..docs.addAll([
'/// ${shadow.validName} (blur: ${shadow.blurRadius}px, spread: ${shadow.spreadRadius}px, offset: ${shadow.offsetDx}/${shadow.offsetDy})',
])
..optionalParameters.add(
Parameter(
(b) => b
..name = 'color'
..type = colorRef
..named = true
..defaultTo = colorsRef.property('black').code,
),
)
..lambda = true
..body = refer('AppShadow')
.property(shadow.validName)
.property('boxShadow')
.call([], {'color': refer('color')})
.code,
),
),
),
),
)
..body.add(
Enum(
(b) => b
..name = 'AppShadow'
..fields.addAll([
Field(
(b) => b
..modifier = FieldModifier.final$
..name = 'blurRadius'
..type = refer('double'),
),
Field(
(b) => b
..modifier = FieldModifier.final$
..name = 'spreadRadius'
..type = refer('double'),
),
Field(
(b) => b
..modifier = FieldModifier.final$
..name = 'offset'
..type = offsetRef,
),
])
..constructors.add(
Constructor(
(b) => b
..constant = true
..requiredParameters.addAll([
Parameter(
(b) => b
..name = 'blurRadius'
..toThis = true,
),
Parameter(
(b) => b
..name = 'spreadRadius'
..toThis = true,
),
Parameter(
(b) => b
..name = 'offset'
..toThis = true,
),
]),
),
)
..methods.add(
Method(
(b) => b
..name = 'boxShadow'
..returns = boxShadowRef
..optionalParameters.add(
Parameter(
(b) => b
..name = 'color'
..type = colorRef
..named = true
..defaultTo = colorsRef.property('black').code,
),
)
..lambda = true
..body = boxShadowRef.newInstance([], {
'color': refer('color'),
'blurRadius': refer('blurRadius'),
'spreadRadius': refer('spreadRadius'),
'offset': refer('offset'),
}).code,
),
)
..methods.add(
Method(
(b) => b
..name = 'asList'
..returns = TypeReference(
(b) => b
..symbol = 'List'
..types.add(boxShadowRef),
)
..optionalParameters.add(
Parameter(
(b) => b
..name = 'color'
..type = colorRef
..named = true
..defaultTo = colorsRef.property('black').code,
),
)
..lambda = true
..body = literalList([
refer('boxShadow').call([], {'color': refer('color')}),
]).code,
),
)
..values.addAll(
config.shadows.map(
(shadow) => EnumValue(
(b) => b
..name = shadow.validName
..docs.addAll([
'/// ${shadow.validName} (blur: ${shadow.blurRadius}px, spread: ${shadow.spreadRadius}px, offset: ${shadow.offsetDx}/${shadow.offsetDy})',
])
..arguments.addAll([
literalNum(shadow.blurRadius),
literalNum(shadow.spreadRadius),
offsetRef.newInstance([
literalNum(shadow.offsetDx),
literalNum(shadow.offsetDy),
]),
]),
),
),
),
),
),
);
}
}
Loading