Skip to content
Open
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
55 changes: 36 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,29 +163,46 @@ SolidUI requires the following dependencies:

## Quick Start to Create an App

To create a new Solid-based app using `solidui` named `myapp` and
published by `example.com` begin with:
To quickly create a new Solid-based app, we provide a [Mason](https://pub.dev/packages/mason) template.

### Using Mason (Recommended)

1. Install Mason:
```bash
dart pub global activate mason_cli
```
2. Initialize Mason in your project (if not already):
```bash
mason init
```
3. Add the SolidUI brick:
```bash
mason add solidui --path templates/solidui/brick
```
4. Create a new app from the template:
```bash
mason make solidui
```
Comment on lines +168 to +185
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The instructions at step 3 use --path templates/solidui/brick which assumes the user is running the command from the SolidUI repository root. This won't work for external users who want to create a new SolidUI app. Consider clarifying this is for contributors, or provide instructions for external users to either: 1) Clone the repository first, or 2) Use a published brick URL when available. The instructions should differentiate between contributors and end-users.

Copilot uses AI. Check for mistakes.

### Template Structure

The template app consists of several files within the
`lib/` directory:
- `main.dart`: Initialises the application and launches the app.
- `app.dart`: Implements the `App()` widget, instantiating `SolidLogin()`.
- `app_scaffold.dart`: Implements `AppScaffold()` widget using `SolidScaffold()`.
- `home.dart`: Implements the `Home()` widget for the main app functionality.
- `constants/app.dart`: App-wide constants including title and description.
- `utils/is_desktop.dart`: Desktop platform detection utility.

### Synchronizing Template and Example

If you are a contributor and want to update the `example/` app from the template (or vice-versa), use the provided sync script:

```bash
flutter create --template solidui --domain com.example myapp
python3 support/sync_template_to_example.py
```

This will create a template app which we also included here under the
`example/` directory. The app consists of several files within the
`lib/` directory. `main.dart` is the main entry point to the app. Its
task in our framework is to initialise the application and then launch
the app itself. `app.dart` implements the `App()` which is typically
where we instantiate a `SolidLogin()`, often as the `child:` of a
`SolidThemeApp()`. The `SolidLogin()` provides the login page for the
app. After logging in the `AppScaffold()`, as the `child:` of the
`SolidLogin()`, is instantiated to contain the main functionality of
the app. `app_scaffold.dart` implements the `AppScaffold()` widget
which builds a `SolidScaffold()` to set up the framework for a typical
Solid app. The child is the `Home()` widget. `home.dart` implements
the `Home()` widget as the main app functionality. Constants are
defined in `constants/app.dart` and utilities such as desktop platform
detection are in `utils/is_desktop.dart`.

## SolidScaffold

The `SolidScaffold()` is the primary widget for building Solid
Expand Down
Binary file added example/lib/home.dart.old
Binary file not shown.
11 changes: 11 additions & 0 deletions mason.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Register bricks which can be used via mason get.
# bricks:
# sample: 0.1.0+1
# hello:
# git:
# url: https://github.com/felangel/mason
# path: bricks/hello

bricks:
solidui:
path: templates/solidui/brick
51 changes: 51 additions & 0 deletions support/sync_template_to_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess

def sync():
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
template_dir = os.path.join(root_dir, 'templates', 'solidui', 'brick')
example_dir = os.path.join(root_dir, 'example')

print(f"Syncing template from {template_dir} to {example_dir}...")

# 1. Ensure mason is initialized and get the brick
subprocess.run(['mason', 'get'], cwd=root_dir, check=True)

# 2. Run mason make to a temporary directory
temp_gen_dir = os.path.join(root_dir, '.temp_template_gen')
if os.path.exists(temp_gen_dir):
shutil.rmtree(temp_gen_dir)
os.makedirs(temp_gen_dir)

subprocess.run([
'mason', 'make', 'solidui',
'--projectName', 'myapp',
'--description', 'My App - A SolidUI Template Application',
'--author', 'Software Innovation Institute, ANU',
'-o', temp_gen_dir
], cwd=root_dir, check=True)
Comment on lines +14 to +28
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subprocess calls lack error handling beyond check=True. If mason is not installed or fails for other reasons, the error message may not be clear to users. Consider adding try-except blocks around the subprocess calls to provide more informative error messages, such as "Mason CLI not found. Please install it with: dart pub global activate mason_cli".

Copilot uses AI. Check for mistakes.

# 3. Copy generated files back to example
# Generated files are usually lib/, assets/, pubspec.yaml, etc.
gen_content_dir = os.path.join(temp_gen_dir) # mason make -o temp_gen_dir puts files directly there
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 32 has a redundant os.path.join() call that doesn't add any path components. This can be simplified to gen_content_dir = temp_gen_dir. The comment already clarifies that mason outputs files directly to the specified directory.

Suggested change
gen_content_dir = os.path.join(temp_gen_dir) # mason make -o temp_gen_dir puts files directly there
gen_content_dir = temp_gen_dir # mason make -o temp_gen_dir puts files directly there

Copilot uses AI. Check for mistakes.

for item in os.listdir(gen_content_dir):
s = os.path.join(gen_content_dir, item)
d = os.path.join(example_dir, item)
if os.path.isdir(s):
if os.path.exists(d):
shutil.rmtree(d)
shutil.copytree(s, d)
print(f"Updated directory: {item}")
else:
shutil.copy2(s, d)
print(f"Updated file: {item}")

# Clean up
shutil.rmtree(temp_gen_dir)
print("Sync complete.")

if __name__ == "__main__":
sync()
163 changes: 163 additions & 0 deletions templates/solidui/brick/__brick__/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
/.metadata
/windows/flutter/CMakeLists.txt
/windows/runner/resources/app_icon.ico
/windows/runner/CMakeLists.txt
/windows/runner/flutter_window.cpp
/windows/runner/flutter_window.h
/windows/runner/main.cpp
/windows/runner/resource.h
/windows/runner/runner.exe.manifest
/windows/runner/Runner.rc
/windows/runner/utils.cpp
/windows/runner/utils.h
/windows/runner/win32_window.cpp
/windows/runner/win32_window.h
/windows/.gitignore
/windows/CMakeLists.txt
/macos/Flutter/Flutter-Debug.xcconfig
/macos/Flutter/Flutter-Release.xcconfig
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
/macos/Runner/Base.lproj/MainMenu.xib
/macos/Runner/Configs/AppInfo.xcconfig
/macos/Runner/Configs/Debug.xcconfig
/macos/Runner/Configs/Release.xcconfig
/macos/Runner/Configs/Warnings.xcconfig
/macos/Runner/AppDelegate.swift
/macos/Runner/DebugProfile.entitlements
/macos/Runner/Info.plist
/macos/Runner/MainFlutterWindow.swift
/macos/Runner/Release.entitlements
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
/macos/Runner.xcodeproj/project.pbxproj
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
/macos/Runner.xcworkspace/contents.xcworkspacedata
/macos/RunnerTests/RunnerTests.swift
/macos/.gitignore
/macos/Podfile
/web/icons/Icon-192.png
/web/icons/Icon-512.png
/web/icons/Icon-maskable-192.png
/web/icons/Icon-maskable-512.png
/web/favicon.png
/web/index.html
/web/manifest.json
/linux/flutter/CMakeLists.txt
/linux/runner/CMakeLists.txt
/linux/runner/main.cc
/linux/runner/my_application.cc
/linux/runner/my_application.h
/linux/.gitignore
/linux/CMakeLists.txt
/ios/Flutter/AppFrameworkInfo.plist
/ios/Flutter/Debug.xcconfig
/ios/Flutter/Release.xcconfig
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
/ios/Runner/Base.lproj/LaunchScreen.storyboard
/ios/Runner/Base.lproj/Main.storyboard
/ios/Runner/AppDelegate.swift
/ios/Runner/Info.plist
/ios/Runner/Runner-Bridging-Header.h
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
/ios/Runner.xcodeproj/project.pbxproj
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
/ios/Runner.xcworkspace/contents.xcworkspacedata
/ios/RunnerTests/RunnerTests.swift
/ios/.gitignore
/ios/Podfile
/android/app/src/debug/AndroidManifest.xml
/android/app/src/main/kotlin/com/example/solidui_simple_example/MainActivity.kt
/android/app/src/main/res/drawable/launch_background.xml
/android/app/src/main/res/drawable-v21/launch_background.xml
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
/android/app/src/main/res/values/styles.xml
/android/app/src/main/res/values-night/styles.xml
/android/app/src/main/AndroidManifest.xml
/android/app/src/profile/AndroidManifest.xml
/android/app/build.gradle.kts
/android/gradle/wrapper/gradle-wrapper.properties
/android/.gitignore
/android/build.gradle.kts
/android/gradle.properties
/android/settings.gradle.kts
/android/app/src/main/kotlin/com/example/solidui_example/MainActivity.kt
18 changes: 18 additions & 0 deletions templates/solidui/brick/__brick__/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# {{projectName.titleCase()}}

{{description}}

Built with [SolidUI](https://github.com/anusii/solidui).

## Getting Started

To run this application, make sure you have the [Flutter SDK](https://flutter.dev/docs/get-started/install) installed.

1. Clone or initialize this project.
2. Run `flutter pub get` to install dependencies.
3. Run the application with `flutter run`.

## License

Copyright (C) 2025, {{author}}.
Licensed under the MIT License.
12 changes: 12 additions & 0 deletions templates/solidui/brick/__brick__/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include: package:flutter_lints/flutter.yaml

analyzer:
exclude:
- build/**

linter:
rules:
prefer_const_constructors: true
prefer_const_literals_to_create_immutables: true
prefer_final_fields: true
sort_child_properties_last: true
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions templates/solidui/brick/__brick__/lib/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/// The primary App widget.
///
/// Copyright (C) 2025, Software Innovation Institute, ANU.
///
/// Licensed under the MIT License (the "License").
///
/// License: https://choosealicense.com/licenses/mit/.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
///
/// Authors: Tony Chen

library;

import 'package:flutter/material.dart';

import 'package:solidui/solidui.dart';

import 'app_scaffold.dart';
import 'constants/app.dart';

// This widget is the root of the application.

class App extends StatelessWidget {
const App({super.key});

@override
Widget build(BuildContext context) {
return SolidThemeApp(
// Turn off debug banner for now.

debugShowCheckedModeBanner: false,
title: appTitle,

theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),

home: const SolidLogin(
image: AssetImage('assets/images/app_image.jpg'),
logo: AssetImage('assets/images/app_icon.png'),
customFolderPathList: [
'customDir1',
'customDir2',
'customDir2/customDir3',
],
child: appScaffold,
),
);
}
}
Loading
Loading