diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index a922f6ea6..000000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,227 +0,0 @@ -# Contributing to OverReact - -Looking to contribute something to the over_react library? __Here's how you can help.__ - -+ __[Coding Standards](#coding-standards)__ - + [General Formatting Guidelines](#general-formatting-guidelines) -+ __[Using the Issue Tracker](#using-the-issue-tracker)__ - + [Reporting Bugs](#bug-reports) - + [Feature Requests](#feature-requests) - + [Submitting Pull Requests](#pull-requests) -+ __[Commit Message Standards](#git-commit-message-standards)__ -+ __[Developer Workflow](#developer-workflow)__ - - - - -## Coding standards - -A lot can be gained by writing code in a consistent way. Moreover, always remember that code is written and -maintained by _people_. Ensure your code is descriptive, well commented, and approachable by others. - -__ALWAYS__ adhere to the [Dart Style Guide]. _Please take the time to read it if you have never done so._ - -  - - -### General formatting guidelines - -+ __AVOID__ lines longer than 120 characters. -+ __AVOID__ using `dartfmt` as an excuse to ignore good judgement about - whether your code is readable and approachable by others. - -  -  - - - -## Using the issue tracker - -The issue tracker is the preferred channel for [bug reports](#bug-reports) and [feature requests](#feature-requests), -but __please follow the guidelines:__ - - + __Fill out the template we've provided.__ - - + __Be Professional__ - + Please __do not__ derail or troll issues. Keep the discussion on topic and respect the opinions of others. - - + __Not that Professional__ - + Feel free to include _relevant_ animated gifs to drive home your message / request. - -  - - -### Bug reports - -A bug is a _demonstrable problem_ that is caused by the code in the repository. - -_Good bug reports are extremely helpful - thank you!__ - -__Guidelines for bug reports:__ - -1. __Search for existing issues.__ Duplicate issues can become cumbersome, and you'd help us out a lot by first - checking if someone else has reported the same issue. Moreover, the issue may have already been resolved with a - fix available. - -2. __Record a screencast of yourself reproducing the issue__. - 1. Be sure the problem exists in over_react's code by building a - reduced test case that one of the reviewers can pull locally - and test out. - -3. __Share as much information as possible.__ Include operating system and version, browser and version, version of - `over_react`, etc. where appropriate. - -Always include steps to reproduce the bug. - -__Example Bug Report:__ - -> Short and descriptive example bug report title -> -> A summary of the issue and the browser/OS environment in which it occurs. If -> suitable, include the steps required to reproduce the bug. -> -> 1. This is the first step -> 2. This is the second step -> 3. Further steps, etc. -> -> `` - a link to branch with the reduced test case -> -> Any other information you want to share that is relevant to the issue being -> reported. This might include the lines of code that you have identified as -> causing the bug, and potential solutions (and your opinions on their -> merits). - -  - - -### Feature requests - -Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the -project. It's up to *you* to make a strong case to convince the `over_react` team of the merits of this feature. -Please provide as much detail and context as possible. - -  - - -### Pull requests - -Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope -and avoid containing unrelated commits. - -__Please ask first__ before embarking on any significant pull request (e.g. implementing features, refactoring code, -porting to a different language), otherwise you risk spending a lot of time working on something that the project's -lead developers might not want to merge into the project. - -Please adhere to the [Dart Style Guide] for all changes contained in your pull requests. - -Adhering to the following process is the best way to get your work included in the project: - -1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, - and configure the remotes: - - ```bash - # Navigate to the directory where you store repos locally - cd ~/your-local-git-repo-spot - # Clone your fork of the repo into the current directory - git clone git@github.com:/over_react - # Navigate to the newly cloned directory - cd ~/your-local-git-repo-spot/over_react - # Assign the repo you forked from to a remote called "upstream" - git remote add upstream git@github.com:Workiva/over_react - ``` - -2. If you cloned a while ago, get the latest changes from upstream: - - ```bash - git checkout master - git pull upstream master - ``` - -3. Create a new topic branch that will contain your feature, change, or fix: - - ```bash - git checkout -b - ``` - -4. Commit your changes in logical chunks. Please adhere to these - [git commit message guidelines](#git-commit-message-standards) or your code is unlikely be merged into the master - branch. Optionally, you can use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) - feature to tidy up your commits before making them public. - -5. Write tests for your changes. - 1. There are no exceptions. - 2. If you're having trouble, reach out in your PR about how to best go about testing your changes. - -6. If you have merge conflicts, locally merge the upstream master branch into your topic branch: - - ```bash - git pull upstream master - ``` - -7. Push your topic branch up to your fork: - - ```bash - git push origin - ``` - -8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) - with a clear title and description - following all the [issue guidelines](#using-the-issue-tracker) listed above. - -  -  - - - -## Git Commit Message Standards - -Below you will find an example commit message that follows the guidelines we would like all over_react contributors -to follow. - -``` -Capitalized, short (50 chars or less) summary - -More detailed explanatory text, if necessary. Wrap it to about 72 -characters or so. In some contexts, the first line is treated as the -subject of an email and the rest of the text as the body. The blank -line separating the summary from the body is critical (unless you omit -the body entirely); tools like rebase can get confused if you run the -two together. - -+ Bullet points are okay, too - -+ Typically a hyphen, asterisk or plus-symbol is used for the bullet, -followed by a single space, with blank lines in between, but -conventions vary here -``` - -Write your commit message in the imperative: "Fix bug" and not "Fixed bug" or "Fixes bug." This convention matches up -with commit messages generated by commands like git merge and git revert. - -Further paragraphs come after blank lines. - -> [Read this](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for more information on why a -> standardized commit message format is important. - -  -  - - - -## Developer Workflow - -The `over_react` developer workflow couldn't be any more simple! - -To serve the demos within `web/`, or start the transformer, run: - -```bash -pub serve -``` - -When you're ready to run the tests... run: - -```bash -pub run dart_dev test -``` - - -[Dart Style Guide]: https://www.dartlang.org/guides/language/effective-dart/style diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b27658a74..c1074fa24 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,16 +1,45 @@ -## Ultimate problem: +## Motivation + +## Changes + -## How it was fixed: +#### Release Notes + +## Review +_[See CONTRIBUTING.md][contributing-review-types] for more details on review types (+1 / QA +1 / +10) and code review process._ -## Testing suggestions: + -> __FYA:__ @greglittlefield-wf @aaronlademann-wf @kealjones-wk @evanweible-wf @maxwellpeterson-wf +Please review: + +### QA Checklist +- [ ] Tests were updated and provide good coverage of the changeset and other affected code +- [ ] Manual testing was performed if needed + - [ ] Steps from PR author: + + - [ ] Anything falling under manual testing criteria [outlined in CONTRIBUTING.md][contributing-manual-testing] + +## Merge Checklist +While we perform many automated checks before auto-merging, some manual checks are needed: +- [ ] A Client Platform member has reviewed these changes +- [ ] There are no unaddressed comments _- this check can be automated if reviewers use the "Request Changes" feature_ +- [ ] _For release PRs -_ Version metadata in Rosie comment is correct + + +[contributing-review-types]: https://github.com/Workiva/over_react/blob/master/CONTRIBUTING.md#review-types +[contributing-manual-testing]: https://github.com/Workiva/over_react/blob/master/CONTRIBUTING.md#manual-testing-criteria diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 17a93a716..000000000 --- a/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @Workiva/app-frameworks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9cd91172a..6fa46dc9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,75 +1,124 @@ -# Contributing +# Contributing to over_react -> We are working on a more thorough version of these contributing guidlines. For -> the time being, we've documented our temporary dual-release setup that is -> necessary for supporting Dart 1 and Dart 2 concurrently. +- [__Support, Opening Issues__](#support-opening-issues) +- [__Contributing Changes__](#contributing-changes) + - [Coding Standards](#coding-standards) + - [Git Commit Message Standards](#git-commit-message-standards) +- [__Code Review Process and Merging Requirements__](#code-review-process-and-merging-requirements) + - [Minimum Required Review](#minimum-required-review) + - [Review Types](#review-types) + - [Manual Testing Criteria](#manual-testing-criteria) -## Dart 1 & Dart 2 Dual-Releases - -Long story short, we are unable to maintain a single codebase of over_react that -is compatible with both Dart 1 and Dart 2. Transformers only work on Dart 1 and -builders only work on Dart 2, and we can't maintain the transformer and builder -together due to dependency conflicts. - -> For more information on our Dart 2 migration, [see this guide](/doc/dart2_migration.md). - -Fortunately, this problem can be shouldered entirely by the maintainers via a -dual-release strategy (credit to the [dart2_constant](https://pub.dartlang.org/packages/dart2_constant) -for the idea). The result is that consumers will depend on a version range of -this library like they normally do and everything will _just work_. - -For every _version_ we want to release, we will actually release two releases - -a Dart 1 (transformer) version and a Dart 2 (builder) version. These two -releases will have the same semantic version, but will have unique build -suffixes. The `pub` client will then decide which one to install based on their -`environment.sdk` constraints and the active Dart SDK version. - -### Branches - -- `master` - - Dart2-only - - Provides a builder - - Environment constraint: `>=2.1.0 <3.0.0` - -- `master_dart1` - - Dart1-only - - Provides a transformer - - Environment constraint: `>=1.24.3 <2.0.0` - -### Release Process - -> Note that these steps are intended to be followed by Workiva employees, and as -> such have some references to internal tooling. - -For every release, do the following: - -1. Ensure the next release versions exist in MARV: - - Name | Branch - ---- | ------ - over_react 2.x.x+dart1 | master_dart1 - over_react 2.x.x+dart2 | master - -1. Trigger the `over_react 2.x.x+dart1` release first and review the PR: - - - Ensure the updated `pubspec.yaml` version is correct, including the - `+dart1` suffix. - - - Ensure the build passes. - - - Merge the Dart 1 release and publish it to pub. - -1. Trigger the `over_react 2.x.x+dart2` release second and review the PR: - - - Ensure the updated `pubspec.yaml` version is correct. - - - Ensure the build passes. - - - **Add any necessary changelog updates to the Dart 2 version.** - - - Merge the Dart 2 release and publish it to pub. - -1. Re-recreate the Dart 1 release in MARV (it does not get recreated - automatically like the default release does). - -1. Add the `+dart2` suffix to the automatically created release. +--- + +## Support, Opening Issues +Have a bug to report or an improvement/feature to request? Please +[open an issue](https://github.com/Workiva/over_react/issues/new) and fill out +the issue template with as much detail as necessary. + +###### Workiva Employees +> __Contact us on Slack:__ [\#support-ui-platform](https://workiva.slack.com/app_redirect?channel=support-ui-platform) + +Have a bug to report or an improvement/feature to request? +Please contact us on Slack or [create a JIRA ticket](https://jira.atl.workiva.net/secure/CreateIssue!default.jspa?pid=CPLAT&component=over_react) +and fill out the description with as much detail as necessary. + +## Contributing Changes +If you're contributing a change to over_react, please follow this process: (and +thank you!) + +1. Before you start working on a larger contribution (e.g. implementing features, + refactoring code, etc.), you should get in touch with us first so that + we can help out and possibly guide you. + + Coordinating up front makes it much easier to avoid frustration later on. + +1. Commit your changes in logical chunks. Please adhere to these + [coding standards](#coding-standards) and + [Git commit message guidelines](#git-commit-message-standards). + +1. Write tests for your changes. + - There are very few exceptions. + - If you're having trouble, please reach out for testing advice. We'll be + happy to help! +1. Open a PR against the `master` branch and fill out the template with as much + detail as necessary. +1. See instructions in PR template for getting review on your changes. + + +### Coding Standards +A lot can be gained by writing code in a consistent way. Moreover, always +remember that code is written and maintained by _people_. Ensure your code is +descriptive, well commented, and approachable by others. + +- Dart + - Adhere to the official [Dart Style Guide][dart-style-guide]. _Please take the time to read it if you have never done so._ + - Format your code using `pub run dart_dev format` (this is enforced by a CI check) + + +### Git Commit Message Standards + +Read [this short post][git-commit-messages] for commit message guidelines (and more information on why standardized commit message format is important). + +[dart-style-guide]: https://www.dartlang.org/articles/style-guide/ +[git-commit-messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html + +## Code Review Process and Merging Requirements +For a PR to merge, it must: +1. Receive the minimum required review + - High-risk PRs (e.g., large number of lines changed, touching areas at high risk of regression, complex changes) + - __Two__ +1s + - QA +1 by someone other than the commit author + - All other PRs (including trivial changes) + - +1 + - QA +1 by someone other than the commit author + + ___NOTE: It does not matter whether the "+1" and "QA +1" come from the same reviewer (e.g., via a "+10").___ +2. Pass the merge checklist outlined in the PR template + + +### Review Types + +- __+1__ + - Reviewing code for correctness, robustness, maintainability, performance, etc. + - Reviewing tests for coverage, thoroughness, and clarity + - _This responsibility is shared with QA reviewers_ +- __QA +1__ + - Verifying that adequate tests have been has been added, and reviewing them + for coverage, thoroughness, and clarity + - _This responsibility is shared with code reviewers_ + - Verifying automated tests pass in CI (this is often done automatically by Rosie). + - Performing manual testing instructions, if they exist. (see criteria in the next section) + - __Must be done by someone other than the commit author.__ +- __+10__ + - Exactly equivalent to performing both a "+1" and a "QA +1", just combined into one step. + +## Manual Testing Criteria +Manual testing instructions (done as part of a "QA +1") should be included for the following scenarios. + +__If none of these apply, then manual testing instructions may be omitted.__ + +- When manual testing can help uncover areas of missed test coverage (in terms of certain scenarios and states, not just lines covered). + + _Examples:_ + - Running CLIs on several different projects to help catch edge-cases. + - Hammering on UI elements to ensure they react gracefully to different sequences of user input. + +- When tests run in CI do not fully exercise the desired behavior. + + _Examples:_ + - Changes were made in areas of the code that shouldn't be tested, like examples. + - Changes were made in areas of the code that are very difficult to fully test, and are more efficient to test manually. + - Changes need to be consumed in a certain library, harness, or deploy to be fully tested. + +- When CI tests do not fully protect against regressions to existing behavior. + + _Examples:_ + - Test coverage around code impacted by changes is sparse. + - Changes need to be integrated with another library to ensure nothing broke. + +- When changes are made to CI itself, and need to be manually verified. + + _Examples:_ + - Test runner was updated. + - New test suites were added. diff --git a/analysis_options.yaml b/analysis_options.yaml index c9e17d830..53b338ea8 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -5,7 +5,6 @@ analyzer: linter: rules: - annotate_overrides - - avoid_as - avoid_empty_else - avoid_init_to_null - avoid_return_types_on_setters @@ -24,3 +23,4 @@ linter: - type_init_formals - unnecessary_brace_in_string_interps - unnecessary_getters_setters + - unrelated_type_equality_checks diff --git a/build.yaml b/build.yaml index da687494d..3bb2b1c4d 100644 --- a/build.yaml +++ b/build.yaml @@ -43,7 +43,7 @@ targets: - "example/**" - "lib/*.dart" - "test/*.dart" - - "web/*.dart" + - "web/**/index.dart" exclude: - "lib/src/builder/**" diff --git a/example/builder/abstract_inheritance.over_react.g.dart b/example/builder/abstract_inheritance.over_react.g.dart index aa56749ed..3881f6564 100644 --- a/example/builder/abstract_inheritance.over_react.g.dart +++ b/example/builder/abstract_inheritance.over_react.g.dart @@ -57,8 +57,7 @@ class _$$SubProps extends _$SubProps with _$SubPropsAccessorsMixin implements SubProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$SubProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -120,8 +119,7 @@ class _$$SubState extends _$SubState with _$SubStateAccessorsMixin implements SubState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$SubState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/example/builder/basic.over_react.g.dart b/example/builder/basic.over_react.g.dart index 71a660bd6..d357f10c9 100644 --- a/example/builder/basic.over_react.g.dart +++ b/example/builder/basic.over_react.g.dart @@ -133,8 +133,7 @@ class _$$BasicProps extends _$BasicProps with _$BasicPropsAccessorsMixin implements BasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/example/builder/basic_library.over_react.g.dart b/example/builder/basic_library.over_react.g.dart index 0926c876a..beb1e04a4 100644 --- a/example/builder/basic_library.over_react.g.dart +++ b/example/builder/basic_library.over_react.g.dart @@ -145,8 +145,7 @@ class _$$BasicPartOfLibProps extends _$BasicPartOfLibProps with _$BasicPartOfLibPropsAccessorsMixin implements BasicPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -215,8 +214,7 @@ class _$$BasicPartOfLibState extends _$BasicPartOfLibState with _$BasicPartOfLibStateAccessorsMixin implements BasicPartOfLibState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -315,8 +313,7 @@ class _$$SubPartOfLibProps extends _$SubPartOfLibProps with _$SubPartOfLibPropsAccessorsMixin implements SubPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$SubPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/example/builder/basic_with_state.over_react.g.dart b/example/builder/basic_with_state.over_react.g.dart index 2c6d6a76c..6e747cbfb 100644 --- a/example/builder/basic_with_state.over_react.g.dart +++ b/example/builder/basic_with_state.over_react.g.dart @@ -129,8 +129,7 @@ class _$$BasicProps extends _$BasicProps with _$BasicPropsAccessorsMixin implements BasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -195,8 +194,7 @@ class _$$BasicState extends _$BasicState with _$BasicStateAccessorsMixin implements BasicState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/example/builder/basic_with_type_params.over_react.g.dart b/example/builder/basic_with_type_params.over_react.g.dart index 48a2924e6..657b6c42c 100644 --- a/example/builder/basic_with_type_params.over_react.g.dart +++ b/example/builder/basic_with_type_params.over_react.g.dart @@ -79,8 +79,7 @@ class _$$BasicProps extends _$BasicProps with _$BasicPropsAccessorsMixin implements BasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/example/builder/generic_inheritance_sub.over_react.g.dart b/example/builder/generic_inheritance_sub.over_react.g.dart index db0a1afca..d14776d95 100644 --- a/example/builder/generic_inheritance_sub.over_react.g.dart +++ b/example/builder/generic_inheritance_sub.over_react.g.dart @@ -63,8 +63,7 @@ class _$$GenericSubProps extends _$GenericSubProps with _$GenericSubPropsAccessorsMixin implements GenericSubProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$GenericSubProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -132,8 +131,7 @@ class _$$GenericSubState extends _$GenericSubState with _$GenericSubStateAccessorsMixin implements GenericSubState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$GenericSubState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/example/builder/generic_inheritance_super.over_react.g.dart b/example/builder/generic_inheritance_super.over_react.g.dart index 04d4ab425..e54ee7ac1 100644 --- a/example/builder/generic_inheritance_super.over_react.g.dart +++ b/example/builder/generic_inheritance_super.over_react.g.dart @@ -97,8 +97,7 @@ class _$$GenericSuperProps extends _$GenericSuperProps with _$GenericSuperPropsAccessorsMixin implements GenericSuperProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$GenericSuperProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -167,8 +166,7 @@ class _$$GenericSuperState extends _$GenericSuperState with _$GenericSuperStateAccessorsMixin implements GenericSuperState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$GenericSuperState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/example/builder/private_component.over_react.g.dart b/example/builder/private_component.over_react.g.dart index 5b3dc3914..9496d7bef 100644 --- a/example/builder/private_component.over_react.g.dart +++ b/example/builder/private_component.over_react.g.dart @@ -59,8 +59,7 @@ class _$$_PrivateProps extends _$_PrivateProps with _$_PrivatePropsAccessorsMixin implements _PrivateProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$_PrivateProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -122,8 +121,7 @@ class _$$_PrivateState extends _$_PrivateState with _$_PrivateStateAccessorsMixin implements _PrivateState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$_PrivateState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/example/builder/private_factory_public_component.over_react.g.dart b/example/builder/private_factory_public_component.over_react.g.dart index 12054bea2..a1c7fa744 100644 --- a/example/builder/private_factory_public_component.over_react.g.dart +++ b/example/builder/private_factory_public_component.over_react.g.dart @@ -65,8 +65,7 @@ class _$$FormActionInputProps extends _$FormActionInputProps with _$FormActionInputPropsAccessorsMixin implements FormActionInputProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$FormActionInputProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/example/index.dart b/example/index.dart index fe2954cff..1f27d5392 100644 --- a/example/index.dart +++ b/example/index.dart @@ -1,7 +1,6 @@ import 'dart:html'; import 'package:over_react/over_react.dart'; -import 'package:react/react_client.dart' show ReactDartComponentFactoryProxy; import 'package:react/react_dom.dart' as react_dom; import './builder/abstract_inheritance.dart'; diff --git a/lib/over_react.dart b/lib/over_react.dart index 49ebd7c07..ec1bbbef0 100644 --- a/lib/over_react.dart +++ b/lib/over_react.dart @@ -27,6 +27,9 @@ export 'package:react/react.dart' show SyntheticUIEvent, SyntheticWheelEvent; +// FIXME 3.0.0-wip use public entrypoint +export 'package:react/src/react_client/js_backed_map.dart' show JsBackedMap; + export 'package:react/react_client.dart' show setClientConfiguration, ReactElement, ReactComponentFactoryProxy; export 'src/component/abstract_transition.dart'; diff --git a/lib/src/builder/generation/declaration_parsing.dart b/lib/src/builder/generation/declaration_parsing.dart index 0c5558873..7ffdc2fe4 100644 --- a/lib/src/builder/generation/declaration_parsing.dart +++ b/lib/src/builder/generation/declaration_parsing.dart @@ -485,10 +485,21 @@ class ParsedDeclarations { class ComponentNode extends NodeWithMeta { static const String _subtypeOfParamName = 'subtypeOf'; + /// Whether the component extends from Component2. + final bool isComponent2; + /// The value of the `subtypeOf` parameter passed in to this node's annotation. Identifier subtypeOfValue; - ComponentNode(unit) : super(unit) { + ComponentNode(ClassDeclaration node) + : this.isComponent2 = node.declaredElement == null + // This can be null when using non-resolved AST in tests; FIXME 3.0.0-wip do we need to update that setup? + ? false + // TODO 3.0.0-wip is there a better way to check against react's Component2? + : node.declaredElement.allSupertypes.any((type) { + return type.name == 'Component2'; + }), + super(node) { // Perform special handling for the `subtypeOf` parameter of this node's annotation. // // If valid, omit it from `unsupportedArguments` so that the `meta` can be accessed without it diff --git a/lib/src/builder/generation/impl_generation.dart b/lib/src/builder/generation/impl_generation.dart index 2db83473e..2acd9b053 100644 --- a/lib/src/builder/generation/impl_generation.dart +++ b/lib/src/builder/generation/impl_generation.dart @@ -14,6 +14,7 @@ import 'package:analyzer/analyzer.dart'; import 'package:logging/logging.dart'; +import 'package:meta/meta.dart'; import 'package:over_react/src/component_declaration/annotations.dart' as annotations; import 'package:over_react/src/builder/generation/declaration_parsing.dart'; import 'package:over_react/src/builder/util.dart'; @@ -67,8 +68,8 @@ class ImplGenerator { final generatedComponentFactoryName = _componentFactoryName(componentClassName); - String typedPropsFactoryImpl = ''; - String typedStateFactoryImpl = ''; + StringBuffer typedPropsFactoryImpl = new StringBuffer(); + StringBuffer typedStateFactoryImpl = new StringBuffer(); // ---------------------------------------------------------------------- // Factory implementation @@ -128,18 +129,57 @@ class ImplGenerator { _generateMetaConstImpl(AccessorType.props, declarations.props)); outputContentsBuffer.write(_generateConsumablePropsOrStateClass(AccessorType.props, declarations.props)); - /// _$$FooProps _$Foo([Map backingProps]) => new _$$FooProps(backingProps); - outputContentsBuffer.writeln('$propsImplName $privateSourcePrefix$factoryName([Map backingProps]) => new $propsImplName(backingProps);'); - - final String propKeyNamespace = _getAccessorKeyNamespace(declarations.props); + outputContentsBuffer.write( + '$propsImplName $privateSourcePrefix$factoryName([Map backingProps]) => '); + if (!declarations.component.isComponent2) { + /// _$$FooProps _$Foo([Map backingProps]) => new _$$FooProps(backingProps); + outputContentsBuffer.writeln('new $propsImplName(backingProps);'); + } else { + final jsMapImplName = _jsMapAccessorImplClassNameFromImplClassName(propsImplName); + outputContentsBuffer.writeln( + // FIXME clean up this logic and the null-awares (or lack thereof in the two impl classes) + // note: if we remove null-awares will that rbeak stuff like `typedPropsFactory(null)`? Does it even matter? + 'backingProps == null ? new $jsMapImplName(new JsBackedMap()) : new $propsImplName(backingProps);' + ); + } - outputContentsBuffer.write(_generateConcretePropsImpl( - AccessorType.props, consumerPropsName, propsImplName, generatedComponentFactoryName, - propKeyNamespace, declarations.props, propsAccessorsMixinName, consumablePropsName)); + outputContentsBuffer.write(_generateConcretePropsOrStateImpl( + type: AccessorType.props, + consumerName: consumerPropsName, + implName: propsImplName, + componentFactoryName: generatedComponentFactoryName, + propKeyNamespace: _getAccessorKeyNamespace(declarations.props), + node: declarations.props, + accessorsMixinName: propsAccessorsMixinName, + consumableName: consumablePropsName, + isComponent2: declarations.component.isComponent2, + )); + + if (declarations.component.isComponent2) { + final jsMapImplName = _jsMapAccessorImplClassNameFromImplClassName(propsImplName); + // This implementation here is necessary so that mixin accesses aren't compiled as index$ax + typedPropsFactoryImpl + ..writeln(' $jsMapImplName _cachedTypedProps;') + ..writeln() + ..writeln(' @override') + ..writeln(' $jsMapImplName get props => _cachedTypedProps;') + ..writeln() + ..writeln(' @override') + ..writeln(' set props(Map value) {') + ..writeln(' super.props = value;') + // FIXME 3.0.0-wip: is this implementation still needed here to get good dart2js output, or can we do it in the superclass? + ..writeln(' _cachedTypedProps = typedPropsFactoryJs(value);') + ..writeln(' }') + ..writeln() + ..writeln(' @override ') + ..writeln(' $jsMapImplName typedPropsFactoryJs(JsBackedMap backingMap) => new $jsMapImplName(backingMap);') + ..writeln(); + } + typedPropsFactoryImpl + ..writeln(' @override') + ..writeln(' $propsImplName typedPropsFactory(Map backingMap) => new $propsImplName(backingMap);') + ..writeln(); - typedPropsFactoryImpl = - ' @override\n' - ' $propsImplName typedPropsFactory(Map backingMap) => new $propsImplName(backingMap);\n\n'; // ---------------------------------------------------------------------- // State implementation @@ -149,8 +189,6 @@ class ImplGenerator { final consumableStateName = _publicPropsOrStateClassNameFromConsumerClassName(stateName); final stateImplName = _propsImplClassNameFromConsumerClassName(stateName); final stateAccessorsMixinName = _accessorsMixinNameFromConsumerName(stateName); - final typeParamsOnClass = declarations.state.node.typeParameters?.toSource() ?? ''; - final typeParamsOnSuper = removeBoundsFromTypeParameters(declarations.state.node.typeParameters); outputContentsBuffer.write(_generateAccessorsMixin( AccessorType.state, stateAccessorsMixinName, declarations.state, @@ -159,32 +197,41 @@ class ImplGenerator { _generateMetaConstImpl(AccessorType.state, declarations.state)); outputContentsBuffer.write(_generateConsumablePropsOrStateClass(AccessorType.state, declarations.state)); - outputContentsBuffer - ..writeln('// Concrete state implementation.') - ..writeln('//') - ..writeln('// Implements constructor and backing map.') - ..writeln('class $stateImplName$typeParamsOnClass extends $stateName$typeParamsOnSuper with $stateAccessorsMixinName$typeParamsOnSuper implements $consumableStateName$typeParamsOnSuper {') - ..writeln(' // This initializer of `_state` to an empty map, as well as the reassignment') - ..writeln(' // of `_state` in the constructor body is necessary to work around an unknown ddc issue.') - ..writeln(' // See for more details') - ..writeln(' $stateImplName(Map backingMap) : this._state = {} {') - ..writeln(' this._state = backingMap ?? {};') - ..writeln(' }') - ..writeln() - ..writeln(' /// The backing state map proxied by this class.') - ..writeln(' @override') - ..writeln(' Map get state => _state;') - ..writeln(' Map _state;') - ..writeln() - ..writeln(' /// Let [UiState] internals know that this class has been generated.') + outputContentsBuffer.write(_generateConcretePropsOrStateImpl( + type: AccessorType.state, + consumerName: stateName, + implName: stateImplName, + componentFactoryName: generatedComponentFactoryName, + propKeyNamespace: null, + node: declarations.state, + accessorsMixinName: stateAccessorsMixinName, + consumableName: consumableStateName, + isComponent2: declarations.component.isComponent2, + )); + + if (declarations.component.isComponent2) { + final jsMapImplName = _jsMapAccessorImplClassNameFromImplClassName(stateImplName); + // This implementation here is necessary so that mixin accesses aren't compiled as index$ax + typedStateFactoryImpl + ..writeln(' $jsMapImplName _cachedTypedState;') + ..writeln(' @override') + ..writeln(' $jsMapImplName get state => _cachedTypedState;') + ..writeln() + ..writeln(' @override') + ..writeln(' set state(Map value) {') + ..writeln(' super.state = value;') + ..writeln(' _cachedTypedState = typedStateFactoryJs(value);') + ..writeln(' }') + ..writeln() + ..writeln(' @override ') + // FIXME 3.0.0-wip: is this implementation still needed here to get good dart2js output, or can we do it in the superclass? + ..writeln(' $jsMapImplName typedStateFactoryJs(JsBackedMap backingMap) => new $jsMapImplName(backingMap);') + ..writeln(); + } + typedStateFactoryImpl ..writeln(' @override') - ..writeln(' bool get \$isClassGenerated => true;') - ..writeln('}') + ..writeln(' $stateImplName typedStateFactory(Map backingMap) => new $stateImplName(backingMap);') ..writeln(); - - typedStateFactoryImpl = - ' @override\n' - ' $stateImplName typedStateFactory(Map backingMap) => new $stateImplName(backingMap);\n\n'; } // ---------------------------------------------------------------------- @@ -316,8 +363,6 @@ class ImplGenerator { annotations.Accessor accessorMeta = instantiateAnnotation(field, annotations.Accessor); annotations.Accessor requiredProp = getConstantAnnotation(field, 'requiredProp', annotations.requiredProp); annotations.Accessor nullableRequiredProp = getConstantAnnotation(field, 'nullableRequiredProp', annotations.nullableRequiredProp); - // ignore: deprecated_member_use - annotations.Required requiredMeta = instantiateAnnotation(field, annotations.Required); if (accessorMeta?.doNotGenerate == true) { @@ -367,16 +412,6 @@ class ImplGenerator { } } - if (requiredMeta != null) { - constantValue += ', isRequired: true'; - - if (requiredMeta.isNullable) constantValue += ', isNullable: true'; - - if (requiredMeta.message != null && requiredMeta.message.isNotEmpty) { - constantValue += ', errorMessage: ${stringLiteral(requiredMeta.message)}'; - } - } - if (requiredProp != null) { annotationCount++; constantValue += ', isRequired: true'; @@ -434,10 +469,14 @@ class ImplGenerator { String generatedAccessor = ' $docComment\n' + // TODO reinstate inlining once https://github.com/dart-lang/sdk/issues/36217 is fixed and all workarounds are removed + // inlining is necessary to get mixins to use $index/$indexSet instead of $index$asx + // ' @tryInline\n' ' @override\n' '${metadataSrc.toString()}' ' ${typeString}get $accessorName => $proxiedMapName[$keyConstantName] ?? null; // Add ` ?? null` to workaround DDC bug: ;\n' ' $docComment\n' + // ' @tryInline\n' ' @override\n' '${metadataSrc.toString()}' ' set $accessorName(${setterTypeString}value) => $proxiedMapName[$keyConstantName] = value;\n'; @@ -523,6 +562,25 @@ class ImplGenerator { return className.replaceFirst(privateSourcePrefix, '$privateSourcePrefix\$'); } + /// Converts the abstract generated props/state implementation's classname + /// into the name of its subclass that can be backed by any Map. + /// + /// Example: + /// Input: '_$$FooProps' + /// Output: '_$$FooProps$PlainMap' + static String _plainMapAccessorsImplClassNameFromImplClassName(String implName) { + return '$implName\$PlainMap'; + } + /// Converts the abstract generated props/state implementation's classname + /// into the name of its subclass that can be backed by only JsMaps. + /// + /// Example: + /// Input: '_$$FooProps' + /// Output: '_$$FooProps$JsMap' + static String _jsMapAccessorImplClassNameFromImplClassName(String implName) { + return '$implName\$JsMap'; + } + /// Converts the consumer's written props classname to the consumable props /// classname by stripping [privateSourcePrefix] from the classname. /// @@ -700,32 +758,80 @@ class ImplGenerator { return buffer.toString(); } - String _generateConcretePropsImpl(AccessorType type, String consumerName, String implName, - String componentFactoryName, String propKeyNamespace, NodeWithMeta node, String accessorsMixinName, String consumableName) { + String _generateConcretePropsOrStateImpl({ + @required AccessorType type, + @required String consumerName, + @required String implName, + @required String componentFactoryName, + @required String propKeyNamespace, + @required NodeWithMeta node, + @required String accessorsMixinName, + @required String consumableName, + @required bool isComponent2, + }) { final typeParamsOnClass = node.node.typeParameters?.toSource() ?? ''; final typeParamsOnSuper = removeBoundsFromTypeParameters(node.node.typeParameters); - final classDeclaration = new StringBuffer() - ..write('class $implName$typeParamsOnClass extends $consumerName$typeParamsOnSuper with $accessorsMixinName$typeParamsOnSuper implements $consumableName$typeParamsOnSuper {\n'); - return (new StringBuffer() - ..writeln('// Concrete props implementation.') - ..writeln('//') - ..writeln('// Implements constructor and backing map, and links up to generated component factory.') - ..write(classDeclaration) - ..writeln(' // This initializer of `_props` to an empty map, as well as the reassignment') - ..writeln(' // of `_props` in the constructor body is necessary to work around an unknown ddc issue.') - ..writeln(' // See for more details') - ..writeln(' $implName(Map backingMap) : this._props = {} {') - ..writeln(' this._props = backingMap ?? {};') - ..writeln(' }') + + final classDeclaration = new StringBuffer(); + if (isComponent2) { + // This class will only have a factory constructor that instantiates one + // of two subclasses. + classDeclaration.write('abstract '); + } + classDeclaration.write('class $implName$typeParamsOnClass ' + 'extends $consumerName$typeParamsOnSuper ' + 'with $accessorsMixinName$typeParamsOnSuper ' + 'implements $consumableName$typeParamsOnSuper { '); + + final propsOrState = type.isProps ? 'props' : 'state'; + + // Class declaration + final buffer = new StringBuffer() + ..writeln('// Concrete $propsOrState implementation.') + ..writeln('//') + ..writeln('// Implements constructor and backing map${type.isProps ? ', and links up to generated component factory' : ''}.') + ..writeln(classDeclaration); + + // Constructors + if (isComponent2) { + final plainMapImplName = _plainMapAccessorsImplClassNameFromImplClassName(implName); + final jsMapImplName = _jsMapAccessorImplClassNameFromImplClassName(implName); + buffer + ..writeln(' $implName._();') ..writeln() - ..writeln(' /// The backing props map proxied by this class.') - ..writeln(' @override') - ..writeln(' Map get props => _props;') - ..writeln(' Map _props;') + ..writeln(' factory $implName(Map backingMap) {') + ..writeln(' if (backingMap is JsBackedMap) {') + ..writeln(' return new $jsMapImplName(backingMap);') + ..writeln(' } else {') + ..writeln(' return new $plainMapImplName(backingMap);') + ..writeln(' }') + ..writeln(' }'); + } else { + buffer + ..writeln(' // This initializer of `_$propsOrState` to an empty map, as well as the reassignment') + ..writeln(' // of `_$propsOrState` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217') + // TODO need to remove this workaround once https://github.com/dart-lang/sdk/issues/36217 is fixed get nice dart2js output + ..writeln(' $implName(Map backingMap) : this._$propsOrState = {} {') + ..writeln(' this._$propsOrState = backingMap ?? {};') + ..writeln(' }'); + } + + // Members + if (!isComponent2) { + buffer ..writeln() - ..writeln(' /// Let [UiProps] internals know that this class has been generated.') + ..writeln(' /// The backing $propsOrState map proxied by this class.') ..writeln(' @override') - ..writeln(' bool get \$isClassGenerated => true;') + ..writeln(' Map get $propsOrState => _$propsOrState;') + ..writeln(' Map _$propsOrState;'); + } + buffer + ..writeln() + ..writeln(' /// Let [${type.isProps ? 'UiProps' : 'UiState'}] internals know that this class has been generated.') + ..writeln(' @override') + ..writeln(' bool get \$isClassGenerated => true;'); + if (type.isProps) { + buffer ..writeln() ..writeln(' /// The [ReactComponentFactory] associated with the component built by this class.') ..writeln(' @override') @@ -733,10 +839,50 @@ class ImplGenerator { ..writeln() ..writeln(' /// The default namespace for the prop getters/setters generated for this class.') ..writeln(' @override') - ..writeln(' String get propKeyNamespace => ${stringLiteral(propKeyNamespace)};') + ..writeln(' String get propKeyNamespace => ${stringLiteral(propKeyNamespace)};'); + } + + // End of class body + buffer.writeln('}'); + + // Component2-specific classes + if (isComponent2) { + final plainMapImplName = _plainMapAccessorsImplClassNameFromImplClassName(implName); + final jsMapImplName = _jsMapAccessorImplClassNameFromImplClassName(implName); + buffer + ..writeln() + ..writeln('// Concrete $propsOrState implementation that can be backed by any [Map].') + ..writeln('class $plainMapImplName$typeParamsOnClass extends $implName$typeParamsOnSuper {') + ..writeln(' // This initializer of `_$propsOrState` to an empty map, as well as the reassignment') + ..writeln(' // of `_$propsOrState` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217') + // TODO need to remove this workaround once https://github.com/dart-lang/sdk/issues/36217 is fixed get nice dart2js output + ..writeln(' $plainMapImplName(Map backingMap) : this._$propsOrState = {}, super._() {') + ..writeln(' this._$propsOrState = backingMap ?? {};') + ..writeln(' }') + ..writeln() + ..writeln(' /// The backing $propsOrState map proxied by this class.') + ..writeln(' @override') + ..writeln(' Map get $propsOrState => _$propsOrState;') + ..writeln(' Map _$propsOrState;') ..writeln('}') - ..writeln()) - .toString(); + ..writeln() + ..writeln('// Concrete $propsOrState implementation that can only be backed by [JsMap],') + ..writeln('// allowing dart2js to compile more optimal code for key-value pair reads/writes.') + ..writeln('class $jsMapImplName$typeParamsOnClass extends $implName$typeParamsOnSuper {') + ..writeln(' // This initializer of `_$propsOrState` to an empty map, as well as the reassignment') + ..writeln(' // of `_$propsOrState` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217') + // TODO need to remove this workaround once https://github.com/dart-lang/sdk/issues/36217 is fixed get nice dart2js output + ..writeln(' $jsMapImplName(JsBackedMap backingMap) : this._$propsOrState = new JsBackedMap(), super._() {') + ..writeln(' this._$propsOrState = backingMap ?? new JsBackedMap();') + ..writeln(' }') + ..writeln() + ..writeln(' /// The backing $propsOrState map proxied by this class.') + ..writeln(' @override') + ..writeln(' JsBackedMap get $propsOrState => _$propsOrState;') + ..writeln(' JsBackedMap _$propsOrState;') + ..writeln('}'); + } + return buffer.toString(); } String _generateConsumablePropsOrStateClass(AccessorType type, NodeWithMeta node) { diff --git a/lib/src/component/dom_components.dart b/lib/src/component/dom_components.dart index a7370604c..c6ed763d6 100644 --- a/lib/src/component/dom_components.dart +++ b/lib/src/component/dom_components.dart @@ -20,6 +20,7 @@ import 'package:over_react/src/component_declaration/component_base.dart' as com import 'package:over_react/src/component_declaration/builder_helpers.dart' as builder_helpers; import 'package:react/react.dart' as react; import 'package:react/react_client.dart'; +import 'package:react/src/react_client/js_backed_map.dart'; /// Returns a new [DomProps], optionally backed by a specified Map. /// @@ -44,8 +45,10 @@ class DomProps extends component_base.UiProps builder_helpers.GeneratedClass implements builder_helpers.UiProps { - // Wrap Map literal in parens to work around https://github.com/dart-lang/sdk/issues/24410 - DomProps(this.componentFactory, [Map props]) : this.props = props ?? ({}); + // Initialize to a JsBackedMap so that copying can be optimized + // when converting props during ReactElement creation. + // TODO 3.0.0-wip generate JsBackedMap-based implementation used when no backing map is provided, like we do for Component2 + DomProps(this.componentFactory, [Map props]) : this.props = props ?? new JsBackedMap(); @override final ReactDomComponentFactoryProxy componentFactory; @@ -66,8 +69,10 @@ class SvgProps extends component_base.UiProps builder_helpers.GeneratedClass implements DomProps { - // Wrap Map literal in parens to work around https://github.com/dart-lang/sdk/issues/24410 - SvgProps(this.componentFactory, [Map props]) : this.props = props ?? ({}); + // Initialize to a JsBackedMap so that copying can be optimized + // when converting props during ReactElement creation. + // TODO 3.0.0-wip generate JsBackedMap-based implementation used when no backing map is provided, like we do for Component2 + SvgProps(this.componentFactory, [Map props]) : this.props = props ?? new JsBackedMap(); @override final ReactDomComponentFactoryProxy componentFactory; diff --git a/lib/src/component/dummy_component.dart b/lib/src/component/dummy_component.dart index f73b83ba2..dbce5076a 100644 --- a/lib/src/component/dummy_component.dart +++ b/lib/src/component/dummy_component.dart @@ -19,6 +19,7 @@ import 'package:react/react.dart' as react; /// Dummy component useful for: /// /// - Allowing sub-typing of components. +// ignore: deprecated_member_use class DummyComponent extends react.Component { @override render() => false; diff --git a/lib/src/component/error_boundary.over_react.g.dart b/lib/src/component/error_boundary.over_react.g.dart index d7b829361..a2a439230 100644 --- a/lib/src/component/error_boundary.over_react.g.dart +++ b/lib/src/component/error_boundary.over_react.g.dart @@ -126,8 +126,7 @@ class _$$ErrorBoundaryProps extends _$ErrorBoundaryProps with _$ErrorBoundaryPropsAccessorsMixin implements ErrorBoundaryProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ErrorBoundaryProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -204,8 +203,7 @@ class _$$ErrorBoundaryState extends _$ErrorBoundaryState with _$ErrorBoundaryStateAccessorsMixin implements ErrorBoundaryState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ErrorBoundaryState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/lib/src/component/resize_sensor.over_react.g.dart b/lib/src/component/resize_sensor.over_react.g.dart index fcd24193c..c4eb154d5 100644 --- a/lib/src/component/resize_sensor.over_react.g.dart +++ b/lib/src/component/resize_sensor.over_react.g.dart @@ -48,8 +48,7 @@ class _$$ResizeSensorProps extends _$ResizeSensorProps with _$ResizeSensorPropsAccessorsMixin implements ResizeSensorProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ResizeSensorProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/lib/src/component_declaration/annotations.dart b/lib/src/component_declaration/annotations.dart index be11af73d..fd0f6d78d 100644 --- a/lib/src/component_declaration/annotations.dart +++ b/lib/src/component_declaration/annotations.dart @@ -256,20 +256,6 @@ class Accessor { }); } -/// Deprecated. -/// -/// Use [Accessor], [requiredProp], or [nullableRequiredProp] instead. -@Deprecated('2.0.0') -class Required { - /// Whether setting a prop to null is allowed. - final bool isNullable; - - /// The message displayed when the prop is not set. - final String message; - - const Required({this.isNullable: false, this.message}); -} - abstract class TypedMap { String get keyNamespace; } diff --git a/lib/src/component_declaration/builder_helpers.dart b/lib/src/component_declaration/builder_helpers.dart index e7fe468ce..564b7bf66 100644 --- a/lib/src/component_declaration/builder_helpers.dart +++ b/lib/src/component_declaration/builder_helpers.dart @@ -15,13 +15,15 @@ library over_react.component_declaration.builder_helpers; import 'package:react/react_client.dart'; +// FIXME 3.0.0-wip use public entrypoint +import 'package:react/src/react_client/js_backed_map.dart'; import './component_base.dart' as component_base; import './annotations.dart' as annotations; export './annotations.dart'; export './component_base.dart' - hide UiComponent, UiStatefulComponent, UiProps, UiState; + hide UiComponent, UiStatefulComponent, UiComponent2, UiStatefulComponent2, UiProps, UiState; // ---------------------------------------------------------------------- // Base classes to be used by pre-generated code that stub out @@ -44,16 +46,8 @@ class GeneratedClass { } } - -/// See: [component_base.UiComponent] -/// -/// Use with the over_react builder via the `@Component()` ([annotations.Component]) annotation. -abstract class UiComponent extends component_base.UiComponent with GeneratedClass { - /// This class should not be instantiated directly, and throws an error to indicate this. - UiComponent() { - _throwIfNotGenerated(); - } - +mixin _GeneratedUiComponentStubs + on component_base.UiComponent, GeneratedClass { /// The default consumed props, taken from the keys generated in the associated @[annotations.Props] class. @toBeGenerated Iterable get $defaultConsumedProps => throw new UngeneratedError(member: #$defaultConsumedProps); @@ -72,39 +66,97 @@ abstract class UiComponent extends component_base.UiComp TProps typedPropsFactory(Map propsMap) => throw new UngeneratedError(member: #typedPropsFactory); } +mixin _GeneratedUiStatefulComponentStubs + on component_base.UiStatefulComponent, GeneratedClass { + /// Returns a typed state object backed by the specified [stateMap]. + /// + /// Required to properly instantiate the generic [TState] class. + @override + @toBeGenerated + TState typedStateFactory(Map stateMap) => throw new UngeneratedError(member: #typedStateFactory, message: + '${#typedStateFactory}` should be implemented by code generation.\n\n' + 'This error may be due to your `UiState` class not being annotated with `@State()`,\n' + 'or because you are extending a stateful component without redeclaring your own `@State()`, like so:\n\n' + ' @State()\n' + ' class MyState extends SuperState {}\n' + ); +} + +/// See: [component_base.UiComponent] +/// +/// Use with the over_react builder via the `@Component()` ([annotations.Component]) annotation. +abstract class UiComponent + extends component_base.UiComponent + with + GeneratedClass, + _GeneratedUiComponentStubs { + /// This class should not be instantiated directly, and throws an error to indicate this. + UiComponent() { + _throwIfNotGenerated(); + } +} /// See: [component_base.UiStatefulComponent] /// /// Use with the over_react builder via the `@Component()` ([annotations.Component]) annotation. abstract class UiStatefulComponent - extends component_base.UiStatefulComponent with GeneratedClass { + extends component_base.UiStatefulComponent + with + GeneratedClass, + _GeneratedUiComponentStubs, + _GeneratedUiStatefulComponentStubs { /// This class should not be instantiated directly, and throws an error to indicate this. UiStatefulComponent() { _throwIfNotGenerated(); } +} - /// The default consumed prop keys, taken from the keys generated in the associated @[annotations.Props] class. - @toBeGenerated - Iterable get $defaultConsumedProps => throw new UngeneratedError(member: #$defaultConsumedProps); - - /// The keys for the non-forwarding props defined in this component. - /// - /// For generated components, this defaults to the keys generated in the associated @[annotations.Props] class - /// if this getter is not overridden. - @override - Iterable get consumedProps => $defaultConsumedProps; - +mixin _GeneratedUiComponent2Stubs + on component_base.UiComponent2, GeneratedClass { /// Returns a typed props object backed by the specified [propsMap]. /// /// Required to properly instantiate the generic [TProps] class. + /// + /// This should be used where possible over [typedPropsFactory] to allow for + /// more efficient dart2js output. @override @toBeGenerated - TProps typedPropsFactory(Map propsMap) => throw new UngeneratedError(member: #typedPropsFactory); + TProps typedPropsFactoryJs(JsBackedMap propsMap) => throw new UngeneratedError(member: #typedPropsFactoryJs); +} + +abstract class UiComponent2 + extends component_base.UiComponent2 + with + GeneratedClass, + _GeneratedUiComponentStubs, + _GeneratedUiComponent2Stubs { + /// This class should not be instantiated directly, and throws an error to indicate this. + UiComponent2() { + _throwIfNotGenerated(); + } +} + +abstract class UiStatefulComponent2 + extends component_base.UiStatefulComponent2 + with + GeneratedClass, + _GeneratedUiComponentStubs, + _GeneratedUiComponent2Stubs, + _GeneratedUiStatefulComponentStubs { + /// This class should not be instantiated directly, and throws an error to indicate this. + UiStatefulComponent2() { + _throwIfNotGenerated(); + } /// Returns a typed state object backed by the specified [stateMap]. /// /// Required to properly instantiate the generic [TState] class. - @override @toBeGenerated TState typedStateFactory(Map stateMap) => throw new UngeneratedError(member: #typedStateFactory, message: + /// + /// This should be used where possible over [typedStateFactory] to allow for + /// more efficient dart2js output. + @override + @toBeGenerated + TState typedStateFactoryJs(JsBackedMap stateMap) => throw new UngeneratedError(member: #typedStateFactory, message: '${#typedStateFactory}` should be implemented by code generation.\n\n' 'This error may be due to your `UiState` class not being annotated with `@State()`,\n' 'or because you are extending a stateful component without redeclaring your own `@State()`, like so:\n\n' diff --git a/lib/src/component_declaration/built_redux_component.dart b/lib/src/component_declaration/built_redux_component.dart index 92f0ee7d5..226a7052b 100644 --- a/lib/src/component_declaration/built_redux_component.dart +++ b/lib/src/component_declaration/built_redux_component.dart @@ -99,6 +99,7 @@ abstract class BuiltReduxUiComponent< void redraw([callback()]) { _isDirty = true; + // ignore: deprecated_member_use super.redraw(() { _isDirty = false; diff --git a/lib/src/component_declaration/component_base.dart b/lib/src/component_declaration/component_base.dart index abfe4878c..4f344a53f 100644 --- a/lib/src/component_declaration/component_base.dart +++ b/lib/src/component_declaration/component_base.dart @@ -16,7 +16,6 @@ library over_react.component_declaration.component_base; import 'dart:async'; import 'dart:collection'; -import 'dart:html'; import 'package:meta/meta.dart'; import 'package:over_react/over_react.dart'; @@ -26,10 +25,14 @@ import 'package:over_react/src/component_declaration/util.dart'; import 'package:over_react/src/util/test_mode.dart'; import 'package:react/react.dart' as react; import 'package:react/react_client.dart'; +import 'package:react/src/react_client/js_backed_map.dart'; import 'package:w_common/disposable.dart'; export 'package:over_react/src/component_declaration/component_type_checking.dart' show isComponentOfType, isValidElementOfType; +part 'component_base/component_base_2.dart'; +part 'component_base/disposable_manager_proxy.dart'; + /// Helper function that wraps react.registerComponent, and allows attachment of additional /// component factory metadata. /// @@ -40,13 +43,16 @@ export 'package:over_react/src/component_declaration/component_type_checking.dar /// used as types for [isComponentOfType]/[getComponentFactory]. /// /// * [displayName]: the name of the component for use when debugging. +// ignore: deprecated_member_use ReactDartComponentFactoryProxy registerComponent(react.Component dartComponentFactory(), { bool isWrapper: false, + // ignore: deprecated_member_use ReactDartComponentFactoryProxy parentType, UiFactory builderFactory, Type componentClass, String displayName }) { + // ignore: deprecated_member_use ReactDartComponentFactoryProxy reactComponentFactory = react.registerComponent(dartComponentFactory); if (displayName != null) { @@ -67,6 +73,7 @@ ReactDartComponentFactoryProxy registerComponent(react.Component dartComponentFa /// __The result must be stored in a variable that is named very specifically:__ /// /// var $`AbstractComponentClassName`Factory = registerAbstractComponent(`AbstractComponentClassName`); +// ignore: deprecated_member_use ReactDartComponentFactoryProxy registerAbstractComponent(Type abstractComponentClass, {ReactDartComponentFactoryProxy parentType}) => registerComponent(() => new DummyComponent(), componentClass: abstractComponentClass, parentType: parentType); @@ -126,9 +133,7 @@ typedef TProps BuilderOnlyUiFactory(); /// } /// /// > Related: [UiStatefulComponent] -abstract class UiComponent extends react.Component implements DisposableManagerV7 { - Disposable _disposableProxy; - +abstract class UiComponent extends react.Component with _DisposableManagerProxy { /// The props for the non-forwarding props defined in this component. Iterable get consumedProps => null; @@ -274,106 +279,6 @@ abstract class UiComponent extends react.Component imple // END Typed props helpers // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- - - // ---------------------------------------------------------------------- - // ---------------------------------------------------------------------- - // BEGIN DisposableManagerV7 interface implementation - // - - @override - Future awaitBeforeDispose(Future future) => - _getDisposableProxy().awaitBeforeDispose(future); - - @override - Future getManagedDelayedFuture(Duration duration, T callback()) => - _getDisposableProxy().getManagedDelayedFuture(duration, callback); - - @override - ManagedDisposer getManagedDisposer(Disposer disposer) => _getDisposableProxy().getManagedDisposer(disposer); - - @override - Timer getManagedPeriodicTimer(Duration duration, void callback(Timer timer)) => - _getDisposableProxy().getManagedPeriodicTimer(duration, callback); - - @override - Timer getManagedTimer(Duration duration, void callback()) => - _getDisposableProxy().getManagedTimer(duration, callback); - - @override - StreamSubscription listenToStream( - Stream stream, void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) => - _getDisposableProxy().listenToStream( - stream, onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); - - @override - Disposable manageAndReturnDisposable(Disposable disposable) => - _getDisposableProxy().manageAndReturnDisposable(disposable); - - @override - Completer manageCompleter(Completer completer) => - _getDisposableProxy().manageCompleter(completer); - - @override - void manageDisposable(Disposable disposable) => - _getDisposableProxy().manageDisposable(disposable); - - /// DEPRECATED. Use [getManagedDisposer] instead. - @Deprecated('2.0.0') - @override - void manageDisposer(Disposer disposer) => - _getDisposableProxy().manageDisposer(disposer); - - @override - void manageStreamController(StreamController controller) => - _getDisposableProxy().manageStreamController(controller); - - /// DEPRECATED. Use [listenToStream] instead. - @Deprecated('2.0.0') - @override - void manageStreamSubscription(StreamSubscription subscription) => - _getDisposableProxy().manageStreamSubscription(subscription); - - /// Instantiates a new [Disposable] instance on the first call to the - /// [DisposableManagerV7] method. - Disposable _getDisposableProxy() { - if (_disposableProxy == null) { - _disposableProxy = new Disposable(); - } - return _disposableProxy; - } - - /// Automatically dispose another object when this object is disposed. - /// - /// This method is an extension to `manageAndReturnDisposable` and returns the - /// passed in [Disposable] as its original type in addition to handling its - /// disposal. The method should be used when a variable is set and should - /// conditionally be managed for disposal. The most common case will be dealing - /// with optional parameters: - /// - /// class MyDisposable extends Disposable { - /// // This object also extends disposable - /// MyObject _internal; - /// - /// MyDisposable({MyObject optional}) { - /// // If optional is injected, we should not manage it. - /// // If we create our own internal reference we should manage it. - /// _internal = optional ?? - /// manageAndReturnTypedDisposable(new MyObject()); - /// } - /// - /// // ... - /// } - /// - /// The parameter may not be `null`. - @override - T manageAndReturnTypedDisposable(T disposable) => - _disposableProxy.manageAndReturnTypedDisposable(disposable); - - // - // END DisposableManagerV7 interface implementation - // ---------------------------------------------------------------------- - // ---------------------------------------------------------------------- } /// The basis for a _stateful_ over_react component. @@ -678,8 +583,9 @@ abstract class UiProps extends MapBase /// An unmodifiable map view of the default props for this component brought /// in from the [componentFactory]. + // ignore: deprecated_member_use Map get componentDefaultProps => componentFactory is ReactDartComponentFactoryProxy - // ignore: avoid_as + // ignore: avoid_as, deprecated_member_use ? (componentFactory as ReactDartComponentFactoryProxy).defaultProps : const {}; } diff --git a/lib/src/component_declaration/component_base/component_base_2.dart b/lib/src/component_declaration/component_base/component_base_2.dart new file mode 100644 index 000000000..a152020a9 --- /dev/null +++ b/lib/src/component_declaration/component_base/component_base_2.dart @@ -0,0 +1,221 @@ +// Copyright 2019 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +part of over_react.component_declaration.component_base; + +// FIXME 3.0.0-wip update doc comment +abstract class UiComponent2 extends react.Component2 + with _DisposableManagerProxy + implements UiComponent { + @override + Map getDefaultProps() => new JsBackedMap(); + + /// The props for the non-forwarding props defined in this component. + @override + Iterable get consumedProps => null; + + /// Returns a copy of this component's props with keys found in [consumedProps] omitted. + /// + /// > Should be used alongside [forwardingClassNameBuilder]. + /// + /// > Related [copyUnconsumedDomProps] + @override + Map copyUnconsumedProps() { + var consumedPropKeys = consumedProps?.map((ConsumedProps consumedProps) => consumedProps.keys) ?? const []; + + return copyProps(keySetsToOmit: consumedPropKeys); + } + + /// Returns a copy of this component's props with keys found in [consumedProps] and non-DOM props omitted. + /// + /// > Should be used alongside [forwardingClassNameBuilder]. + /// + /// > Related [copyUnconsumedProps] + @override + Map copyUnconsumedDomProps() { + var consumedPropKeys = consumedProps?.map((ConsumedProps consumedProps) => consumedProps.keys) ?? const []; + + return copyProps(onlyCopyDomProps: true, keySetsToOmit: consumedPropKeys); + } + + /// Returns a copy of this component's props with React props optionally omitted, and + /// with the specified [keysToOmit] and [keySetsToOmit] omitted. + @override + Map copyProps({bool omitReservedReactProps: true, bool onlyCopyDomProps: false, Iterable keysToOmit, Iterable keySetsToOmit}) { + return getPropsToForward(this.props, + omitReactProps: omitReservedReactProps, + onlyCopyDomProps: onlyCopyDomProps, + keysToOmit: keysToOmit, + keySetsToOmit: keySetsToOmit + ); + } + + /// Throws a [PropError] if [appliedProps] are invalid. + /// + /// This is called automatically with the latest props available during [componentWillReceiveProps] and + /// [componentWillMount], and can also be called manually for custom validation. + /// + /// Override with a custom implementation to easily add validation (and don't forget to call super!) + /// + /// @mustCallSuper + /// void validateProps(Map appliedProps) { + /// super.validateProps(appliedProps); + /// + /// var tProps = typedPropsFactory(appliedProps); + /// if (tProps.items.length.isOdd) { + /// throw new PropError.value(tProps.items, 'items', 'must have an even number of items, because reasons'); + /// } + /// } + @mustCallSuper + @override + void validateProps(Map appliedProps) { + validateRequiredProps(appliedProps); + } + + /// Validates that props with the `@requiredProp` annotation are present. + @override + void validateRequiredProps(Map appliedProps) { + consumedProps?.forEach((ConsumedProps consumedProps) { + consumedProps.props.forEach((PropDescriptor prop) { + if (!prop.isRequired) return; + if (prop.isNullable && appliedProps.containsKey(prop.key)) return; + if (!prop.isNullable && appliedProps[prop.key] != null) return; + + throw new PropError.required(prop.key, prop.errorMessage); + }); + }); + } + + /// Returns a new ClassNameBuilder with className and blacklist values added from [CssClassPropsMixin.className] and + /// [CssClassPropsMixin.classNameBlacklist], if they are specified. + /// + /// This method should be used as the basis for the classNames of components receiving forwarded props. + /// + /// > Should be used alongside [copyUnconsumedProps] or [copyUnconsumedDomProps]. + @override + ClassNameBuilder forwardingClassNameBuilder() { + return new ClassNameBuilder.fromProps(this.props); + } + + @override + @mustCallSuper + void componentWillUnmount() { + _disposableProxy?.dispose(); + } + + // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- + // BEGIN Typed props helpers + // + + /// A typed props object corresponding to the current untyped props Map ([unwrappedProps]). + /// + /// Created using [typedPropsFactory] and cached for each Map instance. + @override + TProps get props { + // This needs to be a concrete implementation in Dart 2 for soundness; + // without it, you get a confusing error. See: https://github.com/dart-lang/sdk/issues/36191 + throw new UngeneratedError(); + } + + /// Equivalent to setting [unwrappedProps], but needed by react-dart to effect props changes. + @override + set props(Map value) => super.props = value; + + /// The props Map that will be used to create the typed [props] object. + @override + Map get unwrappedProps => super.props; + @override + set unwrappedProps(Map value) => super.props = value; + + /// Returns a typed props object backed by the specified [propsMap]. + /// + /// Required to properly instantiate the generic [TProps] class. + @override + TProps typedPropsFactory(Map propsMap); + + /// Returns a typed props object backed by the specified [propsMap]. + /// + /// Required to properly instantiate the generic [TProps] class. + /// + /// This should be used where possible over [typedPropsFactory] to allow for + /// more efficient dart2js output. + TProps typedPropsFactoryJs(JsBackedMap propsMap); + + /// Returns a typed props object backed by a new Map. + /// + /// Convenient for use with [getDefaultProps]. + @override + TProps newProps() => typedPropsFactoryJs(new JsBackedMap()); + + // + // END Typed props helpers + // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- +} + +// FIXME 3.0.0-wip update doc comment +abstract class UiStatefulComponent2 + extends UiComponent2 + implements UiStatefulComponent { + // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- + // BEGIN Typed state helpers + // + + /// A typed state object corresponding to the current untyped state Map ([unwrappedState]). + /// + /// Created using [typedStateFactory] and cached for each Map instance. + @override + TState get state { + // This needs to be a concrete implementation in Dart 2 for soundness; + // without it, you get a confusing error. See: https://github.com/dart-lang/sdk/issues/36191 + throw new UngeneratedError(); + } + + /// Equivalent to setting [unwrappedState], but needed by react-dart to effect state changes. + @override + set state(Map value) => super.state = value; + + /// The state Map that will be used to create the typed [state] object. + @override + Map get unwrappedState => super.state; + @override + set unwrappedState(Map value) => super.state = value; + + /// Returns a typed state object backed by the specified [stateMap]. + /// + /// Required to properly instantiate the generic [TState] class. + @override + TState typedStateFactory(Map stateMap); + + /// Returns a typed state object backed by the specified [stateMap]. + /// + /// Required to properly instantiate the generic [TState] class. + /// + /// This should be used where possible over [typedStateFactory] to allow for + /// more efficient dart2js output. + TState typedStateFactoryJs(JsBackedMap stateMap); + + /// Returns a typed state object backed by a new Map. + /// + /// Convenient for use with [getInitialState] and [setState]. + @override + TState newState() => typedStateFactoryJs(new JsBackedMap()); + + // + // END Typed state helpers + // ---------------------------------------------------------------------- + // ---------------------------------------------------------------------- +} diff --git a/lib/src/component_declaration/component_base/disposable_manager_proxy.dart b/lib/src/component_declaration/component_base/disposable_manager_proxy.dart new file mode 100644 index 000000000..0ee11bac9 --- /dev/null +++ b/lib/src/component_declaration/component_base/disposable_manager_proxy.dart @@ -0,0 +1,108 @@ +// Copyright 2019 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +part of over_react.component_declaration.component_base; + +/// An implementation of [DisposableManagerV7] for use by +/// [UiComponent] and [UiComponent2]. +mixin _DisposableManagerProxy implements DisposableManagerV7 { + Disposable _disposableProxy; + + @override + Future awaitBeforeDispose(Future future) => + _getDisposableProxy().awaitBeforeDispose(future); + + @override + Future getManagedDelayedFuture(Duration duration, T callback()) => + _getDisposableProxy().getManagedDelayedFuture(duration, callback); + + @override + ManagedDisposer getManagedDisposer(Disposer disposer) => + _getDisposableProxy().getManagedDisposer(disposer); + + @override + Timer getManagedPeriodicTimer( + Duration duration, void callback(Timer timer)) => + _getDisposableProxy().getManagedPeriodicTimer(duration, callback); + + @override + Timer getManagedTimer(Duration duration, void callback()) => + _getDisposableProxy().getManagedTimer(duration, callback); + + @override + StreamSubscription listenToStream( + Stream stream, void onData(T event), + {Function onError, void onDone(), bool cancelOnError,}) => + _getDisposableProxy().listenToStream(stream, onData, + onError: onError, onDone: onDone, cancelOnError: cancelOnError); + + @override + Disposable manageAndReturnDisposable(Disposable disposable) => + _getDisposableProxy().manageAndReturnDisposable(disposable); + + @override + Completer manageCompleter(Completer completer) => + _getDisposableProxy().manageCompleter(completer); + + @override + void manageDisposable(Disposable disposable) => + _getDisposableProxy().manageDisposable(disposable); + + /// DEPRECATED. Use [getManagedDisposer] instead. + @Deprecated('w_common 2.0.0') + @override + void manageDisposer(Disposer disposer) => + _getDisposableProxy().manageDisposer(disposer); + + @override + void manageStreamController(StreamController controller) => + _getDisposableProxy().manageStreamController(controller); + + /// DEPRECATED. Use [listenToStream] instead. + @Deprecated('w_common 2.0.0') + @override + void manageStreamSubscription(StreamSubscription subscription) => + _getDisposableProxy().manageStreamSubscription(subscription); + + /// Instantiates a new [Disposable] instance on the first call to the + /// [DisposableManagerV7] method. + Disposable _getDisposableProxy() => _disposableProxy ??= new Disposable(); + + /// Automatically dispose another object when this object is disposed. + /// + /// This method is an extension to `manageAndReturnDisposable` and returns the + /// passed in [Disposable] as its original type in addition to handling its + /// disposal. The method should be used when a variable is set and should + /// conditionally be managed for disposal. The most common case will be dealing + /// with optional parameters: + /// + /// class MyDisposable extends Disposable { + /// // This object also extends disposable + /// MyObject _internal; + /// + /// MyDisposable({MyObject optional}) { + /// // If optional is injected, we should not manage it. + /// // If we create our own internal reference we should manage it. + /// _internal = optional ?? + /// manageAndReturnTypedDisposable(new MyObject()); + /// } + /// + /// // ... + /// } + /// + /// The parameter may not be `null`. + @override + T manageAndReturnTypedDisposable(T disposable) => + _disposableProxy.manageAndReturnTypedDisposable(disposable); +} diff --git a/lib/src/component_declaration/component_type_checking.dart b/lib/src/component_declaration/component_type_checking.dart index 7794149ba..16ebf8648 100644 --- a/lib/src/component_declaration/component_type_checking.dart +++ b/lib/src/component_declaration/component_type_checking.dart @@ -27,10 +27,12 @@ import 'package:react/react_client/react_interop.dart'; // ---------------------------------------------------------------------- +// ignore: deprecated_member_use Expando _typeAliasToFactory = new Expando(); /// Registers a type alias for the specified factory, so that [getComponentTypeFromAlias] can be /// called with [typeAlias] to retrieve [factory]'s [ReactClass] type. +// ignore: deprecated_member_use void registerComponentTypeAlias(ReactDartComponentFactoryProxy factory, dynamic typeAlias) { if (typeAlias != null) { _typeAliasToFactory[typeAlias] = factory; @@ -45,8 +47,10 @@ const String _componentTypeMetaKey = '_componentTypeMeta'; /// the component type of the specified [factory]. /// /// This meta is retrievable via [getComponentTypeMeta]. +// ignore: deprecated_member_use void setComponentTypeMeta(ReactDartComponentFactoryProxy factory, { bool isWrapper, + // ignore: deprecated_member_use ReactDartComponentFactoryProxy parentType }) { setProperty(factory.type, _componentTypeMetaKey, new ComponentTypeMeta(isWrapper, parentType)); @@ -109,6 +113,7 @@ class ComponentTypeMeta { /// isComponentOfType(Bar()(), Foo); // true (due to parent type-checking) /// /// > See: `subtypeOf` (within [annotations.Component]) + // ignore: deprecated_member_use final ReactDartComponentFactoryProxy parentType; ComponentTypeMeta(this.isWrapper, this.parentType); diff --git a/lib/src/util/map_util.dart b/lib/src/util/map_util.dart index 66c63e5e0..94a1752a4 100644 --- a/lib/src/util/map_util.dart +++ b/lib/src/util/map_util.dart @@ -18,6 +18,7 @@ import 'dart:collection'; import 'package:over_react/src/component/dom_components.dart'; import 'package:over_react/src/component/prop_mixins.dart'; +import 'package:react/src/react_client/js_backed_map.dart'; /// Returns a copy of the specified [props] map, omitting reserved React props by default, /// in addition to any specified [keysToOmit] or [keySetsToOmit]. @@ -31,7 +32,7 @@ Map getPropsToForward(Map props, { Iterable keysToOmit, Iterable keySetsToOmit }) { - Map propsToForward = new Map.from(props); + Map propsToForward = new JsBackedMap.from(props); if (omitReactProps) { propsToForward diff --git a/lib/src/util/react_wrappers.dart b/lib/src/util/react_wrappers.dart index 030bfe1f6..4c428e004 100644 --- a/lib/src/util/react_wrappers.dart +++ b/lib/src/util/react_wrappers.dart @@ -46,7 +46,8 @@ import 'package:react/react_dom.dart' as react_dom; /// Returns internal data structure used by react-dart to maintain the native Dart component /// for a given react-dart [ReactElement] or [ReactComponent] [instance]. ReactDartComponentInternal _getInternal(/* ReactElement|ReactComponent */ instance) => - (instance.props as InteropProps).internal; // ignore: avoid_as + // ignore: deprecated_member_use + (instance.props as InteropProps).internal; /// Returns the internal representation of a Dart component's props as maintained by react-dart. /// @@ -154,6 +155,7 @@ Map getProps(/* ReactElement|ReactComponent */ instance, {bool traverseWrappers: } /// Returns the DOM node associated with a mounted React component [instance], +// ignore: deprecated_member_use /// which can be a [ReactComponent]/[Element] or [react.Component]. /// /// This method simply wraps react.findDOMNode with strong typing for the return value @@ -186,8 +188,11 @@ bool _isCompositeComponent(dynamic object) { /// /// Handles both Dart and JS React components, returning the appropriate props structure for each type: /// -/// * For Dart components, existing props are read from [InteropProps.internal], which are then merged with +// ignore: deprecated_member_use +/// * For non-[react.Component2] Dart components, existing props are read from [InteropProps.internal], which are then merged with /// the new [newProps] and saved in a new [InteropProps] with the expected [ReactDartComponentInternal] structure. +/// * For [react.Component2] Dart components, [newProps] is passed through [ReactDartComponentFactoryProxy2.generateExtendedJsProps] +/// and then passed to React JS, which will merge the props normally. /// * Children are likewise copied and potentially overwritten with [newChildren] as expected. /// * For JS components, a copy of [newProps] is returned, since React will merge the props without any special handling. dynamic preparePropsChangeset(ReactElement element, Map newProps, [Iterable newChildren]) { @@ -195,22 +200,28 @@ dynamic preparePropsChangeset(ReactElement element, Map newProps, [Iterable newC final internal = _getInternal(element); if (internal == null) { - // Plain JS component + // react-dart Component2, JS composite component, DOM component if (newProps == null) { propsChangeset = null; } else { - if (isDomElement(element)) { + final type = element.type; + if (type is String) { // DOM component // Convert props for DOM components so that style Maps and event handlers // are properly converted. Map convertedProps = new Map.from(newProps); ReactDomComponentFactoryProxy.convertProps(convertedProps); propsChangeset = jsify(convertedProps); } else { - propsChangeset = jsify(newProps); + final ReactClass reactClass = type; + if (reactClass.dartComponentVersion == '2') { + propsChangeset = ReactDartComponentFactoryProxy2.generateExtendedJsProps(newProps); + } else { + propsChangeset = jsify(newProps); + } } } } else { - // react-dart component + // react-dart Component (not Component2) Map oldExtendedProps = internal.props; Map extendedProps = new Map.from(oldExtendedProps); @@ -218,6 +229,7 @@ dynamic preparePropsChangeset(ReactElement element, Map newProps, [Iterable newC extendedProps.addAll(newProps); } + // ignore: deprecated_member_use propsChangeset = ReactDartComponentFactoryProxy.generateExtendedJsProps(extendedProps, newChildren ?? extendedProps['children']); } @@ -249,6 +261,7 @@ ReactElement cloneElement(ReactElement element, [Map props, Iterable children]) /// Returns the native Dart component associated with a mounted component [instance]. /// /// Returns `null` if the [instance] is not Dart-based _(an [Element] or a JS composite component)_. +// ignore: deprecated_member_use T getDartComponent(/* ReactElement|ReactComponent|Element */ instance) { if (instance is Element) { return null; @@ -301,6 +314,7 @@ T getDartComponent(/* ReactElement|ReactComponent|Ele /// /// The component instance will be of the type: /// +// ignore: deprecated_member_use /// * [react.Component] for Dart components /// * [ReactComponent] for JS composite components /// * [Element] for DOM components @@ -350,6 +364,7 @@ CallbackRef chainRef(ReactElement element, CallbackRef newCallbackRef) { // callback ref and converts the JS instance to the Dart component. // // So, we need to undo the wrapping around this chained ref and pass in the JS instance. + // ignore: deprecated_member_use existingRef(ref is react.Component ? ref.jsThis : ref); if (newCallbackRef != null) newCallbackRef(ref); diff --git a/lib/src/util/validation_util.dart b/lib/src/util/validation_util.dart index b1f82e5bc..43aad8da1 100644 --- a/lib/src/util/validation_util.dart +++ b/lib/src/util/validation_util.dart @@ -86,6 +86,7 @@ class ValidationUtil { if (isValidElement(data)) { window.console.log('props: ${prettyPrintMap(getProps(data))}'); + // ignore: deprecated_member_use } else if (data is react.Component) { window.console.log('props: ${data.props}'); } diff --git a/pubspec.yaml b/pubspec.yaml index 596867969..4a7f7f547 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,3 +39,11 @@ dev_dependencies: mockito: ^4.0.0 over_react_test: ^2.4.0 test: ^1.0.0 + + +dependency_overrides: + react: + git: + url: https://github.com/cleandart/react-dart.git + ref: 5.0.0-wip + diff --git a/test/over_react/component/abstract_transition_test.over_react.g.dart b/test/over_react/component/abstract_transition_test.over_react.g.dart index 31592bdb6..b21b51797 100644 --- a/test/over_react/component/abstract_transition_test.over_react.g.dart +++ b/test/over_react/component/abstract_transition_test.over_react.g.dart @@ -209,8 +209,7 @@ class _$$TransitionerProps extends _$TransitionerProps with _$TransitionerPropsAccessorsMixin implements TransitionerProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TransitionerProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -262,8 +261,7 @@ class _$$TransitionerState extends _$TransitionerState with _$TransitionerStateAccessorsMixin implements TransitionerState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TransitionerState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.dart index aee691b6d..ba17a1c64 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.dart @@ -14,7 +14,7 @@ import 'package:over_react/over_react.dart'; import 'package:test/test.dart'; -import './required_prop_integration_tests.dart' as r; +import './constant_required_accessor_integration_test.dart' as r; import '../../../../test_util/test_util.dart'; // ignore: uri_has_not_been_generated @@ -119,8 +119,6 @@ main() { expect(shallowPropKeys.where((String key) => !key.startsWith('data-prop-')), unorderedEquals(['id', 'extraneous', 'children'])); }); - - r.requiredPropsIntegrationTest(); }); } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.over_react.g.dart index d088dcedb..823ab9aa2 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/component_integration_test.over_react.g.dart @@ -149,8 +149,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/constant_required_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/constant_required_accessor_integration_test.over_react.g.dart index 29c026399..164caec1a 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/constant_required_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/constant_required_accessor_integration_test.over_react.g.dart @@ -80,8 +80,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/do_not_generate_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/do_not_generate_accessor_integration_test.over_react.g.dart index 95db004f3..759a1332c 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/do_not_generate_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/do_not_generate_accessor_integration_test.over_react.g.dart @@ -103,8 +103,7 @@ class _$$DoNotGenerateAccessorTestProps extends _$DoNotGenerateAccessorTestProps with _$DoNotGenerateAccessorTestPropsAccessorsMixin implements DoNotGenerateAccessorTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$DoNotGenerateAccessorTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -211,8 +210,7 @@ class _$$DoNotGenerateAccessorTestState extends _$DoNotGenerateAccessorTestState with _$DoNotGenerateAccessorTestStateAccessorsMixin implements DoNotGenerateAccessorTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$DoNotGenerateAccessorTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/namespaced_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/namespaced_accessor_integration_test.over_react.g.dart index 8134f4d52..afc4dee84 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/namespaced_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/namespaced_accessor_integration_test.over_react.g.dart @@ -157,8 +157,7 @@ class _$$NamespacedAccessorTestProps extends _$NamespacedAccessorTestProps with _$NamespacedAccessorTestPropsAccessorsMixin implements NamespacedAccessorTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$NamespacedAccessorTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -320,8 +319,7 @@ class _$$NamespacedAccessorTestState extends _$NamespacedAccessorTestState with _$NamespacedAccessorTestStateAccessorsMixin implements NamespacedAccessorTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$NamespacedAccessorTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/private_props_ddc_bug.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/private_props_ddc_bug.over_react.g.dart index 6c9aa8654..68f9a179f 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/private_props_ddc_bug.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/private_props_ddc_bug.over_react.g.dart @@ -54,8 +54,7 @@ class _$$FooProps extends _$FooProps with _$FooPropsAccessorsMixin implements FooProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$FooProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_accessor_integration_test.over_react.g.dart index 5223f9342..4b5feaacb 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_accessor_integration_test.over_react.g.dart @@ -93,8 +93,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/stateful_component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/stateful_component_integration_test.over_react.g.dart index f0e13dac4..b49e6bbec 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/stateful_component_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/stateful_component_integration_test.over_react.g.dart @@ -43,8 +43,7 @@ class _$$StatefulComponentTestProps extends _$StatefulComponentTestProps with _$StatefulComponentTestPropsAccessorsMixin implements StatefulComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$StatefulComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -206,8 +205,7 @@ class _$$StatefulComponentTestState extends _$StatefulComponentTestState with _$StatefulComponentTestStateAccessorsMixin implements StatefulComponentTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$StatefulComponentTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/unassigned_prop_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/unassigned_prop_integration_test.over_react.g.dart index d7354bba2..341fc5d36 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/unassigned_prop_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/unassigned_prop_integration_test.over_react.g.dart @@ -71,8 +71,7 @@ class _$$FooProps extends _$FooProps with _$FooPropsAccessorsMixin implements FooProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$FooProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.dart new file mode 100644 index 000000000..3d3157e21 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.dart @@ -0,0 +1,240 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +// ignore: uri_has_not_been_generated +part 'abstract_accessor_integration_test.over_react.g.dart'; + +main() { + group('(Component2) abstract accessor integration:', () { + group('@AbstractProps()', () { + group('generates prop getters/setters with', () { + test('the props class name as a namespace and the prop name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestAbstractPropsSubclass()..stringProp = 'test'; + expect(mixinsTest.props, containsPair('TestAbstractProps.stringProp', 'test')); + + mixinsTest = new TestAbstractPropsSubclass()..dynamicProp = 2; + expect(mixinsTest.props, containsPair('TestAbstractProps.dynamicProp', 2)); + + mixinsTest = new TestAbstractPropsSubclass()..untypedProp = false; + expect(mixinsTest.props, containsPair('TestAbstractProps.untypedProp', false)); + }); + + test('custom prop keys', () { + var mixinsTest = new TestAbstractPropsSubclass()..customKeyProp = 'test'; + expect(mixinsTest.props, containsPair('TestAbstractProps.custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + var mixinsTest = new TestAbstractPropsSubclass()..customNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + var mixinsTest = new TestAbstractPropsSubclass()..customKeyAndNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + group('generates prop getters/setters, when there is a custom key namespace, with', () { + test('the custom namespace and the prop name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..stringProp = 'test'; + expect(mixinsTest.props, containsPair('custom mixin namespace**stringProp', 'test')); + + mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..dynamicProp = 2; + expect(mixinsTest.props, containsPair('custom mixin namespace**dynamicProp', 2)); + + mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..untypedProp = false; + expect(mixinsTest.props, containsPair('custom mixin namespace**untypedProp', false)); + }); + + test('custom prop keys', () { + var mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..customKeyProp = 'test'; + expect(mixinsTest.props, containsPair('custom mixin namespace**custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + var mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..customNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + var mixinsTest = new TestCustomNamespaceAbstractPropsSubclass()..customKeyAndNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + }); + + group('@AbstractState()', () { + group('generates state getters/setters with', () { + test('the state class name as a namespace and the state name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestAbstractStateSubclass()..stringState = 'test'; + expect(mixinsTest.state, containsPair('TestAbstractState.stringState', 'test')); + + mixinsTest = new TestAbstractStateSubclass()..dynamicState = 2; + expect(mixinsTest.state, containsPair('TestAbstractState.dynamicState', 2)); + + mixinsTest = new TestAbstractStateSubclass()..untypedState = false; + expect(mixinsTest.state, containsPair('TestAbstractState.untypedState', false)); + }); + + test('custom state keys', () { + var mixinsTest = new TestAbstractStateSubclass()..customKeyState = 'test'; + expect(mixinsTest.state, containsPair('TestAbstractState.custom key!', 'test')); + }); + + test('custom state key namespaces', () { + var mixinsTest = new TestAbstractStateSubclass()..customNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom state keys and namespaces', () { + var mixinsTest = new TestAbstractStateSubclass()..customKeyAndNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + group('generates state getters/setters, when there is a custom key namespace, with', () { + test('the custom namespace and the state name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..stringState = 'test'; + expect(mixinsTest.state, containsPair('custom mixin namespace**stringState', 'test')); + + mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..dynamicState = 2; + expect(mixinsTest.state, containsPair('custom mixin namespace**dynamicState', 2)); + + mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..untypedState = false; + expect(mixinsTest.state, containsPair('custom mixin namespace**untypedState', false)); + }); + + test('custom state keys', () { + var mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..customKeyState = 'test'; + expect(mixinsTest.state, containsPair('custom mixin namespace**custom key!', 'test')); + }); + + test('custom state key namespaces', () { + var mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..customNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom state keys and namespaces', () { + var mixinsTest = new TestCustomNamespaceAbstractStateSubclass()..customKeyAndNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + }); + }); +} + + +@AbstractProps() +abstract class _$TestAbstractProps extends UiProps { + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +class TestAbstractPropsSubclass extends TestAbstractProps { + @override final Map props = {}; + @override bool get $isClassGenerated => true; + + @override String get propKeyNamespace => null; + @override ReactComponentFactoryProxy get componentFactory => null; +} + + +@AbstractProps(keyNamespace: 'custom mixin namespace**') +abstract class _$TestCustomNamespaceAbstractProps extends UiProps { + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +class TestCustomNamespaceAbstractPropsSubclass extends TestCustomNamespaceAbstractProps { + @override final Map props = {}; + @override bool get $isClassGenerated => true; + + @override String get propKeyNamespace => null; + @override ReactComponentFactoryProxy get componentFactory => null; +} + + +@AbstractState() +abstract class _$TestAbstractState extends UiState { + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +class TestAbstractStateSubclass extends TestAbstractState { + @override final Map state = {}; + @override bool get $isClassGenerated => true; +} + + +@AbstractState(keyNamespace: 'custom mixin namespace**') +abstract class _$TestCustomNamespaceAbstractState extends UiState { + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +class TestCustomNamespaceAbstractStateSubclass extends TestCustomNamespaceAbstractState { + @override final Map state = {}; + @override bool get $isClassGenerated => true; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.over_react.g.dart new file mode 100644 index 000000000..edfd22f40 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.over_react.g.dart @@ -0,0 +1,545 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'abstract_accessor_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +abstract class _$TestAbstractPropsAccessorsMixin + implements _$TestAbstractProps { + @override + Map get props; + + /// + @override + String get stringProp => + props[_$key__stringProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$TestAbstractProps] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$TestAbstractProps] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => + props[_$key__untypedProp___$TestAbstractProps] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$TestAbstractProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$TestAbstractProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[_$key__customKeyAndNamespaceProp___$TestAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => + props[_$key__customKeyAndNamespaceProp___$TestAbstractProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__stringProp___$TestAbstractProps = + const PropDescriptor(_$key__stringProp___$TestAbstractProps); + static const PropDescriptor _$prop__dynamicProp___$TestAbstractProps = + const PropDescriptor(_$key__dynamicProp___$TestAbstractProps); + static const PropDescriptor _$prop__untypedProp___$TestAbstractProps = + const PropDescriptor(_$key__untypedProp___$TestAbstractProps); + static const PropDescriptor _$prop__customKeyProp___$TestAbstractProps = + const PropDescriptor(_$key__customKeyProp___$TestAbstractProps); + static const PropDescriptor _$prop__customNamespaceProp___$TestAbstractProps = + const PropDescriptor(_$key__customNamespaceProp___$TestAbstractProps); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$TestAbstractProps = + const PropDescriptor( + _$key__customKeyAndNamespaceProp___$TestAbstractProps); + static const String _$key__stringProp___$TestAbstractProps = + 'TestAbstractProps.stringProp'; + static const String _$key__dynamicProp___$TestAbstractProps = + 'TestAbstractProps.dynamicProp'; + static const String _$key__untypedProp___$TestAbstractProps = + 'TestAbstractProps.untypedProp'; + static const String _$key__customKeyProp___$TestAbstractProps = + 'TestAbstractProps.custom key!'; + static const String _$key__customNamespaceProp___$TestAbstractProps = + 'custom namespace~~customNamespaceProp'; + static const String _$key__customKeyAndNamespaceProp___$TestAbstractProps = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$TestAbstractProps, + _$prop__dynamicProp___$TestAbstractProps, + _$prop__untypedProp___$TestAbstractProps, + _$prop__customKeyProp___$TestAbstractProps, + _$prop__customNamespaceProp___$TestAbstractProps, + _$prop__customKeyAndNamespaceProp___$TestAbstractProps + ]; + static const List $propKeys = const [ + _$key__stringProp___$TestAbstractProps, + _$key__dynamicProp___$TestAbstractProps, + _$key__untypedProp___$TestAbstractProps, + _$key__customKeyProp___$TestAbstractProps, + _$key__customNamespaceProp___$TestAbstractProps, + _$key__customKeyAndNamespaceProp___$TestAbstractProps + ]; +} + +const PropsMeta _$metaForTestAbstractProps = const PropsMeta( + fields: _$TestAbstractPropsAccessorsMixin.$props, + keys: _$TestAbstractPropsAccessorsMixin.$propKeys, +); + +abstract class TestAbstractProps extends _$TestAbstractProps + with _$TestAbstractPropsAccessorsMixin { + static const PropsMeta meta = _$metaForTestAbstractProps; +} + +abstract class _$TestCustomNamespaceAbstractPropsAccessorsMixin + implements _$TestCustomNamespaceAbstractProps { + @override + Map get props; + + /// + @override + String get stringProp => + props[_$key__stringProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$TestCustomNamespaceAbstractProps] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$TestCustomNamespaceAbstractProps] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => + props[_$key__untypedProp___$TestCustomNamespaceAbstractProps] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$TestCustomNamespaceAbstractProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$TestCustomNamespaceAbstractProps] = + value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[ + _$key__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => props[ + _$key__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps] = + value; + /* GENERATED CONSTANTS */ + static const PropDescriptor + _$prop__stringProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__stringProp___$TestCustomNamespaceAbstractProps); + static const PropDescriptor + _$prop__dynamicProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__dynamicProp___$TestCustomNamespaceAbstractProps); + static const PropDescriptor + _$prop__untypedProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__untypedProp___$TestCustomNamespaceAbstractProps); + static const PropDescriptor + _$prop__customKeyProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__customKeyProp___$TestCustomNamespaceAbstractProps); + static const PropDescriptor + _$prop__customNamespaceProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__customNamespaceProp___$TestCustomNamespaceAbstractProps); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps = + const PropDescriptor( + _$key__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps); + static const String _$key__stringProp___$TestCustomNamespaceAbstractProps = + 'custom mixin namespace**stringProp'; + static const String _$key__dynamicProp___$TestCustomNamespaceAbstractProps = + 'custom mixin namespace**dynamicProp'; + static const String _$key__untypedProp___$TestCustomNamespaceAbstractProps = + 'custom mixin namespace**untypedProp'; + static const String _$key__customKeyProp___$TestCustomNamespaceAbstractProps = + 'custom mixin namespace**custom key!'; + static const String + _$key__customNamespaceProp___$TestCustomNamespaceAbstractProps = + 'custom namespace~~customNamespaceProp'; + static const String + _$key__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$TestCustomNamespaceAbstractProps, + _$prop__dynamicProp___$TestCustomNamespaceAbstractProps, + _$prop__untypedProp___$TestCustomNamespaceAbstractProps, + _$prop__customKeyProp___$TestCustomNamespaceAbstractProps, + _$prop__customNamespaceProp___$TestCustomNamespaceAbstractProps, + _$prop__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps + ]; + static const List $propKeys = const [ + _$key__stringProp___$TestCustomNamespaceAbstractProps, + _$key__dynamicProp___$TestCustomNamespaceAbstractProps, + _$key__untypedProp___$TestCustomNamespaceAbstractProps, + _$key__customKeyProp___$TestCustomNamespaceAbstractProps, + _$key__customNamespaceProp___$TestCustomNamespaceAbstractProps, + _$key__customKeyAndNamespaceProp___$TestCustomNamespaceAbstractProps + ]; +} + +const PropsMeta _$metaForTestCustomNamespaceAbstractProps = const PropsMeta( + fields: _$TestCustomNamespaceAbstractPropsAccessorsMixin.$props, + keys: _$TestCustomNamespaceAbstractPropsAccessorsMixin.$propKeys, +); + +abstract class TestCustomNamespaceAbstractProps + extends _$TestCustomNamespaceAbstractProps + with _$TestCustomNamespaceAbstractPropsAccessorsMixin { + static const PropsMeta meta = _$metaForTestCustomNamespaceAbstractProps; +} + +abstract class _$TestAbstractStateAccessorsMixin + implements _$TestAbstractState { + @override + Map get state; + + /// + @override + String get stringState => + state[_$key__stringState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$TestAbstractState] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$TestAbstractState] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$TestAbstractState] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$TestAbstractState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$TestAbstractState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[_$key__customKeyAndNamespaceState___$TestAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => + state[_$key__customKeyAndNamespaceState___$TestAbstractState] = value; + /* GENERATED CONSTANTS */ + static const StateDescriptor _$prop__stringState___$TestAbstractState = + const StateDescriptor(_$key__stringState___$TestAbstractState); + static const StateDescriptor _$prop__dynamicState___$TestAbstractState = + const StateDescriptor(_$key__dynamicState___$TestAbstractState); + static const StateDescriptor _$prop__untypedState___$TestAbstractState = + const StateDescriptor(_$key__untypedState___$TestAbstractState); + static const StateDescriptor _$prop__customKeyState___$TestAbstractState = + const StateDescriptor(_$key__customKeyState___$TestAbstractState); + static const StateDescriptor + _$prop__customNamespaceState___$TestAbstractState = + const StateDescriptor(_$key__customNamespaceState___$TestAbstractState); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$TestAbstractState = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$TestAbstractState); + static const String _$key__stringState___$TestAbstractState = + 'TestAbstractState.stringState'; + static const String _$key__dynamicState___$TestAbstractState = + 'TestAbstractState.dynamicState'; + static const String _$key__untypedState___$TestAbstractState = + 'TestAbstractState.untypedState'; + static const String _$key__customKeyState___$TestAbstractState = + 'TestAbstractState.custom key!'; + static const String _$key__customNamespaceState___$TestAbstractState = + 'custom namespace~~customNamespaceState'; + static const String _$key__customKeyAndNamespaceState___$TestAbstractState = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$TestAbstractState, + _$prop__dynamicState___$TestAbstractState, + _$prop__untypedState___$TestAbstractState, + _$prop__customKeyState___$TestAbstractState, + _$prop__customNamespaceState___$TestAbstractState, + _$prop__customKeyAndNamespaceState___$TestAbstractState + ]; + static const List $stateKeys = const [ + _$key__stringState___$TestAbstractState, + _$key__dynamicState___$TestAbstractState, + _$key__untypedState___$TestAbstractState, + _$key__customKeyState___$TestAbstractState, + _$key__customNamespaceState___$TestAbstractState, + _$key__customKeyAndNamespaceState___$TestAbstractState + ]; +} + +const StateMeta _$metaForTestAbstractState = const StateMeta( + fields: _$TestAbstractStateAccessorsMixin.$state, + keys: _$TestAbstractStateAccessorsMixin.$stateKeys, +); + +abstract class TestAbstractState extends _$TestAbstractState + with _$TestAbstractStateAccessorsMixin { + static const StateMeta meta = _$metaForTestAbstractState; +} + +abstract class _$TestCustomNamespaceAbstractStateAccessorsMixin + implements _$TestCustomNamespaceAbstractState { + @override + Map get state; + + /// + @override + String get stringState => + state[_$key__stringState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$TestCustomNamespaceAbstractState] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$TestCustomNamespaceAbstractState] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$TestCustomNamespaceAbstractState] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$TestCustomNamespaceAbstractState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$TestCustomNamespaceAbstractState] = + value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[ + _$key__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => state[ + _$key__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState] = + value; + /* GENERATED CONSTANTS */ + static const StateDescriptor + _$prop__stringState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__stringState___$TestCustomNamespaceAbstractState); + static const StateDescriptor + _$prop__dynamicState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__dynamicState___$TestCustomNamespaceAbstractState); + static const StateDescriptor + _$prop__untypedState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__untypedState___$TestCustomNamespaceAbstractState); + static const StateDescriptor + _$prop__customKeyState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__customKeyState___$TestCustomNamespaceAbstractState); + static const StateDescriptor + _$prop__customNamespaceState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__customNamespaceState___$TestCustomNamespaceAbstractState); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState); + static const String _$key__stringState___$TestCustomNamespaceAbstractState = + 'custom mixin namespace**stringState'; + static const String _$key__dynamicState___$TestCustomNamespaceAbstractState = + 'custom mixin namespace**dynamicState'; + static const String _$key__untypedState___$TestCustomNamespaceAbstractState = + 'custom mixin namespace**untypedState'; + static const String + _$key__customKeyState___$TestCustomNamespaceAbstractState = + 'custom mixin namespace**custom key!'; + static const String + _$key__customNamespaceState___$TestCustomNamespaceAbstractState = + 'custom namespace~~customNamespaceState'; + static const String + _$key__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$TestCustomNamespaceAbstractState, + _$prop__dynamicState___$TestCustomNamespaceAbstractState, + _$prop__untypedState___$TestCustomNamespaceAbstractState, + _$prop__customKeyState___$TestCustomNamespaceAbstractState, + _$prop__customNamespaceState___$TestCustomNamespaceAbstractState, + _$prop__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState + ]; + static const List $stateKeys = const [ + _$key__stringState___$TestCustomNamespaceAbstractState, + _$key__dynamicState___$TestCustomNamespaceAbstractState, + _$key__untypedState___$TestCustomNamespaceAbstractState, + _$key__customKeyState___$TestCustomNamespaceAbstractState, + _$key__customNamespaceState___$TestCustomNamespaceAbstractState, + _$key__customKeyAndNamespaceState___$TestCustomNamespaceAbstractState + ]; +} + +const StateMeta _$metaForTestCustomNamespaceAbstractState = const StateMeta( + fields: _$TestCustomNamespaceAbstractStateAccessorsMixin.$state, + keys: _$TestCustomNamespaceAbstractStateAccessorsMixin.$stateKeys, +); + +abstract class TestCustomNamespaceAbstractState + extends _$TestCustomNamespaceAbstractState + with _$TestCustomNamespaceAbstractStateAccessorsMixin { + static const StateMeta meta = _$metaForTestCustomNamespaceAbstractState; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.dart new file mode 100644 index 000000000..e4e794220 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.dart @@ -0,0 +1,241 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +part 'accessor_mixin_integration_test.over_react.g.dart'; + +main() { + group('(Component2) accessor for props/state mixin integration:', () { + group('@PropsMixin()', () { + group('generates prop getters/setters with', () { + test('the props class name as a namespace and the prop name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestPropsMixinSubclass()..stringProp = 'test'; + expect(mixinsTest.props, containsPair('TestPropsMixin.stringProp', 'test')); + + mixinsTest = new TestPropsMixinSubclass()..dynamicProp = 2; + expect(mixinsTest.props, containsPair('TestPropsMixin.dynamicProp', 2)); + + mixinsTest = new TestPropsMixinSubclass()..untypedProp = false; + expect(mixinsTest.props, containsPair('TestPropsMixin.untypedProp', false)); + }); + + test('custom prop keys', () { + var mixinsTest = new TestPropsMixinSubclass()..customKeyProp = 'test'; + expect(mixinsTest.props, containsPair('TestPropsMixin.custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + var mixinsTest = new TestPropsMixinSubclass()..customNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + var mixinsTest = new TestPropsMixinSubclass()..customKeyAndNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + group('generates prop getters/setters, when there is a custom key namespace, with', () { + test('the custom namespace and the prop name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestCustomNamespacePropsMixinSubclass()..stringProp = 'test'; + expect(mixinsTest.props, containsPair('custom mixin namespace**stringProp', 'test')); + + mixinsTest = new TestCustomNamespacePropsMixinSubclass()..dynamicProp = 2; + expect(mixinsTest.props, containsPair('custom mixin namespace**dynamicProp', 2)); + + mixinsTest = new TestCustomNamespacePropsMixinSubclass()..untypedProp = false; + expect(mixinsTest.props, containsPair('custom mixin namespace**untypedProp', false)); + }); + + test('custom prop keys', () { + var mixinsTest = new TestCustomNamespacePropsMixinSubclass()..customKeyProp = 'test'; + expect(mixinsTest.props, containsPair('custom mixin namespace**custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + var mixinsTest = new TestCustomNamespacePropsMixinSubclass()..customNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + var mixinsTest = new TestCustomNamespacePropsMixinSubclass()..customKeyAndNamespaceProp = 'test'; + expect(mixinsTest.props, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + }); + + group('@StateMixin()', () { + group('generates state getters/setters with', () { + test('the state class name as a namespace and the state name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestStateMixinSubclass()..stringState = 'test'; + expect(mixinsTest.state, containsPair('TestStateMixin.stringState', 'test')); + + mixinsTest = new TestStateMixinSubclass()..dynamicState = 2; + expect(mixinsTest.state, containsPair('TestStateMixin.dynamicState', 2)); + + mixinsTest = new TestStateMixinSubclass()..untypedState = false; + expect(mixinsTest.state, containsPair('TestStateMixin.untypedState', false)); + }); + + test('custom state keys', () { + var mixinsTest = new TestStateMixinSubclass()..customKeyState = 'test'; + expect(mixinsTest.state, containsPair('TestStateMixin.custom key!', 'test')); + }); + + test('custom state key namespaces', () { + var mixinsTest = new TestStateMixinSubclass()..customNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom state keys and namespaces', () { + var mixinsTest = new TestStateMixinSubclass()..customKeyAndNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + group('generates state getters/setters, when there is a custom key namespace, with', () { + test('the custom namespace and the state name as the key by default', () { + var mixinsTest; + + mixinsTest = new TestCustomNamespaceStateMixinSubclass()..stringState = 'test'; + expect(mixinsTest.state, containsPair('custom mixin namespace**stringState', 'test')); + + mixinsTest = new TestCustomNamespaceStateMixinSubclass()..dynamicState = 2; + expect(mixinsTest.state, containsPair('custom mixin namespace**dynamicState', 2)); + + mixinsTest = new TestCustomNamespaceStateMixinSubclass()..untypedState = false; + expect(mixinsTest.state, containsPair('custom mixin namespace**untypedState', false)); + }); + + test('custom state keys', () { + var mixinsTest = new TestCustomNamespaceStateMixinSubclass()..customKeyState = 'test'; + expect(mixinsTest.state, containsPair('custom mixin namespace**custom key!', 'test')); + }); + + test('custom state key namespaces', () { + var mixinsTest = new TestCustomNamespaceStateMixinSubclass()..customNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom state keys and namespaces', () { + var mixinsTest = new TestCustomNamespaceStateMixinSubclass()..customKeyAndNamespaceState = 'test'; + expect(mixinsTest.state, containsPair('custom namespace~~custom key!', 'test')); + }); + }); + }); + }); +} + + +@PropsMixin() +abstract class _$TestPropsMixin { + Map get props; + + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +class TestPropsMixinSubclass extends Object with + TestPropsMixin { + @override final Map props = {}; +} + + +@PropsMixin(keyNamespace: 'custom mixin namespace**') +abstract class _$TestCustomNamespacePropsMixin { + Map get props; + + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +class TestCustomNamespacePropsMixinSubclass extends Object with + TestCustomNamespacePropsMixin { + @override final Map props = {}; +} + + +@StateMixin() +abstract class _$TestStateMixin { + Map get state; + + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +class TestStateMixinSubclass extends Object with + TestStateMixin { + @override final Map state = {}; +} + + +@StateMixin(keyNamespace: 'custom mixin namespace**') +abstract class _$TestCustomNamespaceStateMixin { + Map get state; + + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +class TestCustomNamespaceStateMixinSubclass extends Object with + TestCustomNamespaceStateMixin { + @override final Map state = {}; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.over_react.g.dart new file mode 100644 index 000000000..165457b4b --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.over_react.g.dart @@ -0,0 +1,522 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'accessor_mixin_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +abstract class TestPropsMixin implements _$TestPropsMixin { + @override + Map get props; + + static const PropsMeta meta = _$metaForTestPropsMixin; + + /// + @override + String get stringProp => + props[_$key__stringProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$TestPropsMixin] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$TestPropsMixin] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => props[_$key__untypedProp___$TestPropsMixin] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$TestPropsMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$TestPropsMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[_$key__customKeyAndNamespaceProp___$TestPropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => + props[_$key__customKeyAndNamespaceProp___$TestPropsMixin] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__stringProp___$TestPropsMixin = + const PropDescriptor(_$key__stringProp___$TestPropsMixin); + static const PropDescriptor _$prop__dynamicProp___$TestPropsMixin = + const PropDescriptor(_$key__dynamicProp___$TestPropsMixin); + static const PropDescriptor _$prop__untypedProp___$TestPropsMixin = + const PropDescriptor(_$key__untypedProp___$TestPropsMixin); + static const PropDescriptor _$prop__customKeyProp___$TestPropsMixin = + const PropDescriptor(_$key__customKeyProp___$TestPropsMixin); + static const PropDescriptor _$prop__customNamespaceProp___$TestPropsMixin = + const PropDescriptor(_$key__customNamespaceProp___$TestPropsMixin); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$TestPropsMixin = + const PropDescriptor(_$key__customKeyAndNamespaceProp___$TestPropsMixin); + static const String _$key__stringProp___$TestPropsMixin = + 'TestPropsMixin.stringProp'; + static const String _$key__dynamicProp___$TestPropsMixin = + 'TestPropsMixin.dynamicProp'; + static const String _$key__untypedProp___$TestPropsMixin = + 'TestPropsMixin.untypedProp'; + static const String _$key__customKeyProp___$TestPropsMixin = + 'TestPropsMixin.custom key!'; + static const String _$key__customNamespaceProp___$TestPropsMixin = + 'custom namespace~~customNamespaceProp'; + static const String _$key__customKeyAndNamespaceProp___$TestPropsMixin = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$TestPropsMixin, + _$prop__dynamicProp___$TestPropsMixin, + _$prop__untypedProp___$TestPropsMixin, + _$prop__customKeyProp___$TestPropsMixin, + _$prop__customNamespaceProp___$TestPropsMixin, + _$prop__customKeyAndNamespaceProp___$TestPropsMixin + ]; + static const List $propKeys = const [ + _$key__stringProp___$TestPropsMixin, + _$key__dynamicProp___$TestPropsMixin, + _$key__untypedProp___$TestPropsMixin, + _$key__customKeyProp___$TestPropsMixin, + _$key__customNamespaceProp___$TestPropsMixin, + _$key__customKeyAndNamespaceProp___$TestPropsMixin + ]; +} + +const PropsMeta _$metaForTestPropsMixin = const PropsMeta( + fields: TestPropsMixin.$props, + keys: TestPropsMixin.$propKeys, +); + +abstract class TestCustomNamespacePropsMixin + implements _$TestCustomNamespacePropsMixin { + @override + Map get props; + + static const PropsMeta meta = _$metaForTestCustomNamespacePropsMixin; + + /// + @override + String get stringProp => + props[_$key__stringProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$TestCustomNamespacePropsMixin] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$TestCustomNamespacePropsMixin] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => + props[_$key__untypedProp___$TestCustomNamespacePropsMixin] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$TestCustomNamespacePropsMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$TestCustomNamespacePropsMixin] = + value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[ + _$key__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => + props[_$key__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin] = + value; + /* GENERATED CONSTANTS */ + static const PropDescriptor + _$prop__stringProp___$TestCustomNamespacePropsMixin = + const PropDescriptor(_$key__stringProp___$TestCustomNamespacePropsMixin); + static const PropDescriptor + _$prop__dynamicProp___$TestCustomNamespacePropsMixin = + const PropDescriptor(_$key__dynamicProp___$TestCustomNamespacePropsMixin); + static const PropDescriptor + _$prop__untypedProp___$TestCustomNamespacePropsMixin = + const PropDescriptor(_$key__untypedProp___$TestCustomNamespacePropsMixin); + static const PropDescriptor + _$prop__customKeyProp___$TestCustomNamespacePropsMixin = + const PropDescriptor( + _$key__customKeyProp___$TestCustomNamespacePropsMixin); + static const PropDescriptor + _$prop__customNamespaceProp___$TestCustomNamespacePropsMixin = + const PropDescriptor( + _$key__customNamespaceProp___$TestCustomNamespacePropsMixin); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin = + const PropDescriptor( + _$key__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin); + static const String _$key__stringProp___$TestCustomNamespacePropsMixin = + 'custom mixin namespace**stringProp'; + static const String _$key__dynamicProp___$TestCustomNamespacePropsMixin = + 'custom mixin namespace**dynamicProp'; + static const String _$key__untypedProp___$TestCustomNamespacePropsMixin = + 'custom mixin namespace**untypedProp'; + static const String _$key__customKeyProp___$TestCustomNamespacePropsMixin = + 'custom mixin namespace**custom key!'; + static const String + _$key__customNamespaceProp___$TestCustomNamespacePropsMixin = + 'custom namespace~~customNamespaceProp'; + static const String + _$key__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$TestCustomNamespacePropsMixin, + _$prop__dynamicProp___$TestCustomNamespacePropsMixin, + _$prop__untypedProp___$TestCustomNamespacePropsMixin, + _$prop__customKeyProp___$TestCustomNamespacePropsMixin, + _$prop__customNamespaceProp___$TestCustomNamespacePropsMixin, + _$prop__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin + ]; + static const List $propKeys = const [ + _$key__stringProp___$TestCustomNamespacePropsMixin, + _$key__dynamicProp___$TestCustomNamespacePropsMixin, + _$key__untypedProp___$TestCustomNamespacePropsMixin, + _$key__customKeyProp___$TestCustomNamespacePropsMixin, + _$key__customNamespaceProp___$TestCustomNamespacePropsMixin, + _$key__customKeyAndNamespaceProp___$TestCustomNamespacePropsMixin + ]; +} + +const PropsMeta _$metaForTestCustomNamespacePropsMixin = const PropsMeta( + fields: TestCustomNamespacePropsMixin.$props, + keys: TestCustomNamespacePropsMixin.$propKeys, +); + +abstract class TestStateMixin implements _$TestStateMixin { + @override + Map get state; + + static const StateMeta meta = _$metaForTestStateMixin; + + /// + @override + String get stringState => + state[_$key__stringState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$TestStateMixin] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$TestStateMixin] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$TestStateMixin] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$TestStateMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$TestStateMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[_$key__customKeyAndNamespaceState___$TestStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => + state[_$key__customKeyAndNamespaceState___$TestStateMixin] = value; + /* GENERATED CONSTANTS */ + static const StateDescriptor _$prop__stringState___$TestStateMixin = + const StateDescriptor(_$key__stringState___$TestStateMixin); + static const StateDescriptor _$prop__dynamicState___$TestStateMixin = + const StateDescriptor(_$key__dynamicState___$TestStateMixin); + static const StateDescriptor _$prop__untypedState___$TestStateMixin = + const StateDescriptor(_$key__untypedState___$TestStateMixin); + static const StateDescriptor _$prop__customKeyState___$TestStateMixin = + const StateDescriptor(_$key__customKeyState___$TestStateMixin); + static const StateDescriptor _$prop__customNamespaceState___$TestStateMixin = + const StateDescriptor(_$key__customNamespaceState___$TestStateMixin); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$TestStateMixin = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$TestStateMixin); + static const String _$key__stringState___$TestStateMixin = + 'TestStateMixin.stringState'; + static const String _$key__dynamicState___$TestStateMixin = + 'TestStateMixin.dynamicState'; + static const String _$key__untypedState___$TestStateMixin = + 'TestStateMixin.untypedState'; + static const String _$key__customKeyState___$TestStateMixin = + 'TestStateMixin.custom key!'; + static const String _$key__customNamespaceState___$TestStateMixin = + 'custom namespace~~customNamespaceState'; + static const String _$key__customKeyAndNamespaceState___$TestStateMixin = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$TestStateMixin, + _$prop__dynamicState___$TestStateMixin, + _$prop__untypedState___$TestStateMixin, + _$prop__customKeyState___$TestStateMixin, + _$prop__customNamespaceState___$TestStateMixin, + _$prop__customKeyAndNamespaceState___$TestStateMixin + ]; + static const List $stateKeys = const [ + _$key__stringState___$TestStateMixin, + _$key__dynamicState___$TestStateMixin, + _$key__untypedState___$TestStateMixin, + _$key__customKeyState___$TestStateMixin, + _$key__customNamespaceState___$TestStateMixin, + _$key__customKeyAndNamespaceState___$TestStateMixin + ]; +} + +const StateMeta _$metaForTestStateMixin = const StateMeta( + fields: TestStateMixin.$state, + keys: TestStateMixin.$stateKeys, +); + +abstract class TestCustomNamespaceStateMixin + implements _$TestCustomNamespaceStateMixin { + @override + Map get state; + + static const StateMeta meta = _$metaForTestCustomNamespaceStateMixin; + + /// + @override + String get stringState => + state[_$key__stringState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$TestCustomNamespaceStateMixin] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$TestCustomNamespaceStateMixin] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$TestCustomNamespaceStateMixin] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$TestCustomNamespaceStateMixin] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$TestCustomNamespaceStateMixin] = + value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[ + _$key__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => state[ + _$key__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin] = + value; + /* GENERATED CONSTANTS */ + static const StateDescriptor + _$prop__stringState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__stringState___$TestCustomNamespaceStateMixin); + static const StateDescriptor + _$prop__dynamicState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__dynamicState___$TestCustomNamespaceStateMixin); + static const StateDescriptor + _$prop__untypedState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__untypedState___$TestCustomNamespaceStateMixin); + static const StateDescriptor + _$prop__customKeyState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__customKeyState___$TestCustomNamespaceStateMixin); + static const StateDescriptor + _$prop__customNamespaceState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__customNamespaceState___$TestCustomNamespaceStateMixin); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin); + static const String _$key__stringState___$TestCustomNamespaceStateMixin = + 'custom mixin namespace**stringState'; + static const String _$key__dynamicState___$TestCustomNamespaceStateMixin = + 'custom mixin namespace**dynamicState'; + static const String _$key__untypedState___$TestCustomNamespaceStateMixin = + 'custom mixin namespace**untypedState'; + static const String _$key__customKeyState___$TestCustomNamespaceStateMixin = + 'custom mixin namespace**custom key!'; + static const String + _$key__customNamespaceState___$TestCustomNamespaceStateMixin = + 'custom namespace~~customNamespaceState'; + static const String + _$key__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$TestCustomNamespaceStateMixin, + _$prop__dynamicState___$TestCustomNamespaceStateMixin, + _$prop__untypedState___$TestCustomNamespaceStateMixin, + _$prop__customKeyState___$TestCustomNamespaceStateMixin, + _$prop__customNamespaceState___$TestCustomNamespaceStateMixin, + _$prop__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin + ]; + static const List $stateKeys = const [ + _$key__stringState___$TestCustomNamespaceStateMixin, + _$key__dynamicState___$TestCustomNamespaceStateMixin, + _$key__untypedState___$TestCustomNamespaceStateMixin, + _$key__customKeyState___$TestCustomNamespaceStateMixin, + _$key__customNamespaceState___$TestCustomNamespaceStateMixin, + _$key__customKeyAndNamespaceState___$TestCustomNamespaceStateMixin + ]; +} + +const StateMeta _$metaForTestCustomNamespaceStateMixin = const StateMeta( + fields: TestCustomNamespaceStateMixin.$state, + keys: TestCustomNamespaceStateMixin.$stateKeys, +); diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.dart new file mode 100644 index 000000000..7ef38671c --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.dart @@ -0,0 +1,159 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import './constant_required_accessor_integration_test.dart' as r; +import '../../../../test_util/test_util.dart'; + +part 'component_integration_test.over_react.g.dart'; + +main() { + group('(Component2) component integration:', () { + test('renders a component from end to end, successfully reading props via typed getters', () { + var instance = render((ComponentTest() + ..stringProp = '1' + ..dynamicProp = '2' + ..untypedProp = '3' + ..customKeyProp = '4' + ..customNamespaceProp = '5' + ..customKeyAndNamespaceProp = '6' + )()); + expect(instance, isNotNull); + + var node = findDomNode(instance); + expect(node.text, 'rendered content'); + expect(node.dataset, containsPair('prop-string-prop', '1')); + expect(node.dataset, containsPair('prop-dynamic-prop', '2')); + expect(node.dataset, containsPair('prop-untyped-prop', '3')); + expect(node.dataset, containsPair('prop-custom-key-prop', '4')); + expect(node.dataset, containsPair('prop-custom-namespace-prop', '5')); + expect(node.dataset, containsPair('prop-custom-key-and-namespace-prop', '6')); + }); + + group('initializes the factory variable with a function', () { + test('that returns a new props class implementation instance', () { + var instance = ComponentTest(); + expect(instance, const TypeMatcher()); + expect(instance, const TypeMatcher()); + }); + + test('that returns a new props class implementation instance backed by an existing map', () { + Map existingMap = {'ComponentTestProps.stringProp': 'test'}; + var props = ComponentTest(existingMap); + + expect(props.stringProp, equals('test')); + + props.stringProp = 'modified'; + expect(props.stringProp, equals('modified')); + expect(existingMap['ComponentTestProps.stringProp'], equals('modified')); + }); + }); + + group('generates prop getters/setters with', () { + test('the props class name as a namespace and the prop name as the key by default', () { + expect(ComponentTest()..stringProp = 'test', + containsPair('ComponentTestProps.stringProp', 'test')); + + expect(ComponentTest()..dynamicProp = 2, + containsPair('ComponentTestProps.dynamicProp', 2)); + + expect(ComponentTest()..untypedProp = false, + containsPair('ComponentTestProps.untypedProp', false)); + + }); + + test('custom prop keys', () { + expect(ComponentTest()..customKeyProp = 'test', + containsPair('ComponentTestProps.custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + expect(ComponentTest()..customNamespaceProp = 'test', + containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + expect(ComponentTest()..customKeyAndNamespaceProp = 'test', + containsPair('custom namespace~~custom key!', 'test')); + }); + + test('default props', () { + expect(ComponentTest().componentDefaultProps, equals({'id':'testId'})); + }); + + test('empty map when no default props set', () { + expect(r.ComponentTest().componentDefaultProps, equals({})); + }); + + test('empty map when componentFactory is not ReactDartComponentFactoryProxy', () { + expect(Dom.div().componentDefaultProps, equals({})); + }); + }); + + test('omits props declared in the @Props() class when forwarding by default', () { + var shallowInstance = renderShallow((ComponentTest() + ..addProp('extraneous', true) + ..stringProp = 'test' + ..dynamicProp = 'test' + ..untypedProp = 'test' + ..customKeyProp = 'test' + ..customNamespaceProp = 'test' + ..customKeyAndNamespaceProp = 'test' + )()); + + var shallowProps = getProps(shallowInstance); + Iterable shallowPropKeys = shallowProps.keys.map((key) => key as String); // ignore: avoid_as + + expect(shallowPropKeys.where((String key) => !key.startsWith('data-prop-')), unorderedEquals(['id', 'extraneous', 'children'])); + }); + }); +} + + +@Factory() +UiFactory ComponentTest = _$ComponentTest; + +@Props() +class _$ComponentTestProps extends UiProps { + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +@Component() +class ComponentTestComponent extends UiComponent2 { + @override + Map getDefaultProps() => newProps()..id = 'testId'; + + @override + render() => (Dom.div() + ..addProps(copyUnconsumedProps()) + ..addProp('data-prop-string-prop', props.stringProp) + ..addProp('data-prop-dynamic-prop', props.dynamicProp) + ..addProp('data-prop-untyped-prop', props.untypedProp) + ..addProp('data-prop-custom-key-prop', props.customKeyProp) + ..addProp('data-prop-custom-namespace-prop', props.customNamespaceProp) + ..addProp('data-prop-custom-key-and-namespace-prop', props.customKeyAndNamespaceProp) + )('rendered content'); +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.over_react.g.dart new file mode 100644 index 000000000..efe8a003d --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/component_integration_test.over_react.g.dart @@ -0,0 +1,249 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'component_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ComponentTestComponentFactory = registerComponent( + () => new _$ComponentTestComponent(), + builderFactory: ComponentTest, + componentClass: ComponentTestComponent, + isWrapper: false, + parentType: null, + displayName: 'ComponentTest'); + +abstract class _$ComponentTestPropsAccessorsMixin + implements _$ComponentTestProps { + @override + Map get props; + + /// + @override + String get stringProp => + props[_$key__stringProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$ComponentTestProps] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$ComponentTestProps] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => + props[_$key__untypedProp___$ComponentTestProps] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$ComponentTestProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$ComponentTestProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[_$key__customKeyAndNamespaceProp___$ComponentTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => + props[_$key__customKeyAndNamespaceProp___$ComponentTestProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__stringProp___$ComponentTestProps = + const PropDescriptor(_$key__stringProp___$ComponentTestProps); + static const PropDescriptor _$prop__dynamicProp___$ComponentTestProps = + const PropDescriptor(_$key__dynamicProp___$ComponentTestProps); + static const PropDescriptor _$prop__untypedProp___$ComponentTestProps = + const PropDescriptor(_$key__untypedProp___$ComponentTestProps); + static const PropDescriptor _$prop__customKeyProp___$ComponentTestProps = + const PropDescriptor(_$key__customKeyProp___$ComponentTestProps); + static const PropDescriptor + _$prop__customNamespaceProp___$ComponentTestProps = + const PropDescriptor(_$key__customNamespaceProp___$ComponentTestProps); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$ComponentTestProps = + const PropDescriptor( + _$key__customKeyAndNamespaceProp___$ComponentTestProps); + static const String _$key__stringProp___$ComponentTestProps = + 'ComponentTestProps.stringProp'; + static const String _$key__dynamicProp___$ComponentTestProps = + 'ComponentTestProps.dynamicProp'; + static const String _$key__untypedProp___$ComponentTestProps = + 'ComponentTestProps.untypedProp'; + static const String _$key__customKeyProp___$ComponentTestProps = + 'ComponentTestProps.custom key!'; + static const String _$key__customNamespaceProp___$ComponentTestProps = + 'custom namespace~~customNamespaceProp'; + static const String _$key__customKeyAndNamespaceProp___$ComponentTestProps = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$ComponentTestProps, + _$prop__dynamicProp___$ComponentTestProps, + _$prop__untypedProp___$ComponentTestProps, + _$prop__customKeyProp___$ComponentTestProps, + _$prop__customNamespaceProp___$ComponentTestProps, + _$prop__customKeyAndNamespaceProp___$ComponentTestProps + ]; + static const List $propKeys = const [ + _$key__stringProp___$ComponentTestProps, + _$key__dynamicProp___$ComponentTestProps, + _$key__untypedProp___$ComponentTestProps, + _$key__customKeyProp___$ComponentTestProps, + _$key__customNamespaceProp___$ComponentTestProps, + _$key__customKeyAndNamespaceProp___$ComponentTestProps + ]; +} + +const PropsMeta _$metaForComponentTestProps = const PropsMeta( + fields: _$ComponentTestPropsAccessorsMixin.$props, + keys: _$ComponentTestPropsAccessorsMixin.$propKeys, +); + +class ComponentTestProps extends _$ComponentTestProps + with _$ComponentTestPropsAccessorsMixin { + static const PropsMeta meta = _$metaForComponentTestProps; +} + +_$$ComponentTestProps _$ComponentTest([Map backingProps]) => + backingProps == null + ? new _$$ComponentTestProps$JsMap(new JsBackedMap()) + : new _$$ComponentTestProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ComponentTestProps extends _$ComponentTestProps + with _$ComponentTestPropsAccessorsMixin + implements ComponentTestProps { + _$$ComponentTestProps._(); + + factory _$$ComponentTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ComponentTestProps$JsMap(backingMap); + } else { + return new _$$ComponentTestProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $ComponentTestComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ComponentTestProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ComponentTestProps$PlainMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ComponentTestProps$JsMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ComponentTestComponent extends ComponentTestComponent { + _$$ComponentTestProps$JsMap _cachedTypedProps; + + @override + _$$ComponentTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ComponentTestProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ComponentTestProps$JsMap(backingMap); + + @override + _$$ComponentTestProps typedPropsFactory(Map backingMap) => + new _$$ComponentTestProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ComponentTestProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForComponentTestProps + ]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.dart b/test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.dart similarity index 79% rename from test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.dart rename to test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.dart index 3156111ef..8c3db62d7 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.dart @@ -19,15 +19,14 @@ import 'package:test/test.dart'; import '../../../../test_util/test_util.dart'; -// ignore: uri_has_not_been_generated -part 'required_prop_integration_tests.over_react.g.dart'; +part 'constant_required_accessor_integration_test.over_react.g.dart'; -void requiredPropsIntegrationTest() { - group('(backwards compatible with Dart 1) properly identifies required props by', () { +void main() { + group('(Component2) properly identifies required props by', () { group('throwing when a prop is required and not set', () { test('on mount', () { expect(() => render(ComponentTest()..nullable = true), - throwsPropError_Required('ComponentTestProps.required', 'This Prop is Required for testing purposes.') + throwsPropError_Required('ComponentTestProps.required') ); }); @@ -39,7 +38,7 @@ void requiredPropsIntegrationTest() { )(), mountNode); expect(() => react_dom.render((ComponentTest()..nullable = true)(), mountNode), - throwsPropError_Required('ComponentTestProps.required', 'This Prop is Required for testing purposes.') + throwsPropError_Required('ComponentTestProps.required') ); }); }); @@ -64,7 +63,7 @@ void requiredPropsIntegrationTest() { ..required = null ..nullable = true )(), mountNode), - throwsPropError_Required('ComponentTestProps.required', 'This Prop is Required for testing purposes.') + throwsPropError_Required('ComponentTestProps.required') ); }); }); @@ -83,7 +82,7 @@ void requiredPropsIntegrationTest() { )(), mountNode); expect(() => react_dom.render((ComponentTest()..required = true)(), mountNode), - throwsPropError_Required('ComponentTestProps.nullable', 'This prop can be set to null!') + throwsPropError_Required('ComponentTestProps.nullable') ); }); }); @@ -131,33 +130,25 @@ void requiredPropsIntegrationTest() { )(), mountNode), returnsNormally); }); }); - }); + // FIXME 3.0.0-wip unskip once implemented in CPLAT-4887 + }, skip: 'Component2 prop validation will be added in CPLAT-4887'); } @Factory() -// ignore: undefined_identifier UiFactory ComponentTest = _$ComponentTest; @Props() class _$ComponentTestProps extends UiProps { - // ignore: deprecated_member_use - @Required(message: 'This Prop is Required for testing purposes.') + @requiredProp var required; - // ignore: deprecated_member_use - @Required(isNullable: true, message: 'This prop can be set to null!') + @nullableRequiredProp var nullable; } @Component() -class ComponentTestComponent extends UiComponent { +class ComponentTestComponent extends UiComponent2 { @override render() => Dom.div()(); } -// AF-3369 This will be removed once the transition to Dart 2 is complete. -// ignore: mixin_of_non_class, undefined_class -class ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin { - // ignore: undefined_identifier, undefined_class, const_initialized_with_non_constant_value - static const PropsMeta meta = _$metaForComponentTestProps; -} diff --git a/test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.over_react.g.dart similarity index 68% rename from test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.over_react.g.dart rename to test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.over_react.g.dart index 9022a557d..af0784b30 100644 --- a/test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.over_react.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'required_prop_integration_tests.dart'; +part of 'constant_required_accessor_integration_test.dart'; // ************************************************************************** // OverReactGenerator @@ -24,35 +24,32 @@ abstract class _$ComponentTestPropsAccessorsMixin /// @override - @Required(message: 'This Prop is Required for testing purposes.') + @requiredProp get required => props[_$key__required___$ComponentTestProps] ?? null; // Add ` ?? null` to workaround DDC bug: ; /// @override - @Required(message: 'This Prop is Required for testing purposes.') + @requiredProp set required(value) => props[_$key__required___$ComponentTestProps] = value; /// @override - @Required(isNullable: true, message: 'This prop can be set to null!') + @nullableRequiredProp get nullable => props[_$key__nullable___$ComponentTestProps] ?? null; // Add ` ?? null` to workaround DDC bug: ; /// @override - @Required(isNullable: true, message: 'This prop can be set to null!') + @nullableRequiredProp set nullable(value) => props[_$key__nullable___$ComponentTestProps] = value; /* GENERATED CONSTANTS */ static const PropDescriptor _$prop__required___$ComponentTestProps = const PropDescriptor(_$key__required___$ComponentTestProps, - isRequired: true, - errorMessage: 'This Prop is Required for testing purposes.'); + isRequired: true); static const PropDescriptor _$prop__nullable___$ComponentTestProps = const PropDescriptor(_$key__nullable___$ComponentTestProps, - isRequired: true, - isNullable: true, - errorMessage: 'This prop can be set to null!'); + isRequired: true, isNullable: true); static const String _$key__required___$ComponentTestProps = 'ComponentTestProps.required'; static const String _$key__nullable___$ComponentTestProps = @@ -79,26 +76,26 @@ class ComponentTestProps extends _$ComponentTestProps } _$$ComponentTestProps _$ComponentTest([Map backingProps]) => - new _$$ComponentTestProps(backingProps); + backingProps == null + ? new _$$ComponentTestProps$JsMap(new JsBackedMap()) + : new _$$ComponentTestProps(backingProps); // Concrete props implementation. // // Implements constructor and backing map, and links up to generated component factory. -class _$$ComponentTestProps extends _$ComponentTestProps +abstract class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { - // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details - _$$ComponentTestProps(Map backingMap) : this._props = {} { - this._props = backingMap ?? {}; + _$$ComponentTestProps._(); + + factory _$$ComponentTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ComponentTestProps$JsMap(backingMap); + } else { + return new _$$ComponentTestProps$PlainMap(backingMap); + } } - /// The backing props map proxied by this class. - @override - Map get props => _props; - Map _props; - /// Let [UiProps] internals know that this class has been generated. @override bool get $isClassGenerated => true; @@ -113,11 +110,59 @@ class _$$ComponentTestProps extends _$ComponentTestProps String get propKeyNamespace => 'ComponentTestProps.'; } +// Concrete props implementation that can be backed by any [Map]. +class _$$ComponentTestProps$PlainMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ComponentTestProps$JsMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + // Concrete component implementation mixin. // // Implements typed props/state factories, defaults `consumedPropKeys` to the keys // generated for the associated props class. class _$ComponentTestComponent extends ComponentTestComponent { + _$$ComponentTestProps$JsMap _cachedTypedProps; + + @override + _$$ComponentTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ComponentTestProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ComponentTestProps$JsMap(backingMap); + @override _$$ComponentTestProps typedPropsFactory(Map backingMap) => new _$$ComponentTestProps(backingMap); diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.dart new file mode 100644 index 000000000..e18523b44 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.dart @@ -0,0 +1,121 @@ +// Copyright 2017 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import '../../../../test_util/test_util.dart'; + +part 'do_not_generate_accessor_integration_test.over_react.g.dart'; + +main() { + group('(Component2) acessors with doNotGenerate integration', () { + group('generates prop getters/setters properly', () { + test('for prop fields listed before the field annotated with doNotGenerate', () { + expect((DoNotGenerateAccessorTest()..generated1Prop = 'test').values.single, 'test'); + }); + + test('for prop fields listed after the field annotated with doNotGenerate', () { + expect((DoNotGenerateAccessorTest()..generated2Prop = 'test').values.single, 'test'); + }); + + test('for prop fields annotated with `doNotGenerate: false`', () { + expect((DoNotGenerateAccessorTest()..explicitlyGeneratedProp = 'test').values.single, 'test'); + }); + + test('except for the field annotated with doNotGenerate', () { + var instance = DoNotGenerateAccessorTest()..notGeneratedProp = 'test'; + expect(instance.notGeneratedProp, 'test', reason: 'non-generated field should work as expected'); + expect(instance, isEmpty, reason: 'accessor should not be backed by a key-value pair'); + }); + + test('omitting the field annotated with doNotGenerate from the list of props', () { + expect(DoNotGenerateAccessorTestProps.meta.keys, [ + contains('generated1Prop'), + contains('generated2Prop'), + contains('explicitlyGeneratedProp'), + ], reason: 'should only include generated props'); + + expect(DoNotGenerateAccessorTestProps.meta.props.map((prop) => prop.key).toList(), [ + contains('generated1Prop'), + contains('generated2Prop'), + contains('explicitlyGeneratedProp'), + ], reason: 'should only include generated props'); + }); + }); + + group('generates state getters/setters properly', () { + DoNotGenerateAccessorTestComponent component; + + setUp(() { + component = renderAndGetComponent(DoNotGenerateAccessorTest()());; + }); + + test('for state fields listed before the field annotated with doNotGenerate', () { + expect((component.newState()..generated1State = 'test').values.single, 'test'); + }); + + test('for state fields listed after the field annotated with doNotGenerate', () { + expect((component.newState()..generated2State = 'test').values.single, 'test'); + }); + + test('for state fields annotated with `doNotGenerate: false`', () { + expect((component.newState()..explicitlyGeneratedState = 'test').values.single, 'test'); + }); + + test('except for the field annotated with doNotGenerate', () { + var instance = component.newState()..notGeneratedState = 'test'; + expect(instance.notGeneratedState, 'test', reason: 'non-generated field should work as expected'); + expect(instance, isEmpty, reason: 'accessor should not be backed by a key-value pair'); + }); + }); + }); +} + + +@Factory() +UiFactory DoNotGenerateAccessorTest = _$DoNotGenerateAccessorTest; + +@Props() +class _$DoNotGenerateAccessorTestProps extends UiProps { + var generated1Prop; + + @Accessor(doNotGenerate: true) + var notGeneratedProp; + + var generated2Prop; + + @Accessor(doNotGenerate: false) + var explicitlyGeneratedProp; +} + +@State() +class _$DoNotGenerateAccessorTestState extends UiState { + var generated1State; + + @Accessor(doNotGenerate: true) + var notGeneratedState; + + var generated2State; + + @Accessor(doNotGenerate: false) + var explicitlyGeneratedState; +} + +@Component() +class DoNotGenerateAccessorTestComponent extends UiStatefulComponent2 { + @override + render() => (Dom.div() + ..addProps(copyUnconsumedProps()) + )('rendered content'); +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.over_react.g.dart new file mode 100644 index 000000000..f626c64b7 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.over_react.g.dart @@ -0,0 +1,365 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'do_not_generate_accessor_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $DoNotGenerateAccessorTestComponentFactory = registerComponent( + () => new _$DoNotGenerateAccessorTestComponent(), + builderFactory: DoNotGenerateAccessorTest, + componentClass: DoNotGenerateAccessorTestComponent, + isWrapper: false, + parentType: null, + displayName: 'DoNotGenerateAccessorTest'); + +abstract class _$DoNotGenerateAccessorTestPropsAccessorsMixin + implements _$DoNotGenerateAccessorTestProps { + @override + Map get props; + + /// + @override + get generated1Prop => + props[_$key__generated1Prop___$DoNotGenerateAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set generated1Prop(value) => + props[_$key__generated1Prop___$DoNotGenerateAccessorTestProps] = value; + + /// + @override + get generated2Prop => + props[_$key__generated2Prop___$DoNotGenerateAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set generated2Prop(value) => + props[_$key__generated2Prop___$DoNotGenerateAccessorTestProps] = value; + + /// + @override + @Accessor(doNotGenerate: false) + get explicitlyGeneratedProp => + props[_$key__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(doNotGenerate: false) + set explicitlyGeneratedProp(value) => + props[_$key__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps] = + value; + /* GENERATED CONSTANTS */ + static const PropDescriptor + _$prop__generated1Prop___$DoNotGenerateAccessorTestProps = + const PropDescriptor( + _$key__generated1Prop___$DoNotGenerateAccessorTestProps); + static const PropDescriptor + _$prop__generated2Prop___$DoNotGenerateAccessorTestProps = + const PropDescriptor( + _$key__generated2Prop___$DoNotGenerateAccessorTestProps); + static const PropDescriptor + _$prop__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps = + const PropDescriptor( + _$key__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps); + static const String _$key__generated1Prop___$DoNotGenerateAccessorTestProps = + 'DoNotGenerateAccessorTestProps.generated1Prop'; + static const String _$key__generated2Prop___$DoNotGenerateAccessorTestProps = + 'DoNotGenerateAccessorTestProps.generated2Prop'; + static const String + _$key__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps = + 'DoNotGenerateAccessorTestProps.explicitlyGeneratedProp'; + + static const List $props = const [ + _$prop__generated1Prop___$DoNotGenerateAccessorTestProps, + _$prop__generated2Prop___$DoNotGenerateAccessorTestProps, + _$prop__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps + ]; + static const List $propKeys = const [ + _$key__generated1Prop___$DoNotGenerateAccessorTestProps, + _$key__generated2Prop___$DoNotGenerateAccessorTestProps, + _$key__explicitlyGeneratedProp___$DoNotGenerateAccessorTestProps + ]; +} + +const PropsMeta _$metaForDoNotGenerateAccessorTestProps = const PropsMeta( + fields: _$DoNotGenerateAccessorTestPropsAccessorsMixin.$props, + keys: _$DoNotGenerateAccessorTestPropsAccessorsMixin.$propKeys, +); + +class DoNotGenerateAccessorTestProps extends _$DoNotGenerateAccessorTestProps + with _$DoNotGenerateAccessorTestPropsAccessorsMixin { + static const PropsMeta meta = _$metaForDoNotGenerateAccessorTestProps; +} + +_$$DoNotGenerateAccessorTestProps _$DoNotGenerateAccessorTest( + [Map backingProps]) => + backingProps == null + ? new _$$DoNotGenerateAccessorTestProps$JsMap(new JsBackedMap()) + : new _$$DoNotGenerateAccessorTestProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$DoNotGenerateAccessorTestProps + extends _$DoNotGenerateAccessorTestProps + with _$DoNotGenerateAccessorTestPropsAccessorsMixin + implements DoNotGenerateAccessorTestProps { + _$$DoNotGenerateAccessorTestProps._(); + + factory _$$DoNotGenerateAccessorTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$DoNotGenerateAccessorTestProps$JsMap(backingMap); + } else { + return new _$$DoNotGenerateAccessorTestProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $DoNotGenerateAccessorTestComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'DoNotGenerateAccessorTestProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$DoNotGenerateAccessorTestProps$PlainMap + extends _$$DoNotGenerateAccessorTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$DoNotGenerateAccessorTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$DoNotGenerateAccessorTestProps$JsMap + extends _$$DoNotGenerateAccessorTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$DoNotGenerateAccessorTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$DoNotGenerateAccessorTestStateAccessorsMixin + implements _$DoNotGenerateAccessorTestState { + @override + Map get state; + + /// + @override + get generated1State => + state[_$key__generated1State___$DoNotGenerateAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set generated1State(value) => + state[_$key__generated1State___$DoNotGenerateAccessorTestState] = value; + + /// + @override + get generated2State => + state[_$key__generated2State___$DoNotGenerateAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set generated2State(value) => + state[_$key__generated2State___$DoNotGenerateAccessorTestState] = value; + + /// + @override + @Accessor(doNotGenerate: false) + get explicitlyGeneratedState => + state[ + _$key__explicitlyGeneratedState___$DoNotGenerateAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(doNotGenerate: false) + set explicitlyGeneratedState(value) => + state[_$key__explicitlyGeneratedState___$DoNotGenerateAccessorTestState] = + value; + /* GENERATED CONSTANTS */ + static const StateDescriptor + _$prop__generated1State___$DoNotGenerateAccessorTestState = + const StateDescriptor( + _$key__generated1State___$DoNotGenerateAccessorTestState); + static const StateDescriptor + _$prop__generated2State___$DoNotGenerateAccessorTestState = + const StateDescriptor( + _$key__generated2State___$DoNotGenerateAccessorTestState); + static const StateDescriptor + _$prop__explicitlyGeneratedState___$DoNotGenerateAccessorTestState = + const StateDescriptor( + _$key__explicitlyGeneratedState___$DoNotGenerateAccessorTestState); + static const String _$key__generated1State___$DoNotGenerateAccessorTestState = + 'DoNotGenerateAccessorTestState.generated1State'; + static const String _$key__generated2State___$DoNotGenerateAccessorTestState = + 'DoNotGenerateAccessorTestState.generated2State'; + static const String + _$key__explicitlyGeneratedState___$DoNotGenerateAccessorTestState = + 'DoNotGenerateAccessorTestState.explicitlyGeneratedState'; + + static const List $state = const [ + _$prop__generated1State___$DoNotGenerateAccessorTestState, + _$prop__generated2State___$DoNotGenerateAccessorTestState, + _$prop__explicitlyGeneratedState___$DoNotGenerateAccessorTestState + ]; + static const List $stateKeys = const [ + _$key__generated1State___$DoNotGenerateAccessorTestState, + _$key__generated2State___$DoNotGenerateAccessorTestState, + _$key__explicitlyGeneratedState___$DoNotGenerateAccessorTestState + ]; +} + +const StateMeta _$metaForDoNotGenerateAccessorTestState = const StateMeta( + fields: _$DoNotGenerateAccessorTestStateAccessorsMixin.$state, + keys: _$DoNotGenerateAccessorTestStateAccessorsMixin.$stateKeys, +); + +class DoNotGenerateAccessorTestState extends _$DoNotGenerateAccessorTestState + with _$DoNotGenerateAccessorTestStateAccessorsMixin { + static const StateMeta meta = _$metaForDoNotGenerateAccessorTestState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$DoNotGenerateAccessorTestState + extends _$DoNotGenerateAccessorTestState + with _$DoNotGenerateAccessorTestStateAccessorsMixin + implements DoNotGenerateAccessorTestState { + _$$DoNotGenerateAccessorTestState._(); + + factory _$$DoNotGenerateAccessorTestState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$DoNotGenerateAccessorTestState$JsMap(backingMap); + } else { + return new _$$DoNotGenerateAccessorTestState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$DoNotGenerateAccessorTestState$PlainMap + extends _$$DoNotGenerateAccessorTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$DoNotGenerateAccessorTestState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$DoNotGenerateAccessorTestState$JsMap + extends _$$DoNotGenerateAccessorTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$DoNotGenerateAccessorTestState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$DoNotGenerateAccessorTestComponent + extends DoNotGenerateAccessorTestComponent { + _$$DoNotGenerateAccessorTestProps$JsMap _cachedTypedProps; + + @override + _$$DoNotGenerateAccessorTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$DoNotGenerateAccessorTestProps$JsMap typedPropsFactoryJs( + JsBackedMap backingMap) => + new _$$DoNotGenerateAccessorTestProps$JsMap(backingMap); + + @override + _$$DoNotGenerateAccessorTestProps typedPropsFactory(Map backingMap) => + new _$$DoNotGenerateAccessorTestProps(backingMap); + + _$$DoNotGenerateAccessorTestState$JsMap _cachedTypedState; + @override + _$$DoNotGenerateAccessorTestState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$DoNotGenerateAccessorTestState$JsMap typedStateFactoryJs( + JsBackedMap backingMap) => + new _$$DoNotGenerateAccessorTestState$JsMap(backingMap); + + @override + _$$DoNotGenerateAccessorTestState typedStateFactory(Map backingMap) => + new _$$DoNotGenerateAccessorTestState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$DoNotGenerateAccessorTestProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForDoNotGenerateAccessorTestProps + ]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.dart new file mode 100644 index 000000000..d5f817192 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.dart @@ -0,0 +1,147 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import '../../../../test_util/test_util.dart'; + +part 'namespaced_accessor_integration_test.over_react.g.dart'; + +main() { + group('(Component2) custom namespaced props/state integration:', () { + group('generates prop getters/setters, when there is a custom key namespace, with', () { + test('the custom namespace and the prop name as the key by default', () { + expect(NamespacedAccessorTest()..stringProp = 'test', + containsPair('custom props class namespace**stringProp', 'test')); + + expect(NamespacedAccessorTest()..dynamicProp = 2, + containsPair('custom props class namespace**dynamicProp', 2)); + + expect(NamespacedAccessorTest()..untypedProp = false, + containsPair('custom props class namespace**untypedProp', false)); + }); + + test('custom prop keys', () { + expect(NamespacedAccessorTest()..customKeyProp = 'test', + containsPair('custom props class namespace**custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + expect(NamespacedAccessorTest()..customNamespaceProp = 'test', + containsPair('custom namespace~~customNamespaceProp', 'test')); + }); + + test('custom prop keys and namespaces', () { + expect(NamespacedAccessorTest()..customKeyAndNamespaceProp = 'test', + containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + group('generates state getters/setters, when there is a custom key namespace, with', () { + NamespacedAccessorTestComponent component; + + setUp(() { + var renderedInstance = render(NamespacedAccessorTest()()); + component = getDartComponent(renderedInstance); + }); + + test('the custom namespace and the state name as the key by default', () { + expect(component.newState()..stringState = 'test', + containsPair('custom state class namespace**stringState', 'test')); + + expect(component.newState()..dynamicState = 2, + containsPair('custom state class namespace**dynamicState', 2)); + + expect(component.newState()..untypedState = false, + containsPair('custom state class namespace**untypedState', false)); + }); + + test('custom state keys', () { + expect(component.newState()..customKeyState = 'test', + containsPair('custom state class namespace**custom key!', 'test')); + }); + + test('custom state key namespaces', () { + expect(component.newState()..customNamespaceState = 'test', + containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom state keys and namespaces', () { + expect(component.newState()..customKeyAndNamespaceState = 'test', + containsPair('custom namespace~~custom key!', 'test')); + }); + }); + + test('omits props declared in the @Props() class when forwarding by default', () { + var shallowInstance = renderShallow((NamespacedAccessorTest() + ..addProp('extraneous', true) + ..stringProp = 'test' + ..dynamicProp = 'test' + ..untypedProp = 'test' + ..customKeyProp = 'test' + ..customNamespaceProp = 'test' + ..customKeyAndNamespaceProp = 'test' + )()); + + var shallowProps = getProps(shallowInstance); + + expect(shallowProps.keys, unorderedEquals(['extraneous', 'children'])); + }); + }); +} + + +@Factory() +UiFactory NamespacedAccessorTest = _$NamespacedAccessorTest; + +@Props(keyNamespace: 'custom props class namespace**') +class _$NamespacedAccessorTestProps extends UiProps { + String stringProp; + dynamic dynamicProp; + var untypedProp; + + @Accessor(key: 'custom key!') + var customKeyProp; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceProp; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceProp; +} + +@State(keyNamespace: 'custom state class namespace**') +class _$NamespacedAccessorTestState extends UiState { + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +@Component() +class NamespacedAccessorTestComponent extends UiStatefulComponent2 { + @override + render() => (Dom.div() + ..addProps(copyUnconsumedProps()) + )('rendered content'); +} + diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.over_react.g.dart new file mode 100644 index 000000000..2873725c0 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.over_react.g.dart @@ -0,0 +1,474 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'namespaced_accessor_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $NamespacedAccessorTestComponentFactory = registerComponent( + () => new _$NamespacedAccessorTestComponent(), + builderFactory: NamespacedAccessorTest, + componentClass: NamespacedAccessorTestComponent, + isWrapper: false, + parentType: null, + displayName: 'NamespacedAccessorTest'); + +abstract class _$NamespacedAccessorTestPropsAccessorsMixin + implements _$NamespacedAccessorTestProps { + @override + Map get props; + + /// + @override + String get stringProp => + props[_$key__stringProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => + props[_$key__stringProp___$NamespacedAccessorTestProps] = value; + + /// + @override + dynamic get dynamicProp => + props[_$key__dynamicProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicProp(dynamic value) => + props[_$key__dynamicProp___$NamespacedAccessorTestProps] = value; + + /// + @override + get untypedProp => + props[_$key__untypedProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedProp(value) => + props[_$key__untypedProp___$NamespacedAccessorTestProps] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyProp => + props[_$key__customKeyProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyProp(value) => + props[_$key__customKeyProp___$NamespacedAccessorTestProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceProp => + props[_$key__customNamespaceProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceProp(value) => + props[_$key__customNamespaceProp___$NamespacedAccessorTestProps] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceProp => + props[_$key__customKeyAndNamespaceProp___$NamespacedAccessorTestProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceProp(value) => + props[_$key__customKeyAndNamespaceProp___$NamespacedAccessorTestProps] = + value; + /* GENERATED CONSTANTS */ + static const PropDescriptor + _$prop__stringProp___$NamespacedAccessorTestProps = + const PropDescriptor(_$key__stringProp___$NamespacedAccessorTestProps); + static const PropDescriptor + _$prop__dynamicProp___$NamespacedAccessorTestProps = + const PropDescriptor(_$key__dynamicProp___$NamespacedAccessorTestProps); + static const PropDescriptor + _$prop__untypedProp___$NamespacedAccessorTestProps = + const PropDescriptor(_$key__untypedProp___$NamespacedAccessorTestProps); + static const PropDescriptor + _$prop__customKeyProp___$NamespacedAccessorTestProps = + const PropDescriptor(_$key__customKeyProp___$NamespacedAccessorTestProps); + static const PropDescriptor + _$prop__customNamespaceProp___$NamespacedAccessorTestProps = + const PropDescriptor( + _$key__customNamespaceProp___$NamespacedAccessorTestProps); + static const PropDescriptor + _$prop__customKeyAndNamespaceProp___$NamespacedAccessorTestProps = + const PropDescriptor( + _$key__customKeyAndNamespaceProp___$NamespacedAccessorTestProps); + static const String _$key__stringProp___$NamespacedAccessorTestProps = + 'custom props class namespace**stringProp'; + static const String _$key__dynamicProp___$NamespacedAccessorTestProps = + 'custom props class namespace**dynamicProp'; + static const String _$key__untypedProp___$NamespacedAccessorTestProps = + 'custom props class namespace**untypedProp'; + static const String _$key__customKeyProp___$NamespacedAccessorTestProps = + 'custom props class namespace**custom key!'; + static const String + _$key__customNamespaceProp___$NamespacedAccessorTestProps = + 'custom namespace~~customNamespaceProp'; + static const String + _$key__customKeyAndNamespaceProp___$NamespacedAccessorTestProps = + 'custom namespace~~custom key!'; + + static const List $props = const [ + _$prop__stringProp___$NamespacedAccessorTestProps, + _$prop__dynamicProp___$NamespacedAccessorTestProps, + _$prop__untypedProp___$NamespacedAccessorTestProps, + _$prop__customKeyProp___$NamespacedAccessorTestProps, + _$prop__customNamespaceProp___$NamespacedAccessorTestProps, + _$prop__customKeyAndNamespaceProp___$NamespacedAccessorTestProps + ]; + static const List $propKeys = const [ + _$key__stringProp___$NamespacedAccessorTestProps, + _$key__dynamicProp___$NamespacedAccessorTestProps, + _$key__untypedProp___$NamespacedAccessorTestProps, + _$key__customKeyProp___$NamespacedAccessorTestProps, + _$key__customNamespaceProp___$NamespacedAccessorTestProps, + _$key__customKeyAndNamespaceProp___$NamespacedAccessorTestProps + ]; +} + +const PropsMeta _$metaForNamespacedAccessorTestProps = const PropsMeta( + fields: _$NamespacedAccessorTestPropsAccessorsMixin.$props, + keys: _$NamespacedAccessorTestPropsAccessorsMixin.$propKeys, +); + +class NamespacedAccessorTestProps extends _$NamespacedAccessorTestProps + with _$NamespacedAccessorTestPropsAccessorsMixin { + static const PropsMeta meta = _$metaForNamespacedAccessorTestProps; +} + +_$$NamespacedAccessorTestProps _$NamespacedAccessorTest([Map backingProps]) => + backingProps == null + ? new _$$NamespacedAccessorTestProps$JsMap(new JsBackedMap()) + : new _$$NamespacedAccessorTestProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$NamespacedAccessorTestProps + extends _$NamespacedAccessorTestProps + with _$NamespacedAccessorTestPropsAccessorsMixin + implements NamespacedAccessorTestProps { + _$$NamespacedAccessorTestProps._(); + + factory _$$NamespacedAccessorTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$NamespacedAccessorTestProps$JsMap(backingMap); + } else { + return new _$$NamespacedAccessorTestProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $NamespacedAccessorTestComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'custom props class namespace**'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$NamespacedAccessorTestProps$PlainMap + extends _$$NamespacedAccessorTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$NamespacedAccessorTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$NamespacedAccessorTestProps$JsMap + extends _$$NamespacedAccessorTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$NamespacedAccessorTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$NamespacedAccessorTestStateAccessorsMixin + implements _$NamespacedAccessorTestState { + @override + Map get state; + + /// + @override + String get stringState => + state[_$key__stringState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$NamespacedAccessorTestState] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$NamespacedAccessorTestState] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$NamespacedAccessorTestState] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$NamespacedAccessorTestState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$NamespacedAccessorTestState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[_$key__customKeyAndNamespaceState___$NamespacedAccessorTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => + state[_$key__customKeyAndNamespaceState___$NamespacedAccessorTestState] = + value; + /* GENERATED CONSTANTS */ + static const StateDescriptor + _$prop__stringState___$NamespacedAccessorTestState = + const StateDescriptor(_$key__stringState___$NamespacedAccessorTestState); + static const StateDescriptor + _$prop__dynamicState___$NamespacedAccessorTestState = + const StateDescriptor(_$key__dynamicState___$NamespacedAccessorTestState); + static const StateDescriptor + _$prop__untypedState___$NamespacedAccessorTestState = + const StateDescriptor(_$key__untypedState___$NamespacedAccessorTestState); + static const StateDescriptor + _$prop__customKeyState___$NamespacedAccessorTestState = + const StateDescriptor( + _$key__customKeyState___$NamespacedAccessorTestState); + static const StateDescriptor + _$prop__customNamespaceState___$NamespacedAccessorTestState = + const StateDescriptor( + _$key__customNamespaceState___$NamespacedAccessorTestState); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$NamespacedAccessorTestState = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$NamespacedAccessorTestState); + static const String _$key__stringState___$NamespacedAccessorTestState = + 'custom state class namespace**stringState'; + static const String _$key__dynamicState___$NamespacedAccessorTestState = + 'custom state class namespace**dynamicState'; + static const String _$key__untypedState___$NamespacedAccessorTestState = + 'custom state class namespace**untypedState'; + static const String _$key__customKeyState___$NamespacedAccessorTestState = + 'custom state class namespace**custom key!'; + static const String + _$key__customNamespaceState___$NamespacedAccessorTestState = + 'custom namespace~~customNamespaceState'; + static const String + _$key__customKeyAndNamespaceState___$NamespacedAccessorTestState = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$NamespacedAccessorTestState, + _$prop__dynamicState___$NamespacedAccessorTestState, + _$prop__untypedState___$NamespacedAccessorTestState, + _$prop__customKeyState___$NamespacedAccessorTestState, + _$prop__customNamespaceState___$NamespacedAccessorTestState, + _$prop__customKeyAndNamespaceState___$NamespacedAccessorTestState + ]; + static const List $stateKeys = const [ + _$key__stringState___$NamespacedAccessorTestState, + _$key__dynamicState___$NamespacedAccessorTestState, + _$key__untypedState___$NamespacedAccessorTestState, + _$key__customKeyState___$NamespacedAccessorTestState, + _$key__customNamespaceState___$NamespacedAccessorTestState, + _$key__customKeyAndNamespaceState___$NamespacedAccessorTestState + ]; +} + +const StateMeta _$metaForNamespacedAccessorTestState = const StateMeta( + fields: _$NamespacedAccessorTestStateAccessorsMixin.$state, + keys: _$NamespacedAccessorTestStateAccessorsMixin.$stateKeys, +); + +class NamespacedAccessorTestState extends _$NamespacedAccessorTestState + with _$NamespacedAccessorTestStateAccessorsMixin { + static const StateMeta meta = _$metaForNamespacedAccessorTestState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$NamespacedAccessorTestState + extends _$NamespacedAccessorTestState + with _$NamespacedAccessorTestStateAccessorsMixin + implements NamespacedAccessorTestState { + _$$NamespacedAccessorTestState._(); + + factory _$$NamespacedAccessorTestState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$NamespacedAccessorTestState$JsMap(backingMap); + } else { + return new _$$NamespacedAccessorTestState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$NamespacedAccessorTestState$PlainMap + extends _$$NamespacedAccessorTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$NamespacedAccessorTestState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$NamespacedAccessorTestState$JsMap + extends _$$NamespacedAccessorTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$NamespacedAccessorTestState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$NamespacedAccessorTestComponent + extends NamespacedAccessorTestComponent { + _$$NamespacedAccessorTestProps$JsMap _cachedTypedProps; + + @override + _$$NamespacedAccessorTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$NamespacedAccessorTestProps$JsMap typedPropsFactoryJs( + JsBackedMap backingMap) => + new _$$NamespacedAccessorTestProps$JsMap(backingMap); + + @override + _$$NamespacedAccessorTestProps typedPropsFactory(Map backingMap) => + new _$$NamespacedAccessorTestProps(backingMap); + + _$$NamespacedAccessorTestState$JsMap _cachedTypedState; + @override + _$$NamespacedAccessorTestState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$NamespacedAccessorTestState$JsMap typedStateFactoryJs( + JsBackedMap backingMap) => + new _$$NamespacedAccessorTestState$JsMap(backingMap); + + @override + _$$NamespacedAccessorTestState typedStateFactory(Map backingMap) => + new _$$NamespacedAccessorTestState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$NamespacedAccessorTestProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForNamespacedAccessorTestProps + ]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.dart b/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.dart new file mode 100644 index 000000000..ac9775074 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.dart @@ -0,0 +1,36 @@ +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import '../../../../test_util/test_util.dart'; + +part 'private_props_ddc_bug.over_react.g.dart'; + +main() { + test('(Component2) sets private props correctly in `getDefaultProps`', () { + var instance = render((Foo())()); + + expect(instance, isNotNull); // sanity check + + var node = findDomNode(instance); + + expect(node.text, contains('some private value')); + }); +} + + +@Factory() +UiFactory Foo = _$Foo; + +@Props() +class _$FooProps extends UiProps { + String _privateProp; +} + +@Component() +class FooComponent extends UiComponent2 { + @override + Map getDefaultProps() => newProps().._privateProp = 'some private value'; + + @override + render() => (Dom.div())(props._privateProp); +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.over_react.g.dart new file mode 100644 index 000000000..06dafe217 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.over_react.g.dart @@ -0,0 +1,149 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'private_props_ddc_bug.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $FooComponentFactory = registerComponent(() => new _$FooComponent(), + builderFactory: Foo, + componentClass: FooComponent, + isWrapper: false, + parentType: null, + displayName: 'Foo'); + +abstract class _$FooPropsAccessorsMixin implements _$FooProps { + @override + Map get props; + + /// + @override + String get _privateProp => + props[_$key___privateProp___$FooProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set _privateProp(String value) => + props[_$key___privateProp___$FooProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop___privateProp___$FooProps = + const PropDescriptor(_$key___privateProp___$FooProps); + static const String _$key___privateProp___$FooProps = 'FooProps._privateProp'; + + static const List $props = const [ + _$prop___privateProp___$FooProps + ]; + static const List $propKeys = const [_$key___privateProp___$FooProps]; +} + +const PropsMeta _$metaForFooProps = const PropsMeta( + fields: _$FooPropsAccessorsMixin.$props, + keys: _$FooPropsAccessorsMixin.$propKeys, +); + +class FooProps extends _$FooProps with _$FooPropsAccessorsMixin { + static const PropsMeta meta = _$metaForFooProps; +} + +_$$FooProps _$Foo([Map backingProps]) => backingProps == null + ? new _$$FooProps$JsMap(new JsBackedMap()) + : new _$$FooProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$FooProps extends _$FooProps + with _$FooPropsAccessorsMixin + implements FooProps { + _$$FooProps._(); + + factory _$$FooProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$FooProps$JsMap(backingMap); + } else { + return new _$$FooProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $FooComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'FooProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$FooProps$PlainMap extends _$$FooProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$FooProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$FooProps$JsMap extends _$$FooProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$FooProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$FooComponent extends FooComponent { + _$$FooProps$JsMap _cachedTypedProps; + + @override + _$$FooProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$FooProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$FooProps$JsMap(backingMap); + + @override + _$$FooProps typedPropsFactory(Map backingMap) => new _$$FooProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$FooProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [_$metaForFooProps]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.dart b/test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.dart similarity index 87% rename from test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.dart rename to test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.dart index 2d5053233..640c66640 100644 --- a/test/over_react/component_declaration/builder_integration_tests/required_prop_integration_tests.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.dart @@ -17,12 +17,12 @@ import 'package:over_react/over_react.dart'; import 'package:over_react/react_dom.dart' as react_dom; import 'package:test/test.dart'; -import '../../../test_util/test_util.dart'; +import '../../../../test_util/test_util.dart'; -part 'required_prop_integration_tests.over_react.g.dart'; +part 'required_accessor_integration_test.over_react.g.dart'; -void requiredPropsIntegrationTest() { - group('properly identifies required props by', () { +void main() { + group('(Component2) properly identifies required props by', () { group('throwing when a prop is required and not set', () { test('on mount', () { expect(() => render(ComponentTest()..nullable = true), @@ -130,7 +130,8 @@ void requiredPropsIntegrationTest() { )(), mountNode), returnsNormally); }); }); - }); + // FIXME 3.0.0-wip unskip once implemented in CPLAT-4887 + }, skip: 'Component2 prop validation will be added in CPLAT-4887'); } @Factory() @@ -138,17 +139,15 @@ UiFactory ComponentTest = _$ComponentTest; @Props() class _$ComponentTestProps extends UiProps { - // ignore: deprecated_member_use - @Required(message: 'This Prop is Required for testing purposes.') + @Accessor(isRequired: true, requiredErrorMessage: 'This Prop is Required for testing purposes.') var required; - // ignore: deprecated_member_use - @Required(isNullable: true, message: 'This prop can be set to null!') + @Accessor(isRequired: true, isNullable: true, requiredErrorMessage: 'This prop can be set to null!') var nullable; } @Component() -class ComponentTestComponent extends UiComponent { +class ComponentTestComponent extends UiComponent2 { @override render() => Dom.div()(); } diff --git a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.over_react.g.dart similarity index 63% rename from test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.over_react.g.dart rename to test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.over_react.g.dart index c26f66091..92390c9b2 100644 --- a/test/over_react/component_declaration/builder_integration_tests/backwards_compatible/required_prop_integration_tests.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.over_react.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'required_prop_integration_tests.dart'; +part of 'required_accessor_integration_test.dart'; // ************************************************************************** // OverReactGenerator @@ -24,24 +24,34 @@ abstract class _$ComponentTestPropsAccessorsMixin /// @override - @Required(message: 'This Prop is Required for testing purposes.') + @Accessor( + isRequired: true, + requiredErrorMessage: 'This Prop is Required for testing purposes.') get required => props[_$key__required___$ComponentTestProps] ?? null; // Add ` ?? null` to workaround DDC bug: ; /// @override - @Required(message: 'This Prop is Required for testing purposes.') + @Accessor( + isRequired: true, + requiredErrorMessage: 'This Prop is Required for testing purposes.') set required(value) => props[_$key__required___$ComponentTestProps] = value; /// @override - @Required(isNullable: true, message: 'This prop can be set to null!') + @Accessor( + isRequired: true, + isNullable: true, + requiredErrorMessage: 'This prop can be set to null!') get nullable => props[_$key__nullable___$ComponentTestProps] ?? null; // Add ` ?? null` to workaround DDC bug: ; /// @override - @Required(isNullable: true, message: 'This prop can be set to null!') + @Accessor( + isRequired: true, + isNullable: true, + requiredErrorMessage: 'This prop can be set to null!') set nullable(value) => props[_$key__nullable___$ComponentTestProps] = value; /* GENERATED CONSTANTS */ static const PropDescriptor _$prop__required___$ComponentTestProps = @@ -73,27 +83,32 @@ const PropsMeta _$metaForComponentTestProps = const PropsMeta( keys: _$ComponentTestPropsAccessorsMixin.$propKeys, ); +class ComponentTestProps extends _$ComponentTestProps + with _$ComponentTestPropsAccessorsMixin { + static const PropsMeta meta = _$metaForComponentTestProps; +} + _$$ComponentTestProps _$ComponentTest([Map backingProps]) => - new _$$ComponentTestProps(backingProps); + backingProps == null + ? new _$$ComponentTestProps$JsMap(new JsBackedMap()) + : new _$$ComponentTestProps(backingProps); // Concrete props implementation. // // Implements constructor and backing map, and links up to generated component factory. -class _$$ComponentTestProps extends _$ComponentTestProps +abstract class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { - // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details - _$$ComponentTestProps(Map backingMap) : this._props = {} { - this._props = backingMap ?? {}; + _$$ComponentTestProps._(); + + factory _$$ComponentTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ComponentTestProps$JsMap(backingMap); + } else { + return new _$$ComponentTestProps$PlainMap(backingMap); + } } - /// The backing props map proxied by this class. - @override - Map get props => _props; - Map _props; - /// Let [UiProps] internals know that this class has been generated. @override bool get $isClassGenerated => true; @@ -108,11 +123,59 @@ class _$$ComponentTestProps extends _$ComponentTestProps String get propKeyNamespace => 'ComponentTestProps.'; } +// Concrete props implementation that can be backed by any [Map]. +class _$$ComponentTestProps$PlainMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ComponentTestProps$JsMap extends _$$ComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ComponentTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + // Concrete component implementation mixin. // // Implements typed props/state factories, defaults `consumedPropKeys` to the keys // generated for the associated props class. class _$ComponentTestComponent extends ComponentTestComponent { + _$$ComponentTestProps$JsMap _cachedTypedProps; + + @override + _$$ComponentTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ComponentTestProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ComponentTestProps$JsMap(backingMap); + @override _$$ComponentTestProps typedPropsFactory(Map backingMap) => new _$$ComponentTestProps(backingMap); diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.dart new file mode 100644 index 000000000..582988541 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.dart @@ -0,0 +1,127 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import '../../../../test_util/test_util.dart'; + +part 'stateful_component_integration_test.over_react.g.dart'; + +main() { + group('(Component2) stateful component integration:', () { + test('state class cannot be instantiated directly', () { + expect(() { + new StatefulComponentTestState(); + }, throwsA(const TypeMatcher())); + }); + + test('renders a component from end to end, successfully reading state via typed getters', () { + var renderedInstance = render(StatefulComponentTest()()); + expect(renderedInstance, isNotNull); + + var node = findDomNode(renderedInstance); + expect(node.text, 'rendered content'); + expect(node.dataset, containsPair('state-string-state', '1')); + expect(node.dataset, containsPair('state-dynamic-state', '2')); + expect(node.dataset, containsPair('state-untyped-state', '3')); + expect(node.dataset, containsPair('state-custom-key-state', '4')); + expect(node.dataset, containsPair('state-custom-namespace-state', '5')); + expect(node.dataset, containsPair('state-custom-key-and-namespace-state', '6')); + }); + + group('generates state getters/setters with', () { + StatefulComponentTestComponent component; + + setUp(() { + var renderedInstance = render(StatefulComponentTest()()); + component = getDartComponent(renderedInstance); + }); + + test('prop keys using the props class name as a namespace and the prop name as the key by default', () { + expect(component.newState()..stringState = 'test', + containsPair('StatefulComponentTestState.stringState', 'test')); + + expect(component.newState()..dynamicState = 2, + containsPair('StatefulComponentTestState.dynamicState', 2)); + + expect(component.newState()..untypedState = false, + containsPair('StatefulComponentTestState.untypedState', false)); + }); + + test('custom prop keys', () { + expect(component.newState()..customKeyState = 'test', + containsPair('StatefulComponentTestState.custom key!', 'test')); + }); + + test('custom prop key namespaces', () { + expect(component.newState()..customNamespaceState = 'test', + containsPair('custom namespace~~customNamespaceState', 'test')); + }); + + test('custom prop keys and namespaces', () { + expect(component.newState()..customKeyAndNamespaceState = 'test', + containsPair('custom namespace~~custom key!', 'test')); + }); + }); + }); +} + + +@Factory() +UiFactory StatefulComponentTest = _$StatefulComponentTest; + +@Props() +class _$StatefulComponentTestProps extends UiProps {} + +@State() +class _$StatefulComponentTestState extends UiState { + String stringState; + dynamic dynamicState; + var untypedState; + + @Accessor(key: 'custom key!') + var customKeyState; + + @Accessor(keyNamespace: 'custom namespace~~') + var customNamespaceState; + + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + var customKeyAndNamespaceState; +} + +@Component() +class StatefulComponentTestComponent extends UiStatefulComponent2 { + @override + getInitialState() => (newState() + ..stringState = '1' + ..dynamicState = '2' + ..untypedState = '3' + ..customKeyState = '4' + ..customNamespaceState = '5' + ..customKeyAndNamespaceState = '6' + ); + + @override + render() => (Dom.div() + ..addProps(copyUnconsumedProps()) + ..addProp('data-who', state.stringState) + ..addProp('data-state-string-state', state.stringState) + ..addProp('data-state-dynamic-state', state.dynamicState) + ..addProp('data-state-untyped-state', state.untypedState) + ..addProp('data-state-custom-key-state', state.customKeyState) + ..addProp('data-state-custom-namespace-state', state.customNamespaceState) + ..addProp('data-state-custom-key-and-namespace-state', state.customKeyAndNamespaceState) + )('rendered content'); +} + diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.over_react.g.dart new file mode 100644 index 000000000..c81eec302 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.over_react.g.dart @@ -0,0 +1,359 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stateful_component_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $StatefulComponentTestComponentFactory = registerComponent( + () => new _$StatefulComponentTestComponent(), + builderFactory: StatefulComponentTest, + componentClass: StatefulComponentTestComponent, + isWrapper: false, + parentType: null, + displayName: 'StatefulComponentTest'); + +abstract class _$StatefulComponentTestPropsAccessorsMixin + implements _$StatefulComponentTestProps { + @override + Map get props; + + /* GENERATED CONSTANTS */ + + static const List $props = const []; + static const List $propKeys = const []; +} + +const PropsMeta _$metaForStatefulComponentTestProps = const PropsMeta( + fields: _$StatefulComponentTestPropsAccessorsMixin.$props, + keys: _$StatefulComponentTestPropsAccessorsMixin.$propKeys, +); + +class StatefulComponentTestProps extends _$StatefulComponentTestProps + with _$StatefulComponentTestPropsAccessorsMixin { + static const PropsMeta meta = _$metaForStatefulComponentTestProps; +} + +_$$StatefulComponentTestProps _$StatefulComponentTest([Map backingProps]) => + backingProps == null + ? new _$$StatefulComponentTestProps$JsMap(new JsBackedMap()) + : new _$$StatefulComponentTestProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$StatefulComponentTestProps + extends _$StatefulComponentTestProps + with _$StatefulComponentTestPropsAccessorsMixin + implements StatefulComponentTestProps { + _$$StatefulComponentTestProps._(); + + factory _$$StatefulComponentTestProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$StatefulComponentTestProps$JsMap(backingMap); + } else { + return new _$$StatefulComponentTestProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $StatefulComponentTestComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'StatefulComponentTestProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$StatefulComponentTestProps$PlainMap + extends _$$StatefulComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$StatefulComponentTestProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$StatefulComponentTestProps$JsMap + extends _$$StatefulComponentTestProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$StatefulComponentTestProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$StatefulComponentTestStateAccessorsMixin + implements _$StatefulComponentTestState { + @override + Map get state; + + /// + @override + String get stringState => + state[_$key__stringState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringState(String value) => + state[_$key__stringState___$StatefulComponentTestState] = value; + + /// + @override + dynamic get dynamicState => + state[_$key__dynamicState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set dynamicState(dynamic value) => + state[_$key__dynamicState___$StatefulComponentTestState] = value; + + /// + @override + get untypedState => + state[_$key__untypedState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set untypedState(value) => + state[_$key__untypedState___$StatefulComponentTestState] = value; + + /// + @override + @Accessor(key: 'custom key!') + get customKeyState => + state[_$key__customKeyState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(key: 'custom key!') + set customKeyState(value) => + state[_$key__customKeyState___$StatefulComponentTestState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + get customNamespaceState => + state[_$key__customNamespaceState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~') + set customNamespaceState(value) => + state[_$key__customNamespaceState___$StatefulComponentTestState] = value; + + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + get customKeyAndNamespaceState => + state[_$key__customKeyAndNamespaceState___$StatefulComponentTestState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + @Accessor(keyNamespace: 'custom namespace~~', key: 'custom key!') + set customKeyAndNamespaceState(value) => + state[_$key__customKeyAndNamespaceState___$StatefulComponentTestState] = + value; + /* GENERATED CONSTANTS */ + static const StateDescriptor + _$prop__stringState___$StatefulComponentTestState = + const StateDescriptor(_$key__stringState___$StatefulComponentTestState); + static const StateDescriptor + _$prop__dynamicState___$StatefulComponentTestState = + const StateDescriptor(_$key__dynamicState___$StatefulComponentTestState); + static const StateDescriptor + _$prop__untypedState___$StatefulComponentTestState = + const StateDescriptor(_$key__untypedState___$StatefulComponentTestState); + static const StateDescriptor + _$prop__customKeyState___$StatefulComponentTestState = + const StateDescriptor( + _$key__customKeyState___$StatefulComponentTestState); + static const StateDescriptor + _$prop__customNamespaceState___$StatefulComponentTestState = + const StateDescriptor( + _$key__customNamespaceState___$StatefulComponentTestState); + static const StateDescriptor + _$prop__customKeyAndNamespaceState___$StatefulComponentTestState = + const StateDescriptor( + _$key__customKeyAndNamespaceState___$StatefulComponentTestState); + static const String _$key__stringState___$StatefulComponentTestState = + 'StatefulComponentTestState.stringState'; + static const String _$key__dynamicState___$StatefulComponentTestState = + 'StatefulComponentTestState.dynamicState'; + static const String _$key__untypedState___$StatefulComponentTestState = + 'StatefulComponentTestState.untypedState'; + static const String _$key__customKeyState___$StatefulComponentTestState = + 'StatefulComponentTestState.custom key!'; + static const String + _$key__customNamespaceState___$StatefulComponentTestState = + 'custom namespace~~customNamespaceState'; + static const String + _$key__customKeyAndNamespaceState___$StatefulComponentTestState = + 'custom namespace~~custom key!'; + + static const List $state = const [ + _$prop__stringState___$StatefulComponentTestState, + _$prop__dynamicState___$StatefulComponentTestState, + _$prop__untypedState___$StatefulComponentTestState, + _$prop__customKeyState___$StatefulComponentTestState, + _$prop__customNamespaceState___$StatefulComponentTestState, + _$prop__customKeyAndNamespaceState___$StatefulComponentTestState + ]; + static const List $stateKeys = const [ + _$key__stringState___$StatefulComponentTestState, + _$key__dynamicState___$StatefulComponentTestState, + _$key__untypedState___$StatefulComponentTestState, + _$key__customKeyState___$StatefulComponentTestState, + _$key__customNamespaceState___$StatefulComponentTestState, + _$key__customKeyAndNamespaceState___$StatefulComponentTestState + ]; +} + +const StateMeta _$metaForStatefulComponentTestState = const StateMeta( + fields: _$StatefulComponentTestStateAccessorsMixin.$state, + keys: _$StatefulComponentTestStateAccessorsMixin.$stateKeys, +); + +class StatefulComponentTestState extends _$StatefulComponentTestState + with _$StatefulComponentTestStateAccessorsMixin { + static const StateMeta meta = _$metaForStatefulComponentTestState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$StatefulComponentTestState + extends _$StatefulComponentTestState + with _$StatefulComponentTestStateAccessorsMixin + implements StatefulComponentTestState { + _$$StatefulComponentTestState._(); + + factory _$$StatefulComponentTestState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$StatefulComponentTestState$JsMap(backingMap); + } else { + return new _$$StatefulComponentTestState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$StatefulComponentTestState$PlainMap + extends _$$StatefulComponentTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$StatefulComponentTestState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$StatefulComponentTestState$JsMap + extends _$$StatefulComponentTestState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$StatefulComponentTestState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$StatefulComponentTestComponent extends StatefulComponentTestComponent { + _$$StatefulComponentTestProps$JsMap _cachedTypedProps; + + @override + _$$StatefulComponentTestProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$StatefulComponentTestProps$JsMap typedPropsFactoryJs( + JsBackedMap backingMap) => + new _$$StatefulComponentTestProps$JsMap(backingMap); + + @override + _$$StatefulComponentTestProps typedPropsFactory(Map backingMap) => + new _$$StatefulComponentTestProps(backingMap); + + _$$StatefulComponentTestState$JsMap _cachedTypedState; + @override + _$$StatefulComponentTestState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$StatefulComponentTestState$JsMap typedStateFactoryJs( + JsBackedMap backingMap) => + new _$$StatefulComponentTestState$JsMap(backingMap); + + @override + _$$StatefulComponentTestState typedStateFactory(Map backingMap) => + new _$$StatefulComponentTestState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$StatefulComponentTestProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForStatefulComponentTestProps + ]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.dart new file mode 100644 index 000000000..a52ab015e --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.dart @@ -0,0 +1,42 @@ +import 'package:over_react/over_react.dart'; +import 'package:test/test.dart'; + +import '../../../../test_util/test_util.dart'; + +part 'unassigned_prop_integration_test.over_react.g.dart'; + +main() { + test('(Component2) renders all children, even with unassigned props present', () { + var instance = render((Foo() + ..stringProp = 'some string value' + )()); + + expect(instance, isNotNull); // sanity check + + var node = findDomNode(instance); + + // This tests a workaround added to impl_generation.dart to add ` ?? null;` to the getters + // for props/state members. Details: + // without this workaround, this test would fail when compiled via DDC. + expect(node.text, contains('some string value')); + }); +} + + +@Factory() +UiFactory Foo = _$Foo; + +@Props() +class _$FooProps extends UiProps { + String stringProp; + String unassignedProp; +} + +@Component() +class FooComponent extends UiComponent2 { + @override + Map getDefaultProps() => newProps()..id = 'testId'; + + @override + render() => (Dom.div())(props.unassignedProp, props.stringProp); +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.over_react.g.dart new file mode 100644 index 000000000..eb9c0d6e1 --- /dev/null +++ b/test/over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.over_react.g.dart @@ -0,0 +1,166 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'unassigned_prop_integration_test.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $FooComponentFactory = registerComponent(() => new _$FooComponent(), + builderFactory: Foo, + componentClass: FooComponent, + isWrapper: false, + parentType: null, + displayName: 'Foo'); + +abstract class _$FooPropsAccessorsMixin implements _$FooProps { + @override + Map get props; + + /// + @override + String get stringProp => + props[_$key__stringProp___$FooProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set stringProp(String value) => props[_$key__stringProp___$FooProps] = value; + + /// + @override + String get unassignedProp => + props[_$key__unassignedProp___$FooProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// + @override + set unassignedProp(String value) => + props[_$key__unassignedProp___$FooProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__stringProp___$FooProps = + const PropDescriptor(_$key__stringProp___$FooProps); + static const PropDescriptor _$prop__unassignedProp___$FooProps = + const PropDescriptor(_$key__unassignedProp___$FooProps); + static const String _$key__stringProp___$FooProps = 'FooProps.stringProp'; + static const String _$key__unassignedProp___$FooProps = + 'FooProps.unassignedProp'; + + static const List $props = const [ + _$prop__stringProp___$FooProps, + _$prop__unassignedProp___$FooProps + ]; + static const List $propKeys = const [ + _$key__stringProp___$FooProps, + _$key__unassignedProp___$FooProps + ]; +} + +const PropsMeta _$metaForFooProps = const PropsMeta( + fields: _$FooPropsAccessorsMixin.$props, + keys: _$FooPropsAccessorsMixin.$propKeys, +); + +class FooProps extends _$FooProps with _$FooPropsAccessorsMixin { + static const PropsMeta meta = _$metaForFooProps; +} + +_$$FooProps _$Foo([Map backingProps]) => backingProps == null + ? new _$$FooProps$JsMap(new JsBackedMap()) + : new _$$FooProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$FooProps extends _$FooProps + with _$FooPropsAccessorsMixin + implements FooProps { + _$$FooProps._(); + + factory _$$FooProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$FooProps$JsMap(backingMap); + } else { + return new _$$FooProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $FooComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'FooProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$FooProps$PlainMap extends _$$FooProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$FooProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$FooProps$JsMap extends _$$FooProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$FooProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$FooComponent extends FooComponent { + _$$FooProps$JsMap _cachedTypedProps; + + @override + _$$FooProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$FooProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$FooProps$JsMap(backingMap); + + @override + _$$FooProps typedPropsFactory(Map backingMap) => new _$$FooProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$FooProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [_$metaForFooProps]; +} diff --git a/test/over_react/component_declaration/builder_integration_tests/component_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/component_integration_test.dart index e67eba9b2..833fa42a0 100644 --- a/test/over_react/component_declaration/builder_integration_tests/component_integration_test.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component_integration_test.dart @@ -14,7 +14,7 @@ import 'package:over_react/over_react.dart'; import 'package:test/test.dart'; -import './required_prop_integration_tests.dart' as r; +import './constant_required_accessor_integration_test.dart' as r; import '../../../test_util/test_util.dart'; part 'component_integration_test.over_react.g.dart'; @@ -118,8 +118,6 @@ main() { expect(shallowPropKeys.where((String key) => !key.startsWith('data-prop-')), unorderedEquals(['id', 'extraneous', 'children'])); }); - - r.requiredPropsIntegrationTest(); }); } diff --git a/test/over_react/component_declaration/builder_integration_tests/component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/component_integration_test.over_react.g.dart index 08fb80041..e38c001e5 100644 --- a/test/over_react/component_declaration/builder_integration_tests/component_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/component_integration_test.over_react.g.dart @@ -154,8 +154,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.dart b/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.dart index 2fabd7450..766e05694 100644 --- a/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.dart +++ b/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.dart @@ -130,7 +130,8 @@ void main() { )(), mountNode), returnsNormally); }); }); - }); + // FIXME 3.0.0-wip unskip once implemented in CPLAT-4887 + }, skip: 'Component2 prop validation will be added in CPLAT-4887'); } @Factory() diff --git a/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.over_react.g.dart index ca2e7467a..29112637f 100644 --- a/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/constant_required_accessor_integration_test.over_react.g.dart @@ -85,8 +85,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/do_not_generate_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/do_not_generate_accessor_integration_test.over_react.g.dart index 482f38482..053ae7bb5 100644 --- a/test/over_react/component_declaration/builder_integration_tests/do_not_generate_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/do_not_generate_accessor_integration_test.over_react.g.dart @@ -108,8 +108,7 @@ class _$$DoNotGenerateAccessorTestProps extends _$DoNotGenerateAccessorTestProps with _$DoNotGenerateAccessorTestPropsAccessorsMixin implements DoNotGenerateAccessorTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$DoNotGenerateAccessorTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -221,8 +220,7 @@ class _$$DoNotGenerateAccessorTestState extends _$DoNotGenerateAccessorTestState with _$DoNotGenerateAccessorTestStateAccessorsMixin implements DoNotGenerateAccessorTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$DoNotGenerateAccessorTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/namespaced_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/namespaced_accessor_integration_test.over_react.g.dart index 8b2294cc9..321c7bf09 100644 --- a/test/over_react/component_declaration/builder_integration_tests/namespaced_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/namespaced_accessor_integration_test.over_react.g.dart @@ -162,8 +162,7 @@ class _$$NamespacedAccessorTestProps extends _$NamespacedAccessorTestProps with _$NamespacedAccessorTestPropsAccessorsMixin implements NamespacedAccessorTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$NamespacedAccessorTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -330,8 +329,7 @@ class _$$NamespacedAccessorTestState extends _$NamespacedAccessorTestState with _$NamespacedAccessorTestStateAccessorsMixin implements NamespacedAccessorTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$NamespacedAccessorTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/private_props_ddc_bug.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/private_props_ddc_bug.over_react.g.dart index 5bfb0fdcb..90f18e0d0 100644 --- a/test/over_react/component_declaration/builder_integration_tests/private_props_ddc_bug.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/private_props_ddc_bug.over_react.g.dart @@ -58,8 +58,7 @@ class _$$FooProps extends _$FooProps with _$FooPropsAccessorsMixin implements FooProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$FooProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/required_accessor_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/required_accessor_integration_test.over_react.g.dart index ebd9c7e82..e4af45262 100644 --- a/test/over_react/component_declaration/builder_integration_tests/required_accessor_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/required_accessor_integration_test.over_react.g.dart @@ -98,8 +98,7 @@ class _$$ComponentTestProps extends _$ComponentTestProps with _$ComponentTestPropsAccessorsMixin implements ComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/stateful_component_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/stateful_component_integration_test.over_react.g.dart index 698faa785..0947dc2b4 100644 --- a/test/over_react/component_declaration/builder_integration_tests/stateful_component_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/stateful_component_integration_test.over_react.g.dart @@ -48,8 +48,7 @@ class _$$StatefulComponentTestProps extends _$StatefulComponentTestProps with _$StatefulComponentTestPropsAccessorsMixin implements StatefulComponentTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$StatefulComponentTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -216,8 +215,7 @@ class _$$StatefulComponentTestState extends _$StatefulComponentTestState with _$StatefulComponentTestStateAccessorsMixin implements StatefulComponentTestState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$StatefulComponentTestState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/builder_integration_tests/unassigned_prop_integration_test.over_react.g.dart b/test/over_react/component_declaration/builder_integration_tests/unassigned_prop_integration_test.over_react.g.dart index 1e188c8b7..26d887122 100644 --- a/test/over_react/component_declaration/builder_integration_tests/unassigned_prop_integration_test.over_react.g.dart +++ b/test/over_react/component_declaration/builder_integration_tests/unassigned_prop_integration_test.over_react.g.dart @@ -75,8 +75,7 @@ class _$$FooProps extends _$FooProps with _$FooPropsAccessorsMixin implements FooProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$FooProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_base_test.dart b/test/over_react/component_declaration/component_base_test.dart index 5f8923a9d..3ab97d5f9 100644 --- a/test/over_react/component_declaration/component_base_test.dart +++ b/test/over_react/component_declaration/component_base_test.dart @@ -478,6 +478,7 @@ main() { var renderedInstance = render(TestComponent()()); TestComponentComponent component = getDartComponent(renderedInstance); + // ignore: deprecated_member_use expect(component.ref('foo'), isNotNull); }); }); @@ -676,7 +677,7 @@ main() { component.awaitBeforeDispose(completer.future); // Add events to stream - component.manageDisposer(() async => streamController.add('disposalFuture')); // ignore: deprecated_member_use + component.manageDisposer(() async => streamController.add('disposalFuture')); // ignore: deprecated_member_use_from_same_package completer.future.then(streamController.add); // Perform events out of order @@ -772,7 +773,7 @@ main() { test('should call managed disposers', () async { var disposerCalled = false; - component.manageDisposer(() async => disposerCalled = true); // ignore: deprecated_member_use + component.manageDisposer(() async => disposerCalled = true); // ignore: deprecated_member_use_from_same_package expect(disposerCalled, isFalse); await unmountAndDisposal(); expect(disposerCalled, isTrue); @@ -795,7 +796,7 @@ main() { count: 0, reason: 'Did not expect event after cancelling subscription')); - component.manageStreamSubscription(streamSubscription); // ignore: deprecated_member_use + component.manageStreamSubscription(streamSubscription); // ignore: deprecated_member_use_from_same_package await unmountAndDisposal(); streamController diff --git a/test/over_react/component_declaration/component_type_checking_test.dart b/test/over_react/component_declaration/component_type_checking_test.dart index b5529451f..58b9c47ea 100644 --- a/test/over_react/component_declaration/component_type_checking_test.dart +++ b/test/over_react/component_declaration/component_type_checking_test.dart @@ -47,6 +47,7 @@ main() { test('returns the ReactClass type for a ReactDartComponentFactoryProxy', () { var reactClass = createTestReactClass(); + // ignore: deprecated_member_use var factory = new ReactDartComponentFactoryProxy(reactClass); expect(getComponentTypeFromAlias(factory), same(reactClass)); }); @@ -58,6 +59,7 @@ main() { test('returns the ReactClass type for an aliased ReactDartComponentFactoryProxy', () { var reactClass = createTestReactClass(); + // ignore: deprecated_member_use var factory = new ReactDartComponentFactoryProxy(reactClass); var typeAlias = new Object(); diff --git a/test/over_react/component_declaration/component_type_checking_test/test_a.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/test_a.over_react.g.dart index dc65b6122..666204c4b 100644 --- a/test/over_react/component_declaration/component_type_checking_test/test_a.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/test_a.over_react.g.dart @@ -44,8 +44,7 @@ class _$$TestAProps extends _$TestAProps with _$TestAPropsAccessorsMixin implements TestAProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestAProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_type_checking_test/test_b.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/test_b.over_react.g.dart index a3eb3a0e1..15bf4b4fc 100644 --- a/test/over_react/component_declaration/component_type_checking_test/test_b.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/test_b.over_react.g.dart @@ -44,8 +44,7 @@ class _$$TestBProps extends _$TestBProps with _$TestBPropsAccessorsMixin implements TestBProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestBProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/abstract_inheritance/extendedtype.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/abstract_inheritance/extendedtype.over_react.g.dart index 12d545663..18abe3063 100644 --- a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/abstract_inheritance/extendedtype.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/abstract_inheritance/extendedtype.over_react.g.dart @@ -49,8 +49,7 @@ class _$$TestExtendtypeProps extends _$TestExtendtypeProps with _$TestExtendtypePropsAccessorsMixin implements TestExtendtypeProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestExtendtypeProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/parent.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/parent.over_react.g.dart index 3e5e6f40a..ee01fd6e9 100644 --- a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/parent.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/parent.over_react.g.dart @@ -47,8 +47,7 @@ class _$$TestParentProps extends _$TestParentProps with _$TestParentPropsAccessorsMixin implements TestParentProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestParentProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subsubtype.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subsubtype.over_react.g.dart index fc7b69f4d..6f873f831 100644 --- a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subsubtype.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subsubtype.over_react.g.dart @@ -49,8 +49,7 @@ class _$$TestSubsubtypeProps extends _$TestSubsubtypeProps with _$TestSubsubtypePropsAccessorsMixin implements TestSubsubtypeProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestSubsubtypeProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subtype.over_react.g.dart b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subtype.over_react.g.dart index e16ca29b5..8fdbc7509 100644 --- a/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subtype.over_react.g.dart +++ b/test/over_react/component_declaration/component_type_checking_test/type_inheritance/subtype.over_react.g.dart @@ -48,8 +48,7 @@ class _$$TestSubtypeProps extends _$TestSubtypeProps with _$TestSubtypePropsAccessorsMixin implements TestSubtypeProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestSubtypeProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/flux_component_test.over_react.g.dart b/test/over_react/component_declaration/flux_component_test.over_react.g.dart index 8e956eb32..e485b2dc7 100644 --- a/test/over_react/component_declaration/flux_component_test.over_react.g.dart +++ b/test/over_react/component_declaration/flux_component_test.over_react.g.dart @@ -47,8 +47,7 @@ class _$$TestBasicProps extends _$TestBasicProps with _$TestBasicPropsAccessorsMixin implements TestBasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestBasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -134,8 +133,7 @@ class _$$TestHandlerLifecycleProps extends _$TestHandlerLifecycleProps with _$TestHandlerLifecyclePropsAccessorsMixin implements TestHandlerLifecycleProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestHandlerLifecycleProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -222,8 +220,7 @@ class _$$TestHandlerPrecedenceProps extends _$TestHandlerPrecedenceProps with _$TestHandlerPrecedencePropsAccessorsMixin implements TestHandlerPrecedenceProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestHandlerPrecedenceProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -330,8 +327,7 @@ class _$$TestPropValidationProps extends _$TestPropValidationProps with _$TestPropValidationPropsAccessorsMixin implements TestPropValidationProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestPropValidationProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -418,8 +414,7 @@ class _$$TestRedrawOnProps extends _$TestRedrawOnProps with _$TestRedrawOnPropsAccessorsMixin implements TestRedrawOnProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestRedrawOnProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -506,8 +501,7 @@ class _$$TestStoreHandlersProps extends _$TestStoreHandlersProps with _$TestStoreHandlersPropsAccessorsMixin implements TestStoreHandlersProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStoreHandlersProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -594,8 +588,7 @@ class _$$TestStatefulBasicProps extends _$TestStatefulBasicProps with _$TestStatefulBasicPropsAccessorsMixin implements TestStatefulBasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulBasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -647,8 +640,7 @@ class _$$TestStatefulBasicState extends _$TestStatefulBasicState with _$TestStatefulBasicStateAccessorsMixin implements TestStatefulBasicState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulBasicState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -733,8 +725,7 @@ class _$$TestStatefulHandlerLifecycleProps with _$TestStatefulHandlerLifecyclePropsAccessorsMixin implements TestStatefulHandlerLifecycleProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulHandlerLifecycleProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -788,8 +779,7 @@ class _$$TestStatefulHandlerLifecycleState with _$TestStatefulHandlerLifecycleStateAccessorsMixin implements TestStatefulHandlerLifecycleState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulHandlerLifecycleState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -875,8 +865,7 @@ class _$$TestStatefulHandlerPrecedenceProps with _$TestStatefulHandlerPrecedencePropsAccessorsMixin implements TestStatefulHandlerPrecedenceProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulHandlerPrecedenceProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -930,8 +919,7 @@ class _$$TestStatefulHandlerPrecedenceState with _$TestStatefulHandlerPrecedenceStateAccessorsMixin implements TestStatefulHandlerPrecedenceState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulHandlerPrecedenceState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -1039,8 +1027,7 @@ class _$$TestStatefulPropValidationProps with _$TestStatefulPropValidationPropsAccessorsMixin implements TestStatefulPropValidationProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulPropValidationProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -1093,8 +1080,7 @@ class _$$TestStatefulPropValidationState with _$TestStatefulPropValidationStateAccessorsMixin implements TestStatefulPropValidationState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulPropValidationState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -1177,8 +1163,7 @@ class _$$TestStatefulRedrawOnProps extends _$TestStatefulRedrawOnProps with _$TestStatefulRedrawOnPropsAccessorsMixin implements TestStatefulRedrawOnProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulRedrawOnProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -1230,8 +1215,7 @@ class _$$TestStatefulRedrawOnState extends _$TestStatefulRedrawOnState with _$TestStatefulRedrawOnStateAccessorsMixin implements TestStatefulRedrawOnState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulRedrawOnState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -1314,8 +1298,7 @@ class _$$TestStatefulStoreHandlersProps extends _$TestStatefulStoreHandlersProps with _$TestStatefulStoreHandlersPropsAccessorsMixin implements TestStatefulStoreHandlersProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulStoreHandlersProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -1367,8 +1350,7 @@ class _$$TestStatefulStoreHandlersState extends _$TestStatefulStoreHandlersState with _$TestStatefulStoreHandlersStateAccessorsMixin implements TestStatefulStoreHandlersState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestStatefulStoreHandlersState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/test/over_react/component_declaration/redux_component_test.over_react.g.dart b/test/over_react/component_declaration/redux_component_test.over_react.g.dart index 4d12a3192..9de9ee8b9 100644 --- a/test/over_react/component_declaration/redux_component_test.over_react.g.dart +++ b/test/over_react/component_declaration/redux_component_test.over_react.g.dart @@ -47,8 +47,7 @@ class _$$TestDefaultProps extends _$TestDefaultProps with _$TestDefaultPropsAccessorsMixin implements TestDefaultProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestDefaultProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -134,8 +133,7 @@ class _$$TestConnectProps extends _$TestConnectProps with _$TestConnectPropsAccessorsMixin implements TestConnectProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestConnectProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -220,8 +218,7 @@ class _$$TestPureProps extends _$TestPureProps with _$TestPurePropsAccessorsMixin implements TestPureProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestPureProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/dom/fixtures/dummy_composite_component.over_react.g.dart b/test/over_react/dom/fixtures/dummy_composite_component.over_react.g.dart index aa3918146..70e243de8 100644 --- a/test/over_react/dom/fixtures/dummy_composite_component.over_react.g.dart +++ b/test/over_react/dom/fixtures/dummy_composite_component.over_react.g.dart @@ -107,8 +107,7 @@ class _$$TestCompositeComponentProps extends _$TestCompositeComponentProps with _$TestCompositeComponentPropsAccessorsMixin implements TestCompositeComponentProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestCompositeComponentProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/util/dom_util_test.over_react.g.dart b/test/over_react/util/dom_util_test.over_react.g.dart index cede73bab..32c793026 100644 --- a/test/over_react/util/dom_util_test.over_react.g.dart +++ b/test/over_react/util/dom_util_test.over_react.g.dart @@ -46,8 +46,7 @@ class _$$DomTestProps extends _$DomTestProps with _$DomTestPropsAccessorsMixin implements DomTestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$DomTestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/util/prop_key_util_test_dart2.over_react.g.dart b/test/over_react/util/prop_key_util_test_dart2.over_react.g.dart index 84e2c29e3..d1c3198f8 100644 --- a/test/over_react/util/prop_key_util_test_dart2.over_react.g.dart +++ b/test/over_react/util/prop_key_util_test_dart2.over_react.g.dart @@ -73,8 +73,7 @@ class _$$TestProps extends _$TestProps with _$TestPropsAccessorsMixin implements TestProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TestProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/over_react/util/react_wrappers_test.dart b/test/over_react/util/react_wrappers_test.dart index 4c4385bf9..54e5eb121 100644 --- a/test/over_react/util/react_wrappers_test.dart +++ b/test/over_react/util/react_wrappers_test.dart @@ -1018,6 +1018,7 @@ main() { cloneElement(instanceWithRef, {'ref': chainedRef}) ); var component = getDartComponent(renderedInstance); + // ignore: deprecated_member_use expect(component, const TypeMatcher(), reason: 'test setup sanity check'); expect(calls, equals([ @@ -1083,6 +1084,7 @@ main() { cloneElement(instanceWithoutRef, {'ref': chainedRef}) ); var component = getDartComponent(renderedInstance); + // ignore: deprecated_member_use expect(component, const TypeMatcher(), reason: 'test setup sanity check'); expect(calls, equals([ @@ -1103,6 +1105,7 @@ main() { cloneElement(instanceWithRef, {'ref': chainedRef}) ); var component = getDartComponent(renderedInstance); + // ignore: deprecated_member_use expect(component, const TypeMatcher(), reason: 'test setup sanity check'); expect(calls, equals([ @@ -1136,6 +1139,7 @@ main() { /// Helper component for testing a Dart (react-dart) React component with cloneElement. final TestComponentFactory = react.registerComponent(() => new TestComponent()); +// ignore: deprecated_member_use class TestComponent extends react.Component { @override render() => Dom.div()(); @@ -1156,6 +1160,7 @@ class PlainObjectStyleMap { /// Helper component that renders whatever you tell it to. Necessary for rendering components with the 'ref' prop. final RenderingContainerComponentFactory = react.registerComponent(() => new RenderingContainerComponent()); +// ignore: deprecated_member_use class RenderingContainerComponent extends react.Component { @override render() => props['renderer'](); diff --git a/test/over_react_component_declaration_test.dart b/test/over_react_component_declaration_test.dart index d6be011e0..a6e728fce 100644 --- a/test/over_react_component_declaration_test.dart +++ b/test/over_react_component_declaration_test.dart @@ -49,6 +49,16 @@ import 'over_react/component_declaration/builder_integration_tests/backwards_com import 'over_react/component_declaration/builder_integration_tests/backwards_compatible/required_accessor_integration_test.dart' as backwards_compat_required_accessor_integration_test; import 'over_react/component_declaration/builder_integration_tests/backwards_compatible/stateful_component_integration_test.dart' as backwards_compat_stateful_component_integration_test; import 'over_react/component_declaration/builder_integration_tests/backwards_compatible/unassigned_prop_integration_test.dart' as backwards_compat_unassigned_prop_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/abstract_accessor_integration_test.dart' as component2_abstract_accessor_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/accessor_mixin_integration_test.dart' as component2_accessor_mixin_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/component_integration_test.dart' as component2_component_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/constant_required_accessor_integration_test.dart' as component2_constant_required_accessor_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/do_not_generate_accessor_integration_test.dart' as component2_do_not_generate_accessor_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/namespaced_accessor_integration_test.dart' as component2_namespaced_accessor_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/private_props_ddc_bug.dart' as component2_private_props_ddc_bug; +import 'over_react/component_declaration/builder_integration_tests/component2/required_accessor_integration_test.dart' as component2_required_accessor_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/stateful_component_integration_test.dart' as component2_stateful_component_integration_test; +import 'over_react/component_declaration/builder_integration_tests/component2/unassigned_prop_integration_test.dart' as component2_unassigned_prop_integration_test; main() { setClientConfiguration(); @@ -83,4 +93,15 @@ main() { backwards_compat_required_accessor_integration_test.main(); backwards_compat_stateful_component_integration_test.main(); backwards_compat_unassigned_prop_integration_test.main(); + + component2_abstract_accessor_integration_test.main(); + component2_accessor_mixin_integration_test.main(); + component2_do_not_generate_accessor_integration_test.main(); + component2_component_integration_test.main(); + component2_constant_required_accessor_integration_test.main(); + component2_private_props_ddc_bug.main(); + component2_namespaced_accessor_integration_test.main(); + component2_required_accessor_integration_test.main(); + component2_stateful_component_integration_test.main(); + component2_unassigned_prop_integration_test.main(); } diff --git a/test/test_util/one_level_wrapper.over_react.g.dart b/test/test_util/one_level_wrapper.over_react.g.dart index 96385c530..c87127fe5 100644 --- a/test/test_util/one_level_wrapper.over_react.g.dart +++ b/test/test_util/one_level_wrapper.over_react.g.dart @@ -48,8 +48,7 @@ class _$$OneLevelWrapperProps extends _$OneLevelWrapperProps with _$OneLevelWrapperPropsAccessorsMixin implements OneLevelWrapperProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$OneLevelWrapperProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test/test_util/two_level_wrapper.over_react.g.dart b/test/test_util/two_level_wrapper.over_react.g.dart index 5bc510795..7488993e3 100644 --- a/test/test_util/two_level_wrapper.over_react.g.dart +++ b/test/test_util/two_level_wrapper.over_react.g.dart @@ -48,8 +48,7 @@ class _$$TwoLevelWrapperProps extends _$TwoLevelWrapperProps with _$TwoLevelWrapperPropsAccessorsMixin implements TwoLevelWrapperProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TwoLevelWrapperProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test_fixtures/gold_output_files/backwards_compatible/basic.over_react.g.dart.goldFile b/test_fixtures/gold_output_files/backwards_compatible/basic.over_react.g.dart.goldFile index 94b585dd6..c740e96f3 100644 --- a/test_fixtures/gold_output_files/backwards_compatible/basic.over_react.g.dart.goldFile +++ b/test_fixtures/gold_output_files/backwards_compatible/basic.over_react.g.dart.goldFile @@ -133,8 +133,7 @@ class _$$BasicProps extends _$BasicProps with _$BasicPropsAccessorsMixin implements BasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test_fixtures/gold_output_files/backwards_compatible/basic_library.over_react.g.dart.goldFile b/test_fixtures/gold_output_files/backwards_compatible/basic_library.over_react.g.dart.goldFile index e2568732f..aaff4b073 100644 --- a/test_fixtures/gold_output_files/backwards_compatible/basic_library.over_react.g.dart.goldFile +++ b/test_fixtures/gold_output_files/backwards_compatible/basic_library.over_react.g.dart.goldFile @@ -144,8 +144,7 @@ class _$$BasicPartOfLibProps extends _$BasicPartOfLibProps with _$BasicPartOfLibPropsAccessorsMixin implements BasicPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -209,8 +208,7 @@ class _$$BasicPartOfLibState extends _$BasicPartOfLibState with _$BasicPartOfLibStateAccessorsMixin implements BasicPartOfLibState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -304,8 +302,7 @@ class _$$SubPartOfLibProps extends _$SubPartOfLibProps with _$SubPartOfLibPropsAccessorsMixin implements SubPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$SubPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test_fixtures/gold_output_files/basic.over_react.g.dart.goldFile b/test_fixtures/gold_output_files/basic.over_react.g.dart.goldFile index 711aefe03..2dfc7e28f 100644 --- a/test_fixtures/gold_output_files/basic.over_react.g.dart.goldFile +++ b/test_fixtures/gold_output_files/basic.over_react.g.dart.goldFile @@ -139,8 +139,7 @@ class _$$BasicProps extends _$BasicProps with _$BasicPropsAccessorsMixin implements BasicProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/test_fixtures/gold_output_files/basic_library.over_react.g.dart.goldFile b/test_fixtures/gold_output_files/basic_library.over_react.g.dart.goldFile index cce3afde3..2cf0d042f 100644 --- a/test_fixtures/gold_output_files/basic_library.over_react.g.dart.goldFile +++ b/test_fixtures/gold_output_files/basic_library.over_react.g.dart.goldFile @@ -149,8 +149,7 @@ class _$$BasicPartOfLibProps extends _$BasicPartOfLibProps with _$BasicPartOfLibPropsAccessorsMixin implements BasicPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -219,8 +218,7 @@ class _$$BasicPartOfLibState extends _$BasicPartOfLibState with _$BasicPartOfLibStateAccessorsMixin implements BasicPartOfLibState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$BasicPartOfLibState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } @@ -319,8 +317,7 @@ class _$$SubPartOfLibProps extends _$SubPartOfLibProps with _$SubPartOfLibPropsAccessorsMixin implements SubPartOfLibProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$SubPartOfLibProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/tool/reduced_test_case.dart b/tool/reduced_test_case.dart new file mode 100644 index 000000000..e69de29bb diff --git a/web/index.dart b/web/component1/index.dart similarity index 100% rename from web/index.dart rename to web/component1/index.dart diff --git a/web/component1/index.html b/web/component1/index.html new file mode 100644 index 000000000..a5a8fa153 --- /dev/null +++ b/web/component1/index.html @@ -0,0 +1,67 @@ + + + + + + over_react demo components + + + + + + + + +
+

OverReact Component Demos - UiComponent1(deprecated)

+
+
+

Button

+

Modify the source of /web/demos/button/button-examples.dart to play + around with the component rendered below.

+
+
+
+

ListGroup / ListGroupItem

+

Modify the source of /web/demos/list-group/list-group-basic.dart to play + around with the component rendered below.

+
+
+
+

Progress

+

Modify the source of /web/demos/progress/progress-basic.dart to play + around with the component rendered below.

+
+
+
+

Tag

+

Modify the source of /web/demos/tag/tag-basic.dart to play + around with the component rendered below.

+
+
+
+

ToggleButton (Checkbox)

+

Modify the source of /web/demos/toggle-button/toggle-button-checkbox.dart to play + around with the component rendered below.

+
+
+
+

ToggleButton (Radio)

+

Modify the source of /web/demos/toggle-button/toggle-button-radio.dart to play + around with the component rendered below.

+
+
+
+
+ + + + + + + + + + + + diff --git a/web/src/demo_components.dart b/web/component1/src/demo_components.dart similarity index 100% rename from web/src/demo_components.dart rename to web/component1/src/demo_components.dart diff --git a/web/src/demo_components/button.dart b/web/component1/src/demo_components/button.dart similarity index 99% rename from web/src/demo_components/button.dart rename to web/component1/src/demo_components/button.dart index 7ffaeb70d..3da1a4b69 100644 --- a/web/src/demo_components/button.dart +++ b/web/component1/src/demo_components/button.dart @@ -89,6 +89,8 @@ class ButtonComponent extends UiSt ..type = ButtonType.BUTTON ); +// T get props; +// @override render() { return renderButton(props.children); diff --git a/web/src/demo_components/button.over_react.g.dart b/web/component1/src/demo_components/button.over_react.g.dart similarity index 98% rename from web/src/demo_components/button.over_react.g.dart rename to web/component1/src/demo_components/button.over_react.g.dart index 19f4d6dc6..337ef75c7 100644 --- a/web/src/demo_components/button.over_react.g.dart +++ b/web/component1/src/demo_components/button.over_react.g.dart @@ -263,8 +263,7 @@ class _$$ButtonProps extends _$ButtonProps with _$ButtonPropsAccessorsMixin implements ButtonProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ButtonProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -313,8 +312,7 @@ class _$$ButtonState extends _$ButtonState with _$ButtonStateAccessorsMixin implements ButtonState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ButtonState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/web/src/demo_components/button_group.dart b/web/component1/src/demo_components/button_group.dart similarity index 100% rename from web/src/demo_components/button_group.dart rename to web/component1/src/demo_components/button_group.dart diff --git a/web/src/demo_components/button_group.over_react.g.dart b/web/component1/src/demo_components/button_group.over_react.g.dart similarity index 97% rename from web/src/demo_components/button_group.over_react.g.dart rename to web/component1/src/demo_components/button_group.over_react.g.dart index ad2e27a4e..f18f75832 100644 --- a/web/src/demo_components/button_group.over_react.g.dart +++ b/web/component1/src/demo_components/button_group.over_react.g.dart @@ -121,8 +121,7 @@ class _$$ButtonGroupProps extends _$ButtonGroupProps with _$ButtonGroupPropsAccessorsMixin implements ButtonGroupProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ButtonGroupProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -173,8 +172,7 @@ class _$$ButtonGroupState extends _$ButtonGroupState with _$ButtonGroupStateAccessorsMixin implements ButtonGroupState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ButtonGroupState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/web/src/demo_components/list_group.dart b/web/component1/src/demo_components/list_group.dart similarity index 100% rename from web/src/demo_components/list_group.dart rename to web/component1/src/demo_components/list_group.dart diff --git a/web/src/demo_components/list_group.over_react.g.dart b/web/component1/src/demo_components/list_group.over_react.g.dart similarity index 97% rename from web/src/demo_components/list_group.over_react.g.dart rename to web/component1/src/demo_components/list_group.over_react.g.dart index 64ca9ca41..2766861ae 100644 --- a/web/src/demo_components/list_group.over_react.g.dart +++ b/web/component1/src/demo_components/list_group.over_react.g.dart @@ -74,8 +74,7 @@ class _$$ListGroupProps extends _$ListGroupProps with _$ListGroupPropsAccessorsMixin implements ListGroupProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ListGroupProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/web/src/demo_components/list_group_item.dart b/web/component1/src/demo_components/list_group_item.dart similarity index 100% rename from web/src/demo_components/list_group_item.dart rename to web/component1/src/demo_components/list_group_item.dart diff --git a/web/src/demo_components/list_group_item.over_react.g.dart b/web/component1/src/demo_components/list_group_item.over_react.g.dart similarity index 99% rename from web/src/demo_components/list_group_item.over_react.g.dart rename to web/component1/src/demo_components/list_group_item.over_react.g.dart index 157482c0f..71ff53aa9 100644 --- a/web/src/demo_components/list_group_item.over_react.g.dart +++ b/web/component1/src/demo_components/list_group_item.over_react.g.dart @@ -325,8 +325,7 @@ class _$$ListGroupItemProps extends _$ListGroupItemProps with _$ListGroupItemPropsAccessorsMixin implements ListGroupItemProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ListGroupItemProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/web/src/demo_components/progress.dart b/web/component1/src/demo_components/progress.dart similarity index 100% rename from web/src/demo_components/progress.dart rename to web/component1/src/demo_components/progress.dart diff --git a/web/src/demo_components/progress.over_react.g.dart b/web/component1/src/demo_components/progress.over_react.g.dart similarity index 98% rename from web/src/demo_components/progress.over_react.g.dart rename to web/component1/src/demo_components/progress.over_react.g.dart index d4778e9f7..cfd1fa951 100644 --- a/web/src/demo_components/progress.over_react.g.dart +++ b/web/component1/src/demo_components/progress.over_react.g.dart @@ -308,8 +308,7 @@ class _$$ProgressProps extends _$ProgressProps with _$ProgressPropsAccessorsMixin implements ProgressProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ProgressProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -383,8 +382,7 @@ class _$$ProgressState extends _$ProgressState with _$ProgressStateAccessorsMixin implements ProgressState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ProgressState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/web/src/demo_components/tag.dart b/web/component1/src/demo_components/tag.dart similarity index 100% rename from web/src/demo_components/tag.dart rename to web/component1/src/demo_components/tag.dart diff --git a/web/src/demo_components/tag.over_react.g.dart b/web/component1/src/demo_components/tag.over_react.g.dart similarity index 97% rename from web/src/demo_components/tag.over_react.g.dart rename to web/component1/src/demo_components/tag.over_react.g.dart index a0fdc3f63..0bc089f90 100644 --- a/web/src/demo_components/tag.over_react.g.dart +++ b/web/component1/src/demo_components/tag.over_react.g.dart @@ -99,8 +99,7 @@ class _$$TagProps extends _$TagProps with _$TagPropsAccessorsMixin implements TagProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$TagProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } diff --git a/web/src/demo_components/toggle_button.dart b/web/component1/src/demo_components/toggle_button.dart similarity index 100% rename from web/src/demo_components/toggle_button.dart rename to web/component1/src/demo_components/toggle_button.dart diff --git a/web/src/demo_components/toggle_button.over_react.g.dart b/web/component1/src/demo_components/toggle_button.over_react.g.dart similarity index 98% rename from web/src/demo_components/toggle_button.over_react.g.dart rename to web/component1/src/demo_components/toggle_button.over_react.g.dart index 5bfde667c..e8495710c 100644 --- a/web/src/demo_components/toggle_button.over_react.g.dart +++ b/web/component1/src/demo_components/toggle_button.over_react.g.dart @@ -163,8 +163,7 @@ class _$$ToggleButtonProps extends _$ToggleButtonProps with _$ToggleButtonPropsAccessorsMixin implements ToggleButtonProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ToggleButtonProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -267,8 +266,7 @@ class _$$ToggleButtonState extends _$ToggleButtonState with _$ToggleButtonStateAccessorsMixin implements ToggleButtonState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ToggleButtonState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/web/src/demo_components/toggle_button_group.dart b/web/component1/src/demo_components/toggle_button_group.dart similarity index 100% rename from web/src/demo_components/toggle_button_group.dart rename to web/component1/src/demo_components/toggle_button_group.dart diff --git a/web/src/demo_components/toggle_button_group.over_react.g.dart b/web/component1/src/demo_components/toggle_button_group.over_react.g.dart similarity index 95% rename from web/src/demo_components/toggle_button_group.over_react.g.dart rename to web/component1/src/demo_components/toggle_button_group.over_react.g.dart index 8f3a3cbd3..1f515c96e 100644 --- a/web/src/demo_components/toggle_button_group.over_react.g.dart +++ b/web/component1/src/demo_components/toggle_button_group.over_react.g.dart @@ -49,8 +49,7 @@ class _$$ToggleButtonGroupProps extends _$ToggleButtonGroupProps with _$ToggleButtonGroupPropsAccessorsMixin implements ToggleButtonGroupProps { // This initializer of `_props` to an empty map, as well as the reassignment - // of `_props` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ToggleButtonGroupProps(Map backingMap) : this._props = {} { this._props = backingMap ?? {}; } @@ -102,8 +101,7 @@ class _$$ToggleButtonGroupState extends _$ToggleButtonGroupState with _$ToggleButtonGroupStateAccessorsMixin implements ToggleButtonGroupState { // This initializer of `_state` to an empty map, as well as the reassignment - // of `_state` in the constructor body is necessary to work around an unknown ddc issue. - // See for more details + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 _$$ToggleButtonGroupState(Map backingMap) : this._state = {} { this._state = backingMap ?? {}; } diff --git a/web/src/demos.dart b/web/component1/src/demos.dart similarity index 100% rename from web/src/demos.dart rename to web/component1/src/demos.dart diff --git a/web/src/demos/button/button-active.dart b/web/component1/src/demos/button/button-active.dart similarity index 100% rename from web/src/demos/button/button-active.dart rename to web/component1/src/demos/button/button-active.dart diff --git a/web/src/demos/button/button-block.dart b/web/component1/src/demos/button/button-block.dart similarity index 100% rename from web/src/demos/button/button-block.dart rename to web/component1/src/demos/button/button-block.dart diff --git a/web/src/demos/button/button-disabled.dart b/web/component1/src/demos/button/button-disabled.dart similarity index 100% rename from web/src/demos/button/button-disabled.dart rename to web/component1/src/demos/button/button-disabled.dart diff --git a/web/src/demos/button/button-examples.dart b/web/component1/src/demos/button/button-examples.dart similarity index 100% rename from web/src/demos/button/button-examples.dart rename to web/component1/src/demos/button/button-examples.dart diff --git a/web/src/demos/button/button-outline.dart b/web/component1/src/demos/button/button-outline.dart similarity index 100% rename from web/src/demos/button/button-outline.dart rename to web/component1/src/demos/button/button-outline.dart diff --git a/web/src/demos/button/button-sizes.dart b/web/component1/src/demos/button/button-sizes.dart similarity index 100% rename from web/src/demos/button/button-sizes.dart rename to web/component1/src/demos/button/button-sizes.dart diff --git a/web/src/demos/button/button-types.dart b/web/component1/src/demos/button/button-types.dart similarity index 100% rename from web/src/demos/button/button-types.dart rename to web/component1/src/demos/button/button-types.dart diff --git a/web/src/demos/button/index.dart b/web/component1/src/demos/button/index.dart similarity index 100% rename from web/src/demos/button/index.dart rename to web/component1/src/demos/button/index.dart diff --git a/web/src/demos/list-group/index.dart b/web/component1/src/demos/list-group/index.dart similarity index 100% rename from web/src/demos/list-group/index.dart rename to web/component1/src/demos/list-group/index.dart diff --git a/web/src/demos/list-group/list-group-anchors-and-buttons.dart b/web/component1/src/demos/list-group/list-group-anchors-and-buttons.dart similarity index 100% rename from web/src/demos/list-group/list-group-anchors-and-buttons.dart rename to web/component1/src/demos/list-group/list-group-anchors-and-buttons.dart diff --git a/web/src/demos/list-group/list-group-basic.dart b/web/component1/src/demos/list-group/list-group-basic.dart similarity index 100% rename from web/src/demos/list-group/list-group-basic.dart rename to web/component1/src/demos/list-group/list-group-basic.dart diff --git a/web/src/demos/list-group/list-group-contextual.dart b/web/component1/src/demos/list-group/list-group-contextual.dart similarity index 100% rename from web/src/demos/list-group/list-group-contextual.dart rename to web/component1/src/demos/list-group/list-group-contextual.dart diff --git a/web/src/demos/list-group/list-group-header.dart b/web/component1/src/demos/list-group/list-group-header.dart similarity index 100% rename from web/src/demos/list-group/list-group-header.dart rename to web/component1/src/demos/list-group/list-group-header.dart diff --git a/web/src/demos/list-group/list-group-tags.dart b/web/component1/src/demos/list-group/list-group-tags.dart similarity index 100% rename from web/src/demos/list-group/list-group-tags.dart rename to web/component1/src/demos/list-group/list-group-tags.dart diff --git a/web/src/demos/progress/index.dart b/web/component1/src/demos/progress/index.dart similarity index 100% rename from web/src/demos/progress/index.dart rename to web/component1/src/demos/progress/index.dart diff --git a/web/src/demos/progress/progress-animated-stripes.dart b/web/component1/src/demos/progress/progress-animated-stripes.dart similarity index 100% rename from web/src/demos/progress/progress-animated-stripes.dart rename to web/component1/src/demos/progress/progress-animated-stripes.dart diff --git a/web/src/demos/progress/progress-basic.dart b/web/component1/src/demos/progress/progress-basic.dart similarity index 100% rename from web/src/demos/progress/progress-basic.dart rename to web/component1/src/demos/progress/progress-basic.dart diff --git a/web/src/demos/progress/progress-contextual.dart b/web/component1/src/demos/progress/progress-contextual.dart similarity index 100% rename from web/src/demos/progress/progress-contextual.dart rename to web/component1/src/demos/progress/progress-contextual.dart diff --git a/web/src/demos/progress/progress-striped.dart b/web/component1/src/demos/progress/progress-striped.dart similarity index 100% rename from web/src/demos/progress/progress-striped.dart rename to web/component1/src/demos/progress/progress-striped.dart diff --git a/web/src/demos/tag/index.dart b/web/component1/src/demos/tag/index.dart similarity index 100% rename from web/src/demos/tag/index.dart rename to web/component1/src/demos/tag/index.dart diff --git a/web/src/demos/tag/tag-basic.dart b/web/component1/src/demos/tag/tag-basic.dart similarity index 100% rename from web/src/demos/tag/tag-basic.dart rename to web/component1/src/demos/tag/tag-basic.dart diff --git a/web/src/demos/tag/tag-contextual.dart b/web/component1/src/demos/tag/tag-contextual.dart similarity index 100% rename from web/src/demos/tag/tag-contextual.dart rename to web/component1/src/demos/tag/tag-contextual.dart diff --git a/web/src/demos/tag/tag-pills.dart b/web/component1/src/demos/tag/tag-pills.dart similarity index 100% rename from web/src/demos/tag/tag-pills.dart rename to web/component1/src/demos/tag/tag-pills.dart diff --git a/web/src/demos/toggle-button/toggle-button-checkbox.dart b/web/component1/src/demos/toggle-button/toggle-button-checkbox.dart similarity index 100% rename from web/src/demos/toggle-button/toggle-button-checkbox.dart rename to web/component1/src/demos/toggle-button/toggle-button-checkbox.dart diff --git a/web/src/demos/toggle-button/toggle-button-radio.dart b/web/component1/src/demos/toggle-button/toggle-button-radio.dart similarity index 100% rename from web/src/demos/toggle-button/toggle-button-radio.dart rename to web/component1/src/demos/toggle-button/toggle-button-radio.dart diff --git a/web/src/shared/constants.dart b/web/component1/src/shared/constants.dart similarity index 100% rename from web/src/shared/constants.dart rename to web/component1/src/shared/constants.dart diff --git a/web/src/shared/constants.over_react.g.dart b/web/component1/src/shared/constants.over_react.g.dart similarity index 100% rename from web/src/shared/constants.over_react.g.dart rename to web/component1/src/shared/constants.over_react.g.dart diff --git a/web/component2/index.dart b/web/component2/index.dart new file mode 100644 index 000000000..71dc30091 --- /dev/null +++ b/web/component2/index.dart @@ -0,0 +1,28 @@ +import 'dart:html'; + +import 'package:over_react/over_react.dart'; +import 'package:over_react/react_dom.dart' as react_dom; + +import 'src/demos.dart'; + +void main() { + setClientConfiguration(); + + react_dom.render( + buttonExamplesDemo(), querySelector('$demoMountNodeSelectorPrefix--button')); + + react_dom.render( + listGroupBasicDemo(), querySelector('$demoMountNodeSelectorPrefix--list-group')); + + react_dom.render( + progressBasicDemo(), querySelector('$demoMountNodeSelectorPrefix--progress')); + + react_dom.render( + tagBasicDemo(), querySelector('$demoMountNodeSelectorPrefix--tag')); + + react_dom.render( + checkboxToggleButtonDemo(), querySelector('$demoMountNodeSelectorPrefix--checkbox-toggle')); + + react_dom.render( + radioToggleButtonDemo(), querySelector('$demoMountNodeSelectorPrefix--radio-toggle')); +} diff --git a/web/component2/index.html b/web/component2/index.html new file mode 100644 index 000000000..7a67af318 --- /dev/null +++ b/web/component2/index.html @@ -0,0 +1,67 @@ + + + + + + over_react demo components + + + + + + + + +
+

OverReact Component Demos - UiComponent2

+
+
+

Button

+

Modify the source of /web/demos/button/button-examples.dart to play + around with the component rendered below.

+
+
+
+

ListGroup / ListGroupItem

+

Modify the source of /web/demos/list-group/list-group-basic.dart to play + around with the component rendered below.

+
+
+
+

Progress

+

Modify the source of /web/demos/progress/progress-basic.dart to play + around with the component rendered below.

+
+
+
+

Tag

+

Modify the source of /web/demos/tag/tag-basic.dart to play + around with the component rendered below.

+
+
+
+

ToggleButton (Checkbox)

+

Modify the source of /web/demos/toggle-button/toggle-button-checkbox.dart to play + around with the component rendered below.

+
+
+
+

ToggleButton (Radio)

+

Modify the source of /web/demos/toggle-button/toggle-button-radio.dart to play + around with the component rendered below.

+
+
+
+
+ + + + + + + + + + + + diff --git a/web/component2/src/demo_components.dart b/web/component2/src/demo_components.dart new file mode 100644 index 000000000..26d2dbec9 --- /dev/null +++ b/web/component2/src/demo_components.dart @@ -0,0 +1,10 @@ +export 'shared/constants.dart'; + +export 'demo_components/button.dart'; +export 'demo_components/button_group.dart'; +export 'demo_components/list_group.dart'; +export 'demo_components/list_group_item.dart'; +export 'demo_components/progress.dart'; +export 'demo_components/tag.dart'; +export 'demo_components/toggle_button_group.dart'; +export 'demo_components/toggle_button.dart'; diff --git a/web/component2/src/demo_components/button.dart b/web/component2/src/demo_components/button.dart new file mode 100644 index 000000000..7a917eabe --- /dev/null +++ b/web/component2/src/demo_components/button.dart @@ -0,0 +1,207 @@ +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'button.over_react.g.dart'; + +/// Nest one or more `Button` components within a [ListGroup] +/// to render individual items within a list. +/// +/// See: +@Factory() +UiFactory Button = _$Button; + +@Props() +class _$ButtonProps extends UiProps { + /// The skin / "context" for the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSkin.PRIMARY] + ButtonSkin skin; + + /// The size of the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSize.DEFAULT] + ButtonSize size; + + /// Whether the [Button] should appear "active". + /// + /// See: + /// + /// Default: false + bool isActive; + + /// Whether the [Button] is disabled. + /// + /// See: + /// + /// Default: false + @Accessor(key: 'disabled', keyNamespace: '') + bool isDisabled; + + /// Whether the [Button] is a block level button -- that which spans the full + /// width of its parent. + /// + /// Default: false + bool isBlock; + + /// The HTML `href` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + @Accessor(keyNamespace: '') + String href; + + /// The HTML `target` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + @Accessor(keyNamespace: '') + String target; + + /// The HTML `type` attribute value for the [Button] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [href] is not set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + ButtonType type; +} + +@State() +class _$ButtonState extends UiState {} + +@Component() +class ButtonComponent extends UiStatefulComponent2 { + @override + Map getDefaultProps() => (newProps() + ..skin = ButtonSkin.PRIMARY + ..size = ButtonSize.DEFAULT + ..isActive = false + ..isDisabled = false + ..isBlock = false + ..type = ButtonType.BUTTON + ); + +// T get props; +// + @override + render() { + return renderButton(props.children); + } + + ReactElement renderButton(dynamic children) { + BuilderOnlyUiFactory factory = buttonDomNodeFactory; + + return (factory() + ..addProps(copyUnconsumedDomProps()) + ..className = getButtonClasses().toClassName() + ..href = props.href + ..target = props.target + ..type = type + ..disabled = isAnchorLink ? null : props.isDisabled + ..addProps(ariaProps() + ..disabled = isAnchorLink ? props.isDisabled : null + ) + )(children); + } + + ClassNameBuilder getButtonClasses() { + return forwardingClassNameBuilder() + ..add('btn') + ..add('btn-block', props.isBlock) + ..add('active', isActive) + ..add('disabled', props.isDisabled) + ..add(props.skin.className) + ..add(props.size.className); + } + + BuilderOnlyUiFactory get buttonDomNodeFactory => isAnchorLink ? Dom.a : Dom.button; + + bool get isAnchorLink => props.href != null; + + bool get isActive => props.isActive; + + String get type => isAnchorLink ? null : props.type.typeName; +} + +/// Contextual skin options for a [Button] component. +class ButtonSkin extends ClassNameConstant { + const ButtonSkin._(String name, String className) : super(name, className); + + /// [className] value: 'btn-primary' + static const ButtonSkin PRIMARY = + const ButtonSkin._('PRIMARY', 'btn-primary'); + + /// [className] value: 'btn-secondary' + static const ButtonSkin SECONDARY = + const ButtonSkin._('SECONDARY', 'btn-secondary'); + + /// [className] value: 'btn-danger' + static const ButtonSkin DANGER = + const ButtonSkin._('DANGER', 'btn-danger'); + + /// [className] value: 'btn-success' + static const ButtonSkin SUCCESS = + const ButtonSkin._('SUCCESS', 'btn-success'); + + /// [className] value: 'btn-warning' + static const ButtonSkin WARNING = + const ButtonSkin._('WARNING', 'btn-warning'); + + /// [className] value: 'btn-info' + static const ButtonSkin INFO = + const ButtonSkin._('INFO', 'btn-info'); + + /// [className] value: 'btn-link' + static const ButtonSkin LINK = + const ButtonSkin._('LINK', 'btn-link'); + + /// [className] value: 'btn-outline-primary' + static const ButtonSkin PRIMARY_OUTLINE = + const ButtonSkin._('PRIMARY_OUTLINE', 'btn-outline-primary'); + + /// [className] value: 'btn-outline-secondary' + static const ButtonSkin SECONDARY_OUTLINE = + const ButtonSkin._('SECONDARY_OUTLINE', 'btn-outline-secondary'); + + /// [className] value: 'btn-outline-danger' + static const ButtonSkin DANGER_OUTLINE = + const ButtonSkin._('DANGER_OUTLINE', 'btn-outline-danger'); + + /// [className] value: 'btn-outline-success' + static const ButtonSkin SUCCESS_OUTLINE = + const ButtonSkin._('SUCCESS_OUTLINE', 'btn-outline-success'); + + /// [className] value: 'btn-outline-warning' + static const ButtonSkin WARNING_OUTLINE = + const ButtonSkin._('WARNING_OUTLINE', 'btn-outline-warning'); + + /// [className] value: 'btn-outline-info' + static const ButtonSkin INFO_OUTLINE = + const ButtonSkin._('INFO_OUTLINE', 'btn-outline-info'); +} + +/// Size options for a [Button] component. +class ButtonSize extends ClassNameConstant { + const ButtonSize._(String name, String className) : super(name, className); + + /// [className] value: '' + static const ButtonSize DEFAULT = + const ButtonSize._('DEFAULT', ''); + + /// [className] value: 'btn-lg' + static const ButtonSize LARGE = + const ButtonSize._('LARGE', 'btn-lg'); + + /// [className] value: 'btn-sm' + static const ButtonSize SMALL = + const ButtonSize._('SMALL', 'btn-sm'); +} + diff --git a/web/component2/src/demo_components/button.over_react.g.dart b/web/component2/src/demo_components/button.over_react.g.dart new file mode 100644 index 000000000..5ae39b2fc --- /dev/null +++ b/web/component2/src/demo_components/button.over_react.g.dart @@ -0,0 +1,448 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'button.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ButtonComponentFactory = registerComponent(() => new _$ButtonComponent(), + builderFactory: Button, + componentClass: ButtonComponent, + isWrapper: false, + parentType: null, + displayName: 'Button'); + +abstract class _$ButtonPropsAccessorsMixin implements _$ButtonProps { + @override + Map get props; + + /// The skin / "context" for the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSkin.PRIMARY] + /// + /// + @override + ButtonSkin get skin => + props[_$key__skin___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The skin / "context" for the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSkin.PRIMARY] + /// + /// + @override + set skin(ButtonSkin value) => props[_$key__skin___$ButtonProps] = value; + + /// The size of the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSize.DEFAULT] + /// + /// + @override + ButtonSize get size => + props[_$key__size___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The size of the [Button]. + /// + /// See: . + /// + /// Default: [ButtonSize.DEFAULT] + /// + /// + @override + set size(ButtonSize value) => props[_$key__size___$ButtonProps] = value; + + /// Whether the [Button] should appear "active". + /// + /// See: + /// + /// Default: false + /// + /// + @override + bool get isActive => + props[_$key__isActive___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [Button] should appear "active". + /// + /// See: + /// + /// Default: false + /// + /// + @override + set isActive(bool value) => props[_$key__isActive___$ButtonProps] = value; + + /// Whether the [Button] is disabled. + /// + /// See: + /// + /// Default: false + /// + /// + @override + @Accessor(key: 'disabled', keyNamespace: '') + bool get isDisabled => + props[_$key__isDisabled___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [Button] is disabled. + /// + /// See: + /// + /// Default: false + /// + /// + @override + @Accessor(key: 'disabled', keyNamespace: '') + set isDisabled(bool value) => props[_$key__isDisabled___$ButtonProps] = value; + + /// Whether the [Button] is a block level button -- that which spans the full + /// width of its parent. + /// + /// Default: false + /// + /// + @override + bool get isBlock => + props[_$key__isBlock___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [Button] is a block level button -- that which spans the full + /// width of its parent. + /// + /// Default: false + /// + /// + @override + set isBlock(bool value) => props[_$key__isBlock___$ButtonProps] = value; + + /// The HTML `href` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + /// + /// + @override + @Accessor(keyNamespace: '') + String get href => + props[_$key__href___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `href` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + /// + /// + @override + @Accessor(keyNamespace: '') + set href(String value) => props[_$key__href___$ButtonProps] = value; + + /// The HTML `target` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + /// + /// + @override + @Accessor(keyNamespace: '') + String get target => + props[_$key__target___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `target` attribute value for the [Button]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + /// + /// + @override + @Accessor(keyNamespace: '') + set target(String value) => props[_$key__target___$ButtonProps] = value; + + /// The HTML `type` attribute value for the [Button] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [href] is not set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + /// + /// + @override + ButtonType get type => + props[_$key__type___$ButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `type` attribute value for the [Button] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [href] is not set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + /// + /// + @override + set type(ButtonType value) => props[_$key__type___$ButtonProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__skin___$ButtonProps = + const PropDescriptor(_$key__skin___$ButtonProps); + static const PropDescriptor _$prop__size___$ButtonProps = + const PropDescriptor(_$key__size___$ButtonProps); + static const PropDescriptor _$prop__isActive___$ButtonProps = + const PropDescriptor(_$key__isActive___$ButtonProps); + static const PropDescriptor _$prop__isDisabled___$ButtonProps = + const PropDescriptor(_$key__isDisabled___$ButtonProps); + static const PropDescriptor _$prop__isBlock___$ButtonProps = + const PropDescriptor(_$key__isBlock___$ButtonProps); + static const PropDescriptor _$prop__href___$ButtonProps = + const PropDescriptor(_$key__href___$ButtonProps); + static const PropDescriptor _$prop__target___$ButtonProps = + const PropDescriptor(_$key__target___$ButtonProps); + static const PropDescriptor _$prop__type___$ButtonProps = + const PropDescriptor(_$key__type___$ButtonProps); + static const String _$key__skin___$ButtonProps = 'ButtonProps.skin'; + static const String _$key__size___$ButtonProps = 'ButtonProps.size'; + static const String _$key__isActive___$ButtonProps = 'ButtonProps.isActive'; + static const String _$key__isDisabled___$ButtonProps = 'disabled'; + static const String _$key__isBlock___$ButtonProps = 'ButtonProps.isBlock'; + static const String _$key__href___$ButtonProps = 'href'; + static const String _$key__target___$ButtonProps = 'target'; + static const String _$key__type___$ButtonProps = 'ButtonProps.type'; + + static const List $props = const [ + _$prop__skin___$ButtonProps, + _$prop__size___$ButtonProps, + _$prop__isActive___$ButtonProps, + _$prop__isDisabled___$ButtonProps, + _$prop__isBlock___$ButtonProps, + _$prop__href___$ButtonProps, + _$prop__target___$ButtonProps, + _$prop__type___$ButtonProps + ]; + static const List $propKeys = const [ + _$key__skin___$ButtonProps, + _$key__size___$ButtonProps, + _$key__isActive___$ButtonProps, + _$key__isDisabled___$ButtonProps, + _$key__isBlock___$ButtonProps, + _$key__href___$ButtonProps, + _$key__target___$ButtonProps, + _$key__type___$ButtonProps + ]; +} + +const PropsMeta _$metaForButtonProps = const PropsMeta( + fields: _$ButtonPropsAccessorsMixin.$props, + keys: _$ButtonPropsAccessorsMixin.$propKeys, +); + +class ButtonProps extends _$ButtonProps with _$ButtonPropsAccessorsMixin { + static const PropsMeta meta = _$metaForButtonProps; +} + +_$$ButtonProps _$Button([Map backingProps]) => backingProps == null + ? new _$$ButtonProps$JsMap(new JsBackedMap()) + : new _$$ButtonProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ButtonProps extends _$ButtonProps + with _$ButtonPropsAccessorsMixin + implements ButtonProps { + _$$ButtonProps._(); + + factory _$$ButtonProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ButtonProps$JsMap(backingMap); + } else { + return new _$$ButtonProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $ButtonComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ButtonProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ButtonProps$PlainMap extends _$$ButtonProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ButtonProps$JsMap extends _$$ButtonProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$ButtonStateAccessorsMixin implements _$ButtonState { + @override + Map get state; + + /* GENERATED CONSTANTS */ + + static const List $state = const []; + static const List $stateKeys = const []; +} + +const StateMeta _$metaForButtonState = const StateMeta( + fields: _$ButtonStateAccessorsMixin.$state, + keys: _$ButtonStateAccessorsMixin.$stateKeys, +); + +class ButtonState extends _$ButtonState with _$ButtonStateAccessorsMixin { + static const StateMeta meta = _$metaForButtonState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$ButtonState extends _$ButtonState + with _$ButtonStateAccessorsMixin + implements ButtonState { + _$$ButtonState._(); + + factory _$$ButtonState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ButtonState$JsMap(backingMap); + } else { + return new _$$ButtonState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$ButtonState$PlainMap extends _$$ButtonState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ButtonState$JsMap extends _$$ButtonState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ButtonComponent extends ButtonComponent { + _$$ButtonProps$JsMap _cachedTypedProps; + + @override + _$$ButtonProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ButtonProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ButtonProps$JsMap(backingMap); + + @override + _$$ButtonProps typedPropsFactory(Map backingMap) => + new _$$ButtonProps(backingMap); + + _$$ButtonState$JsMap _cachedTypedState; + @override + _$$ButtonState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$ButtonState$JsMap typedStateFactoryJs(JsBackedMap backingMap) => + new _$$ButtonState$JsMap(backingMap); + + @override + _$$ButtonState typedStateFactory(Map backingMap) => + new _$$ButtonState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ButtonProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForButtonProps + ]; +} diff --git a/web/component2/src/demo_components/button_group.dart b/web/component2/src/demo_components/button_group.dart new file mode 100644 index 000000000..dabb7c387 --- /dev/null +++ b/web/component2/src/demo_components/button_group.dart @@ -0,0 +1,160 @@ +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'button_group.over_react.g.dart'; + +/// Groups a series of [Button]s together on a single line. +/// +/// See: . +@Factory() +UiFactory ButtonGroup = _$ButtonGroup; + +@Props() +class _$ButtonGroupProps extends UiProps { + /// Apply a button size variation universally to every [Button] within the [ButtonGroup]. + /// + /// See: . + /// + /// Default: [ButtonGroupSize.DEFAULT] + ButtonGroupSize size; + + /// The [ButtonSkin] variation applied to every [Button] within the [ButtonGroup]. + ButtonSkin skin; + + /// Make the [Button]s within a [ButtonGroup] stack vertically. + /// + /// See: . + /// + /// Default: false + bool isVertical; +} + +@State() +class _$ButtonGroupState extends UiState {} + +@Component() +class ButtonGroupComponent + extends UiStatefulComponent2 { + @override + Map getDefaultProps() => (newProps() + ..size = ButtonGroupSize.DEFAULT + ..isVertical = false + ); + + @override + render() { + return renderButtonGroup(renderButtons()); + } + + ReactElement renderButtonGroup(dynamic children) { + var componentBuilder = Dom.div(); + + if (children.length > 1) { + componentBuilder.role = Role.group; + } + + return (componentBuilder + ..addProps(copyUnconsumedDomProps()) + ..className = getButtonGroupClasses().toClassName())(children); + } + + ClassNameBuilder getButtonGroupClasses() { + return forwardingClassNameBuilder() + ..add('btn-group', !props.isVertical) + ..add('btn-group-vertical', props.isVertical) + ..add(props.size.className); + } + + /// Renders a list of [Button]s using [renderButton]. + List renderButtons() { + List buttons = []; + + for (int index = 0; index < props.children.length; index++) { + buttons.add(renderButton(props.children[index], index)); + } + + return buttons; + } + + /// Clones the provided [child] with the props specified in [buttonPropsToAdd]. + ReactElement renderButton(dynamic child, int index) { + if (isValidButtonChild(child)) { + return cloneElement(child, buttonPropsToAdd(child, index)); + } + + print('invalid child'); + return child; + } + + /// The props that should be added when we clone the given [child] using + /// [cloneElement] via [renderButton]. + ButtonProps buttonPropsToAdd(dynamic child, int index) { + var childProps = childFactory(getProps(child)); + var childKey = getInstanceKey(child); + + return childFactory() + ..skin = props.skin ?? childProps.skin + ..key = childKey ?? index; + } + + /// Returns whether the provided [child] can be cloned using [cloneElement]. + bool isValidButtonChild(dynamic child) { + var isCloneable = false; + if (isValidElement(child)) { + if (!isComponentOfType(child, childFactory)) { + assert(ValidationUtil.warn( + 'An unexpected child type was found within this component.', + this + )); + } + + isCloneable = true; + } else if (child != null) { + assert(ValidationUtil.warn( + 'You are not using a valid ReactElement.', + this + )); + } + + return isCloneable; + } + + /// The factory expected for each child of [ButtonGroup]. + /// + /// _The factory accept [ButtonProps] as its generic parameter._ + UiFactory get childFactory => Button; +} + +/// Size options for a [ButtonGroup]s, with corresponding [className] values. +class ButtonGroupSize extends ClassNameConstant { + const ButtonGroupSize._(String name, String className) : super(name, className); + + /// [className] value: 'btn-group-sm' + static const ButtonGroupSize SMALL = const ButtonGroupSize._('SMALL', 'btn-group-sm'); + + /// [className] value: '' + static const ButtonGroupSize DEFAULT = const ButtonGroupSize._('DEFAULT', ''); + + /// [className] value: 'btn-group-lg' + static const ButtonGroupSize LARGE = const ButtonGroupSize._('LARGE', 'btn-group-lg'); +} + +/// Mapping from [ButtonSize] values to their analogous [ButtonGroupSize] values. +/// +/// __Example:__ +/// +/// @Props() +/// class MyProps extends UiProps { +/// ButtonSize size; +/// } +/// +/// @Component() +/// class MyComponent extends UiComponent2 { +/// ButtonGroupSize matchingButtonGroupSize = buttonToButtonGroupSize[props.size]; +/// } +final Map buttonToButtonGroupSize = const { + ButtonSize.SMALL: ButtonGroupSize.SMALL, + ButtonSize.DEFAULT: ButtonGroupSize.DEFAULT, + ButtonSize.LARGE: ButtonGroupSize.LARGE, +}; + diff --git a/web/component2/src/demo_components/button_group.over_react.g.dart b/web/component2/src/demo_components/button_group.over_react.g.dart new file mode 100644 index 000000000..8be42a9c7 --- /dev/null +++ b/web/component2/src/demo_components/button_group.over_react.g.dart @@ -0,0 +1,307 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'button_group.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ButtonGroupComponentFactory = registerComponent( + () => new _$ButtonGroupComponent(), + builderFactory: ButtonGroup, + componentClass: ButtonGroupComponent, + isWrapper: false, + parentType: null, + displayName: 'ButtonGroup'); + +abstract class _$ButtonGroupPropsAccessorsMixin implements _$ButtonGroupProps { + @override + Map get props; + + /// Apply a button size variation universally to every [Button] within the [ButtonGroup]. + /// + /// See: . + /// + /// Default: [ButtonGroupSize.DEFAULT] + /// + /// + @override + ButtonGroupSize get size => + props[_$key__size___$ButtonGroupProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Apply a button size variation universally to every [Button] within the [ButtonGroup]. + /// + /// See: . + /// + /// Default: [ButtonGroupSize.DEFAULT] + /// + /// + @override + set size(ButtonGroupSize value) => + props[_$key__size___$ButtonGroupProps] = value; + + /// The [ButtonSkin] variation applied to every [Button] within the [ButtonGroup]. + /// + /// + @override + ButtonSkin get skin => + props[_$key__skin___$ButtonGroupProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The [ButtonSkin] variation applied to every [Button] within the [ButtonGroup]. + /// + /// + @override + set skin(ButtonSkin value) => props[_$key__skin___$ButtonGroupProps] = value; + + /// Make the [Button]s within a [ButtonGroup] stack vertically. + /// + /// See: . + /// + /// Default: false + /// + /// + @override + bool get isVertical => + props[_$key__isVertical___$ButtonGroupProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Make the [Button]s within a [ButtonGroup] stack vertically. + /// + /// See: . + /// + /// Default: false + /// + /// + @override + set isVertical(bool value) => + props[_$key__isVertical___$ButtonGroupProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__size___$ButtonGroupProps = + const PropDescriptor(_$key__size___$ButtonGroupProps); + static const PropDescriptor _$prop__skin___$ButtonGroupProps = + const PropDescriptor(_$key__skin___$ButtonGroupProps); + static const PropDescriptor _$prop__isVertical___$ButtonGroupProps = + const PropDescriptor(_$key__isVertical___$ButtonGroupProps); + static const String _$key__size___$ButtonGroupProps = 'ButtonGroupProps.size'; + static const String _$key__skin___$ButtonGroupProps = 'ButtonGroupProps.skin'; + static const String _$key__isVertical___$ButtonGroupProps = + 'ButtonGroupProps.isVertical'; + + static const List $props = const [ + _$prop__size___$ButtonGroupProps, + _$prop__skin___$ButtonGroupProps, + _$prop__isVertical___$ButtonGroupProps + ]; + static const List $propKeys = const [ + _$key__size___$ButtonGroupProps, + _$key__skin___$ButtonGroupProps, + _$key__isVertical___$ButtonGroupProps + ]; +} + +const PropsMeta _$metaForButtonGroupProps = const PropsMeta( + fields: _$ButtonGroupPropsAccessorsMixin.$props, + keys: _$ButtonGroupPropsAccessorsMixin.$propKeys, +); + +class ButtonGroupProps extends _$ButtonGroupProps + with _$ButtonGroupPropsAccessorsMixin { + static const PropsMeta meta = _$metaForButtonGroupProps; +} + +_$$ButtonGroupProps _$ButtonGroup([Map backingProps]) => backingProps == null + ? new _$$ButtonGroupProps$JsMap(new JsBackedMap()) + : new _$$ButtonGroupProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ButtonGroupProps extends _$ButtonGroupProps + with _$ButtonGroupPropsAccessorsMixin + implements ButtonGroupProps { + _$$ButtonGroupProps._(); + + factory _$$ButtonGroupProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ButtonGroupProps$JsMap(backingMap); + } else { + return new _$$ButtonGroupProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $ButtonGroupComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ButtonGroupProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ButtonGroupProps$PlainMap extends _$$ButtonGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonGroupProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ButtonGroupProps$JsMap extends _$$ButtonGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonGroupProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$ButtonGroupStateAccessorsMixin implements _$ButtonGroupState { + @override + Map get state; + + /* GENERATED CONSTANTS */ + + static const List $state = const []; + static const List $stateKeys = const []; +} + +const StateMeta _$metaForButtonGroupState = const StateMeta( + fields: _$ButtonGroupStateAccessorsMixin.$state, + keys: _$ButtonGroupStateAccessorsMixin.$stateKeys, +); + +class ButtonGroupState extends _$ButtonGroupState + with _$ButtonGroupStateAccessorsMixin { + static const StateMeta meta = _$metaForButtonGroupState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$ButtonGroupState extends _$ButtonGroupState + with _$ButtonGroupStateAccessorsMixin + implements ButtonGroupState { + _$$ButtonGroupState._(); + + factory _$$ButtonGroupState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ButtonGroupState$JsMap(backingMap); + } else { + return new _$$ButtonGroupState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$ButtonGroupState$PlainMap extends _$$ButtonGroupState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonGroupState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ButtonGroupState$JsMap extends _$$ButtonGroupState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ButtonGroupState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ButtonGroupComponent extends ButtonGroupComponent { + _$$ButtonGroupProps$JsMap _cachedTypedProps; + + @override + _$$ButtonGroupProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ButtonGroupProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ButtonGroupProps$JsMap(backingMap); + + @override + _$$ButtonGroupProps typedPropsFactory(Map backingMap) => + new _$$ButtonGroupProps(backingMap); + + _$$ButtonGroupState$JsMap _cachedTypedState; + @override + _$$ButtonGroupState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$ButtonGroupState$JsMap typedStateFactoryJs(JsBackedMap backingMap) => + new _$$ButtonGroupState$JsMap(backingMap); + + @override + _$$ButtonGroupState typedStateFactory(Map backingMap) => + new _$$ButtonGroupState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ButtonGroupProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForButtonGroupProps + ]; +} diff --git a/web/component2/src/demo_components/list_group.dart b/web/component2/src/demo_components/list_group.dart new file mode 100644 index 000000000..ed8a40ab1 --- /dev/null +++ b/web/component2/src/demo_components/list_group.dart @@ -0,0 +1,53 @@ +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'list_group.over_react.g.dart'; + +/// Bootstrap's `ListGroup` component is flexible and powerful for +/// displaying lists of [ListGroupItem] components. +/// +/// See: +@Factory() +UiFactory ListGroup = _$ListGroup; + +@Props() +class _$ListGroupProps extends UiProps { + /// The HTML element type for the [ListGroup], specifying its + /// DOM representation when rendered. + /// + /// Default: [ListGroupElementType.DIV] + ListGroupElementType elementType; +} + +@Component() +class ListGroupComponent extends UiComponent2 { + @override + Map getDefaultProps() => (newProps() + ..elementType = ListGroupElementType.DIV + ); + + @override + render() { + var classes = forwardingClassNameBuilder() + ..add('list-group'); + + return (props.elementType.componentBuilderFactory() + ..addProps(copyUnconsumedDomProps()) + ..className = classes.toClassName() + )(props.children); + } +} + +/// Options for the [Element] that will be used when +/// rendering a [ListGroup] component. +class ListGroupElementType { + final BuilderOnlyUiFactory componentBuilderFactory; + ListGroupElementType._internal(this.componentBuilderFactory); + + /// A [Dom.ul] (HTML `
    ` element) + static final ListGroupElementType UL = new ListGroupElementType._internal(Dom.ul); + + /// A [Dom.div] (HTML `
    ` element) + static final ListGroupElementType DIV = new ListGroupElementType._internal(Dom.div); +} + diff --git a/web/component2/src/demo_components/list_group.over_react.g.dart b/web/component2/src/demo_components/list_group.over_react.g.dart new file mode 100644 index 000000000..1df392cd3 --- /dev/null +++ b/web/component2/src/demo_components/list_group.over_react.g.dart @@ -0,0 +1,167 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'list_group.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ListGroupComponentFactory = registerComponent( + () => new _$ListGroupComponent(), + builderFactory: ListGroup, + componentClass: ListGroupComponent, + isWrapper: false, + parentType: null, + displayName: 'ListGroup'); + +abstract class _$ListGroupPropsAccessorsMixin implements _$ListGroupProps { + @override + Map get props; + + /// The HTML element type for the [ListGroup], specifying its + /// DOM representation when rendered. + /// + /// Default: [ListGroupElementType.DIV] + /// + /// + @override + ListGroupElementType get elementType => + props[_$key__elementType___$ListGroupProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML element type for the [ListGroup], specifying its + /// DOM representation when rendered. + /// + /// Default: [ListGroupElementType.DIV] + /// + /// + @override + set elementType(ListGroupElementType value) => + props[_$key__elementType___$ListGroupProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__elementType___$ListGroupProps = + const PropDescriptor(_$key__elementType___$ListGroupProps); + static const String _$key__elementType___$ListGroupProps = + 'ListGroupProps.elementType'; + + static const List $props = const [ + _$prop__elementType___$ListGroupProps + ]; + static const List $propKeys = const [ + _$key__elementType___$ListGroupProps + ]; +} + +const PropsMeta _$metaForListGroupProps = const PropsMeta( + fields: _$ListGroupPropsAccessorsMixin.$props, + keys: _$ListGroupPropsAccessorsMixin.$propKeys, +); + +class ListGroupProps extends _$ListGroupProps + with _$ListGroupPropsAccessorsMixin { + static const PropsMeta meta = _$metaForListGroupProps; +} + +_$$ListGroupProps _$ListGroup([Map backingProps]) => backingProps == null + ? new _$$ListGroupProps$JsMap(new JsBackedMap()) + : new _$$ListGroupProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ListGroupProps extends _$ListGroupProps + with _$ListGroupPropsAccessorsMixin + implements ListGroupProps { + _$$ListGroupProps._(); + + factory _$$ListGroupProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ListGroupProps$JsMap(backingMap); + } else { + return new _$$ListGroupProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $ListGroupComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ListGroupProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ListGroupProps$PlainMap extends _$$ListGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ListGroupProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ListGroupProps$JsMap extends _$$ListGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ListGroupProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ListGroupComponent extends ListGroupComponent { + _$$ListGroupProps$JsMap _cachedTypedProps; + + @override + _$$ListGroupProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ListGroupProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ListGroupProps$JsMap(backingMap); + + @override + _$$ListGroupProps typedPropsFactory(Map backingMap) => + new _$$ListGroupProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ListGroupProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForListGroupProps + ]; +} diff --git a/web/component2/src/demo_components/list_group_item.dart b/web/component2/src/demo_components/list_group_item.dart new file mode 100644 index 000000000..3a93b7031 --- /dev/null +++ b/web/component2/src/demo_components/list_group_item.dart @@ -0,0 +1,247 @@ +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'list_group_item.over_react.g.dart'; + +/// Nest one or more `ListGroupItem` components within a [ListGroup] +/// to render individual items within a list. +/// +/// See: +@Factory() +UiFactory ListGroupItem = _$ListGroupItem; + +@Props() +class _$ListGroupItemProps extends UiProps { + /// The HTML element type for the [ListGroupItem], specifying its DOM + /// representation when rendered. + /// + /// Will only be used if [href] and [onClick] are both `null`. + /// + /// Default: [ListGroupItemElementType.SPAN] + ListGroupItemElementType elementType; + + /// Optional header text to display within the [ListGroupItem] above + /// the value of [children]. + /// + /// See: . + dynamic header; + + /// The size of the [header] text you desire. + /// + /// Default: [ListGroupItemHeaderElementSize.H5] + ListGroupItemHeaderElementSize headerSize; + + /// Additional props to be added to the [header] element _(if specified)_. + Map headerProps; + + /// The skin / "context" for the [ListGroupItem]. + /// + /// See: . + /// + /// Default: [ListGroupItemSkin.DEFAULT] + ListGroupItemSkin skin; + + /// Whether the [ListGroupItem] should appear "active". + /// + /// See: + /// + /// Default: false + bool isActive; + + /// Whether the [ListGroupItem] is disabled. + /// + /// See: + /// + /// Default: false + @Accessor(key: 'disabled', keyNamespace: '') + bool isDisabled; + + /// The HTML `href` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + @Accessor(keyNamespace: '') + String href; + + /// The HTML `target` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + @Accessor(keyNamespace: '') + String target; + + /// The HTML `type` attribute value for the [ListGroupItem] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [onClick] is also set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + ButtonType type; +} + +@Component() +class ListGroupItemComponent extends UiComponent2 { + @override + Map getDefaultProps() => (newProps() + ..elementType = ListGroupItemElementType.SPAN + ..skin = ListGroupItemSkin.DEFAULT + ..isActive = false + ..isDisabled = false + ..type = ButtonType.BUTTON + ..headerSize = ListGroupItemHeaderElementSize.H5 + ); + + @override + render() { + var children = props.children; + + if (props.header != null) { + children = [ + renderItemHeader(), + (Dom.p() + ..className = 'list-group-item-text' + ..key = 'item-text' + )(props.children) + ]; + } + + BuilderOnlyUiFactory factory = _getItemDomNodeFactory(); + + return (factory() + ..addProps(copyUnconsumedDomProps()) + ..className = _getItemClasses().toClassName() + ..href = props.href + ..target = props.target + ..type = _isActionItem && !_isAnchorLink ? props.type.typeName : null + ..disabled = _useDisabledAttr ? props.isDisabled : null + ..addProps(ariaProps() + ..disabled = !_useDisabledAttr ? props.isDisabled : null + ) + )(children); + } + + ReactElement renderItemHeader() { + if (props.header == null) return null; + + var headerClasses = new ClassNameBuilder.fromProps(props.headerProps) + ..add('list-group-item-heading'); + + return (props.headerSize.componentBuilderFactory() + ..addProps(props.headerProps) + ..className = headerClasses.toClassName() + ..key = 'item-header' + )(props.header); + } + + BuilderOnlyUiFactory _getItemDomNodeFactory() { + BuilderOnlyUiFactory factory; + + if (props.href != null) { + factory = Dom.a; + } else if (props.onClick != null) { + factory = Dom.button; + } else { + factory = props.elementType.componentBuilderFactory; + } + + return factory; + } + + ClassNameBuilder _getItemClasses() { + return forwardingClassNameBuilder() + ..add('list-group-item') + ..add('list-group-item-action', _isActionItem) + ..add('active', props.isActive) + ..add('disabled', props.isDisabled) + ..add(props.skin.className); + } + + bool get _useDisabledAttr => _getItemDomNodeFactory() == Dom.button; + + bool get _isActionItem => (props.href ?? props.onClick) != null; + + bool get _isAnchorLink => props.href != null; +} + +/// Contextual skin options for a [ListGroupItem] component. +class ListGroupItemSkin extends ClassNameConstant { + const ListGroupItemSkin._(String name, String className) : super(name, className); + + /// [className] value: null + static const ListGroupItemSkin DEFAULT = + const ListGroupItemSkin._('DEFAULT', null); + + /// [className] value: 'list-group-item-danger' + static const ListGroupItemSkin DANGER = + const ListGroupItemSkin._('DANGER', 'list-group-item-danger'); + + /// [className] value: 'list-group-item-success' + static const ListGroupItemSkin SUCCESS = + const ListGroupItemSkin._('SUCCESS', 'list-group-item-success'); + + /// [className] value: 'list-group-item-warning' + static const ListGroupItemSkin WARNING = + const ListGroupItemSkin._('WARNING', 'list-group-item-warning'); + + /// [className] value: 'list-group-item-info' + static const ListGroupItemSkin INFO = + const ListGroupItemSkin._('INFO', 'list-group-item-info'); +} + +/// Options for the [Element] that will be used when rendering a [ListGroupItem] component. +class ListGroupItemElementType { + final BuilderOnlyUiFactory componentBuilderFactory; + ListGroupItemElementType._internal(this.componentBuilderFactory); + + /// A [Dom.li] (HTML `
  • ` element) + /// + /// Will only be used if [ListGroupItemProps.href] and + /// [ListGroupItemProps.onClick] are both `null`. + /// + /// Only use this when the parent [ListGroup] has + /// [ListGroupProps.elementType] set to [ListGroupElementType.UL]. + static final ListGroupItemElementType LI = + new ListGroupItemElementType._internal(Dom.li); + + /// A [Dom.span] (HTML `` element) + /// + /// Will only be used if [ListGroupItemProps.href] and + /// [ListGroupItemProps.onClick] are both `null`. + static final ListGroupItemElementType SPAN = + new ListGroupItemElementType._internal(Dom.span); +} + +/// Options for the [Element] that will be used when rendering a [ListGroupItemProps.header]. +class ListGroupItemHeaderElementSize { + final BuilderOnlyUiFactory componentBuilderFactory; + ListGroupItemHeaderElementSize._internal(this.componentBuilderFactory); + + /// A [Dom.h1] (HTML `

    ` element) + static final ListGroupItemHeaderElementSize H1 = + new ListGroupItemHeaderElementSize._internal(Dom.h1); + + /// A [Dom.h2] (HTML `

    ` element) + static final ListGroupItemHeaderElementSize H2 = + new ListGroupItemHeaderElementSize._internal(Dom.h2); + + /// A [Dom.h3] (HTML `

    ` element) + static final ListGroupItemHeaderElementSize H3 = + new ListGroupItemHeaderElementSize._internal(Dom.h3); + + /// A [Dom.h4] (HTML `

    ` element) + static final ListGroupItemHeaderElementSize H4 = + new ListGroupItemHeaderElementSize._internal(Dom.h4); + + /// A [Dom.h5] (HTML `

    ` element) + static final ListGroupItemHeaderElementSize H5 = + new ListGroupItemHeaderElementSize._internal(Dom.h5); + + /// A [Dom.h6] (HTML `
    ` element) + static final ListGroupItemHeaderElementSize H6 = + new ListGroupItemHeaderElementSize._internal(Dom.h6); +} + diff --git a/web/component2/src/demo_components/list_group_item.over_react.g.dart b/web/component2/src/demo_components/list_group_item.over_react.g.dart new file mode 100644 index 000000000..45c479d71 --- /dev/null +++ b/web/component2/src/demo_components/list_group_item.over_react.g.dart @@ -0,0 +1,420 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'list_group_item.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ListGroupItemComponentFactory = registerComponent( + () => new _$ListGroupItemComponent(), + builderFactory: ListGroupItem, + componentClass: ListGroupItemComponent, + isWrapper: false, + parentType: null, + displayName: 'ListGroupItem'); + +abstract class _$ListGroupItemPropsAccessorsMixin + implements _$ListGroupItemProps { + @override + Map get props; + + /// The HTML element type for the [ListGroupItem], specifying its DOM + /// representation when rendered. + /// + /// Will only be used if [href] and [onClick] are both `null`. + /// + /// Default: [ListGroupItemElementType.SPAN] + /// + /// + @override + ListGroupItemElementType get elementType => + props[_$key__elementType___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML element type for the [ListGroupItem], specifying its DOM + /// representation when rendered. + /// + /// Will only be used if [href] and [onClick] are both `null`. + /// + /// Default: [ListGroupItemElementType.SPAN] + /// + /// + @override + set elementType(ListGroupItemElementType value) => + props[_$key__elementType___$ListGroupItemProps] = value; + + /// Optional header text to display within the [ListGroupItem] above + /// the value of [children]. + /// + /// See: . + /// + /// + @override + dynamic get header => + props[_$key__header___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Optional header text to display within the [ListGroupItem] above + /// the value of [children]. + /// + /// See: . + /// + /// + @override + set header(dynamic value) => + props[_$key__header___$ListGroupItemProps] = value; + + /// The size of the [header] text you desire. + /// + /// Default: [ListGroupItemHeaderElementSize.H5] + /// + /// + @override + ListGroupItemHeaderElementSize get headerSize => + props[_$key__headerSize___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The size of the [header] text you desire. + /// + /// Default: [ListGroupItemHeaderElementSize.H5] + /// + /// + @override + set headerSize(ListGroupItemHeaderElementSize value) => + props[_$key__headerSize___$ListGroupItemProps] = value; + + /// Additional props to be added to the [header] element _(if specified)_. + /// + /// + @override + Map get headerProps => + props[_$key__headerProps___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Additional props to be added to the [header] element _(if specified)_. + /// + /// + @override + set headerProps(Map value) => + props[_$key__headerProps___$ListGroupItemProps] = value; + + /// The skin / "context" for the [ListGroupItem]. + /// + /// See: . + /// + /// Default: [ListGroupItemSkin.DEFAULT] + /// + /// + @override + ListGroupItemSkin get skin => + props[_$key__skin___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The skin / "context" for the [ListGroupItem]. + /// + /// See: . + /// + /// Default: [ListGroupItemSkin.DEFAULT] + /// + /// + @override + set skin(ListGroupItemSkin value) => + props[_$key__skin___$ListGroupItemProps] = value; + + /// Whether the [ListGroupItem] should appear "active". + /// + /// See: + /// + /// Default: false + /// + /// + @override + bool get isActive => + props[_$key__isActive___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [ListGroupItem] should appear "active". + /// + /// See: + /// + /// Default: false + /// + /// + @override + set isActive(bool value) => + props[_$key__isActive___$ListGroupItemProps] = value; + + /// Whether the [ListGroupItem] is disabled. + /// + /// See: + /// + /// Default: false + /// + /// + @override + @Accessor(key: 'disabled', keyNamespace: '') + bool get isDisabled => + props[_$key__isDisabled___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [ListGroupItem] is disabled. + /// + /// See: + /// + /// Default: false + /// + /// + @override + @Accessor(key: 'disabled', keyNamespace: '') + set isDisabled(bool value) => + props[_$key__isDisabled___$ListGroupItemProps] = value; + + /// The HTML `href` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + /// + /// + @override + @Accessor(keyNamespace: '') + String get href => + props[_$key__href___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `href` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.href]_ + /// + /// + @override + @Accessor(keyNamespace: '') + set href(String value) => props[_$key__href___$ListGroupItemProps] = value; + + /// The HTML `target` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + /// + /// + @override + @Accessor(keyNamespace: '') + String get target => + props[_$key__target___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `target` attribute value for the [ListGroupItem]. + /// + /// If set, the item will render via [Dom.a]. + /// + /// _Proxies [DomProps.target]_ + /// + /// + @override + @Accessor(keyNamespace: '') + set target(String value) => + props[_$key__target___$ListGroupItemProps] = value; + + /// The HTML `type` attribute value for the [ListGroupItem] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [onClick] is also set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + /// + /// + @override + ButtonType get type => + props[_$key__type___$ListGroupItemProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The HTML `type` attribute value for the [ListGroupItem] when + /// rendered via [Dom.button]. + /// + /// This will only be applied if [onClick] is also set. + /// + /// _Proxies [DomProps.type]_ + /// + /// Default: [ButtonType.BUTTON] + /// + /// + @override + set type(ButtonType value) => + props[_$key__type___$ListGroupItemProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__elementType___$ListGroupItemProps = + const PropDescriptor(_$key__elementType___$ListGroupItemProps); + static const PropDescriptor _$prop__header___$ListGroupItemProps = + const PropDescriptor(_$key__header___$ListGroupItemProps); + static const PropDescriptor _$prop__headerSize___$ListGroupItemProps = + const PropDescriptor(_$key__headerSize___$ListGroupItemProps); + static const PropDescriptor _$prop__headerProps___$ListGroupItemProps = + const PropDescriptor(_$key__headerProps___$ListGroupItemProps); + static const PropDescriptor _$prop__skin___$ListGroupItemProps = + const PropDescriptor(_$key__skin___$ListGroupItemProps); + static const PropDescriptor _$prop__isActive___$ListGroupItemProps = + const PropDescriptor(_$key__isActive___$ListGroupItemProps); + static const PropDescriptor _$prop__isDisabled___$ListGroupItemProps = + const PropDescriptor(_$key__isDisabled___$ListGroupItemProps); + static const PropDescriptor _$prop__href___$ListGroupItemProps = + const PropDescriptor(_$key__href___$ListGroupItemProps); + static const PropDescriptor _$prop__target___$ListGroupItemProps = + const PropDescriptor(_$key__target___$ListGroupItemProps); + static const PropDescriptor _$prop__type___$ListGroupItemProps = + const PropDescriptor(_$key__type___$ListGroupItemProps); + static const String _$key__elementType___$ListGroupItemProps = + 'ListGroupItemProps.elementType'; + static const String _$key__header___$ListGroupItemProps = + 'ListGroupItemProps.header'; + static const String _$key__headerSize___$ListGroupItemProps = + 'ListGroupItemProps.headerSize'; + static const String _$key__headerProps___$ListGroupItemProps = + 'ListGroupItemProps.headerProps'; + static const String _$key__skin___$ListGroupItemProps = + 'ListGroupItemProps.skin'; + static const String _$key__isActive___$ListGroupItemProps = + 'ListGroupItemProps.isActive'; + static const String _$key__isDisabled___$ListGroupItemProps = 'disabled'; + static const String _$key__href___$ListGroupItemProps = 'href'; + static const String _$key__target___$ListGroupItemProps = 'target'; + static const String _$key__type___$ListGroupItemProps = + 'ListGroupItemProps.type'; + + static const List $props = const [ + _$prop__elementType___$ListGroupItemProps, + _$prop__header___$ListGroupItemProps, + _$prop__headerSize___$ListGroupItemProps, + _$prop__headerProps___$ListGroupItemProps, + _$prop__skin___$ListGroupItemProps, + _$prop__isActive___$ListGroupItemProps, + _$prop__isDisabled___$ListGroupItemProps, + _$prop__href___$ListGroupItemProps, + _$prop__target___$ListGroupItemProps, + _$prop__type___$ListGroupItemProps + ]; + static const List $propKeys = const [ + _$key__elementType___$ListGroupItemProps, + _$key__header___$ListGroupItemProps, + _$key__headerSize___$ListGroupItemProps, + _$key__headerProps___$ListGroupItemProps, + _$key__skin___$ListGroupItemProps, + _$key__isActive___$ListGroupItemProps, + _$key__isDisabled___$ListGroupItemProps, + _$key__href___$ListGroupItemProps, + _$key__target___$ListGroupItemProps, + _$key__type___$ListGroupItemProps + ]; +} + +const PropsMeta _$metaForListGroupItemProps = const PropsMeta( + fields: _$ListGroupItemPropsAccessorsMixin.$props, + keys: _$ListGroupItemPropsAccessorsMixin.$propKeys, +); + +class ListGroupItemProps extends _$ListGroupItemProps + with _$ListGroupItemPropsAccessorsMixin { + static const PropsMeta meta = _$metaForListGroupItemProps; +} + +_$$ListGroupItemProps _$ListGroupItem([Map backingProps]) => + backingProps == null + ? new _$$ListGroupItemProps$JsMap(new JsBackedMap()) + : new _$$ListGroupItemProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ListGroupItemProps extends _$ListGroupItemProps + with _$ListGroupItemPropsAccessorsMixin + implements ListGroupItemProps { + _$$ListGroupItemProps._(); + + factory _$$ListGroupItemProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ListGroupItemProps$JsMap(backingMap); + } else { + return new _$$ListGroupItemProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $ListGroupItemComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ListGroupItemProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ListGroupItemProps$PlainMap extends _$$ListGroupItemProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ListGroupItemProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ListGroupItemProps$JsMap extends _$$ListGroupItemProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ListGroupItemProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ListGroupItemComponent extends ListGroupItemComponent { + _$$ListGroupItemProps$JsMap _cachedTypedProps; + + @override + _$$ListGroupItemProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ListGroupItemProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ListGroupItemProps$JsMap(backingMap); + + @override + _$$ListGroupItemProps typedPropsFactory(Map backingMap) => + new _$$ListGroupItemProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ListGroupItemProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForListGroupItemProps + ]; +} diff --git a/web/component2/src/demo_components/progress.dart b/web/component2/src/demo_components/progress.dart new file mode 100644 index 000000000..b708d1df8 --- /dev/null +++ b/web/component2/src/demo_components/progress.dart @@ -0,0 +1,192 @@ +import 'dart:math'; + +import 'package:over_react/over_react.dart'; +part 'progress.over_react.g.dart'; + +/// Bootstrap's `Progress` component stylizes the HTML5 `` element with a +/// few extra CSS classes and some crafty browser-specific CSS. +/// +/// See: +@Factory() +UiFactory Progress = _$Progress; + +@Props() +class _$ProgressProps extends UiProps { + /// The current value of the [Progress] component. + /// + /// This value should be between the [min] and [max] values. + /// + /// Default: `0.0` + double value; + + /// The min value of the [Progress] component. + /// + /// Default: `0.0` + double min; + + /// The max value of the [Progress] component. + /// + /// Default: `100.0` + double max; + + /// The skin / "context" for the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressSkin.DEFAULT] + ProgressSkin skin; + + /// Whether to render a "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// Default: false + bool isStriped; + + /// Whether to animate the "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// __Note:__ Has no effect if [isStriped] is `false`. + /// + /// Default: false + bool isAnimated; + + /// Optionally add a caption that describes the context of the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressComponent._getPercentComplete]% + String caption; + + /// Additional props to be added to the [caption] element _(if specified)_. + Map captionProps; + + /// Whether the [caption] should be visible. + /// + /// Default: false + bool showCaption; + + /// Whether the [caption] should be appended with the value of [value]. + /// + /// Default: true + bool showPercentComplete; + + /// Additional props to be added to the [Dom.div] that wraps around the [caption] element and `` element. + Map rootNodeProps; +} + +@State() +class _$ProgressState extends UiState { + /// An autogenerated GUID, used as a fallback when [ProgressProps.id] is unspecified, and + /// saved on the state so it will persist across remounts. + /// + /// HTML id attributes are needed on `` elements for proper accessibility support, + /// so this state value ensures there's always a valid ID value to use. + String id; +} + +@Component() +class ProgressComponent extends UiStatefulComponent2 { + @override + Map getDefaultProps() => (newProps() + ..value = 0.0 + ..min = 0.0 + ..max = 100.0 + ..skin = ProgressSkin.DEFAULT + ..isStriped = false + ..isAnimated = false + ..showCaption = false + ..showPercentComplete = true + ); + + @override + Map getInitialState() => (newState() + ..id = 'progress_' + generateGuid(4) + ); + + @override + render() { + return (Dom.div()..addProps(props.rootNodeProps))( + renderCaptionNode(), + renderProgressNode(), + props.children + ); + } + + ReactElement renderProgressNode() { + return (Dom.progress() + ..addProps(copyUnconsumedDomProps()) + ..addProps(ariaProps() + ..labelledby = captionId + ) + ..className = _getProgressNodeClasses().toClassName() + ..id = id + ..value = currentValue + ..max = props.max + )(); + } + + ReactElement renderCaptionNode() { + var captionClasses = new ClassNameBuilder.fromProps(props.captionProps) + ..add('sr-only', !props.showCaption); + + var captionText = props.caption ?? ''; + + if (props.showPercentComplete) { + captionText += ' ${_getPercentComplete()}%'; + } + + return (Dom.div() + ..addProps(props.captionProps) + ..id = captionId + ..className = captionClasses.toClassName() + )(captionText); + } + + ClassNameBuilder _getProgressNodeClasses() { + return new ClassNameBuilder() + ..add('progress') + ..add('progress-striped', props.isStriped) + ..add('progress-animated', props.isAnimated) + ..add(props.skin.className); + } + + /// Get the percentage complete based on [ProgressProps.min], [ProgressProps.max] and [ProgressProps.value]. + double _getPercentComplete() { + return (props.value - props.min) / (props.max - props.min) * 100; + } + + /// Returns the value that determines the width of the progress bar + /// within the rendered [Progress] component via [DomPropsMixin.value]. + /// + /// Note that the value of the HTML `` element's value + /// attribute will never be less than the value of [ProgressProps.min]. + double get currentValue => max(props.min, props.value); + + String get id => props.id ?? state.id; + + String get captionId => '${id}_caption'; +} + +/// Contextual skin options for a [Progress] component. +class ProgressSkin extends ClassNameConstant { + const ProgressSkin._(String name, String className) : super(name, className); + + /// [className] value: '' + static const ProgressSkin DEFAULT = + const ProgressSkin._('DEFAULT', ''); + + /// [className] value: 'progress-danger' + static const ProgressSkin DANGER = + const ProgressSkin._('DANGER', 'progress-danger'); + + /// [className] value: 'progress-success' + static const ProgressSkin SUCCESS = + const ProgressSkin._('SUCCESS', 'progress-success'); + + /// [className] value: 'progress-warning' + static const ProgressSkin WARNING = + const ProgressSkin._('WARNING', 'progress-warning'); + + /// [className] value: 'progress-info' + static const ProgressSkin INFO = + const ProgressSkin._('INFO', 'progress-info'); +} + diff --git a/web/component2/src/demo_components/progress.over_react.g.dart b/web/component2/src/demo_components/progress.over_react.g.dart new file mode 100644 index 000000000..4d416753e --- /dev/null +++ b/web/component2/src/demo_components/progress.over_react.g.dart @@ -0,0 +1,517 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'progress.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ProgressComponentFactory = registerComponent( + () => new _$ProgressComponent(), + builderFactory: Progress, + componentClass: ProgressComponent, + isWrapper: false, + parentType: null, + displayName: 'Progress'); + +abstract class _$ProgressPropsAccessorsMixin implements _$ProgressProps { + @override + Map get props; + + /// The current value of the [Progress] component. + /// + /// This value should be between the [min] and [max] values. + /// + /// Default: `0.0` + /// + /// + @override + double get value => + props[_$key__value___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The current value of the [Progress] component. + /// + /// This value should be between the [min] and [max] values. + /// + /// Default: `0.0` + /// + /// + @override + set value(double value) => props[_$key__value___$ProgressProps] = value; + + /// The min value of the [Progress] component. + /// + /// Default: `0.0` + /// + /// + @override + double get min => + props[_$key__min___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The min value of the [Progress] component. + /// + /// Default: `0.0` + /// + /// + @override + set min(double value) => props[_$key__min___$ProgressProps] = value; + + /// The max value of the [Progress] component. + /// + /// Default: `100.0` + /// + /// + @override + double get max => + props[_$key__max___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The max value of the [Progress] component. + /// + /// Default: `100.0` + /// + /// + @override + set max(double value) => props[_$key__max___$ProgressProps] = value; + + /// The skin / "context" for the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressSkin.DEFAULT] + /// + /// + @override + ProgressSkin get skin => + props[_$key__skin___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The skin / "context" for the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressSkin.DEFAULT] + /// + /// + @override + set skin(ProgressSkin value) => props[_$key__skin___$ProgressProps] = value; + + /// Whether to render a "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// Default: false + /// + /// + @override + bool get isStriped => + props[_$key__isStriped___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether to render a "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// Default: false + /// + /// + @override + set isStriped(bool value) => props[_$key__isStriped___$ProgressProps] = value; + + /// Whether to animate the "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// __Note:__ Has no effect if [isStriped] is `false`. + /// + /// Default: false + /// + /// + @override + bool get isAnimated => + props[_$key__isAnimated___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether to animate the "Barber Pole" gradient stripe effect in the [Progress] component. + /// + /// __Note:__ Has no effect if [isStriped] is `false`. + /// + /// Default: false + /// + /// + @override + set isAnimated(bool value) => + props[_$key__isAnimated___$ProgressProps] = value; + + /// Optionally add a caption that describes the context of the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressComponent._getPercentComplete]% + /// + /// + @override + String get caption => + props[_$key__caption___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Optionally add a caption that describes the context of the [Progress] component. + /// + /// See: . + /// + /// Default: [ProgressComponent._getPercentComplete]% + /// + /// + @override + set caption(String value) => props[_$key__caption___$ProgressProps] = value; + + /// Additional props to be added to the [caption] element _(if specified)_. + /// + /// + @override + Map get captionProps => + props[_$key__captionProps___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Additional props to be added to the [caption] element _(if specified)_. + /// + /// + @override + set captionProps(Map value) => + props[_$key__captionProps___$ProgressProps] = value; + + /// Whether the [caption] should be visible. + /// + /// Default: false + /// + /// + @override + bool get showCaption => + props[_$key__showCaption___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [caption] should be visible. + /// + /// Default: false + /// + /// + @override + set showCaption(bool value) => + props[_$key__showCaption___$ProgressProps] = value; + + /// Whether the [caption] should be appended with the value of [value]. + /// + /// Default: true + /// + /// + @override + bool get showPercentComplete => + props[_$key__showPercentComplete___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [caption] should be appended with the value of [value]. + /// + /// Default: true + /// + /// + @override + set showPercentComplete(bool value) => + props[_$key__showPercentComplete___$ProgressProps] = value; + + /// Additional props to be added to the [Dom.div] that wraps around the [caption] element and `` element. + /// + /// + @override + Map get rootNodeProps => + props[_$key__rootNodeProps___$ProgressProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Additional props to be added to the [Dom.div] that wraps around the [caption] element and `` element. + /// + /// + @override + set rootNodeProps(Map value) => + props[_$key__rootNodeProps___$ProgressProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__value___$ProgressProps = + const PropDescriptor(_$key__value___$ProgressProps); + static const PropDescriptor _$prop__min___$ProgressProps = + const PropDescriptor(_$key__min___$ProgressProps); + static const PropDescriptor _$prop__max___$ProgressProps = + const PropDescriptor(_$key__max___$ProgressProps); + static const PropDescriptor _$prop__skin___$ProgressProps = + const PropDescriptor(_$key__skin___$ProgressProps); + static const PropDescriptor _$prop__isStriped___$ProgressProps = + const PropDescriptor(_$key__isStriped___$ProgressProps); + static const PropDescriptor _$prop__isAnimated___$ProgressProps = + const PropDescriptor(_$key__isAnimated___$ProgressProps); + static const PropDescriptor _$prop__caption___$ProgressProps = + const PropDescriptor(_$key__caption___$ProgressProps); + static const PropDescriptor _$prop__captionProps___$ProgressProps = + const PropDescriptor(_$key__captionProps___$ProgressProps); + static const PropDescriptor _$prop__showCaption___$ProgressProps = + const PropDescriptor(_$key__showCaption___$ProgressProps); + static const PropDescriptor _$prop__showPercentComplete___$ProgressProps = + const PropDescriptor(_$key__showPercentComplete___$ProgressProps); + static const PropDescriptor _$prop__rootNodeProps___$ProgressProps = + const PropDescriptor(_$key__rootNodeProps___$ProgressProps); + static const String _$key__value___$ProgressProps = 'ProgressProps.value'; + static const String _$key__min___$ProgressProps = 'ProgressProps.min'; + static const String _$key__max___$ProgressProps = 'ProgressProps.max'; + static const String _$key__skin___$ProgressProps = 'ProgressProps.skin'; + static const String _$key__isStriped___$ProgressProps = + 'ProgressProps.isStriped'; + static const String _$key__isAnimated___$ProgressProps = + 'ProgressProps.isAnimated'; + static const String _$key__caption___$ProgressProps = 'ProgressProps.caption'; + static const String _$key__captionProps___$ProgressProps = + 'ProgressProps.captionProps'; + static const String _$key__showCaption___$ProgressProps = + 'ProgressProps.showCaption'; + static const String _$key__showPercentComplete___$ProgressProps = + 'ProgressProps.showPercentComplete'; + static const String _$key__rootNodeProps___$ProgressProps = + 'ProgressProps.rootNodeProps'; + + static const List $props = const [ + _$prop__value___$ProgressProps, + _$prop__min___$ProgressProps, + _$prop__max___$ProgressProps, + _$prop__skin___$ProgressProps, + _$prop__isStriped___$ProgressProps, + _$prop__isAnimated___$ProgressProps, + _$prop__caption___$ProgressProps, + _$prop__captionProps___$ProgressProps, + _$prop__showCaption___$ProgressProps, + _$prop__showPercentComplete___$ProgressProps, + _$prop__rootNodeProps___$ProgressProps + ]; + static const List $propKeys = const [ + _$key__value___$ProgressProps, + _$key__min___$ProgressProps, + _$key__max___$ProgressProps, + _$key__skin___$ProgressProps, + _$key__isStriped___$ProgressProps, + _$key__isAnimated___$ProgressProps, + _$key__caption___$ProgressProps, + _$key__captionProps___$ProgressProps, + _$key__showCaption___$ProgressProps, + _$key__showPercentComplete___$ProgressProps, + _$key__rootNodeProps___$ProgressProps + ]; +} + +const PropsMeta _$metaForProgressProps = const PropsMeta( + fields: _$ProgressPropsAccessorsMixin.$props, + keys: _$ProgressPropsAccessorsMixin.$propKeys, +); + +class ProgressProps extends _$ProgressProps with _$ProgressPropsAccessorsMixin { + static const PropsMeta meta = _$metaForProgressProps; +} + +_$$ProgressProps _$Progress([Map backingProps]) => backingProps == null + ? new _$$ProgressProps$JsMap(new JsBackedMap()) + : new _$$ProgressProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ProgressProps extends _$ProgressProps + with _$ProgressPropsAccessorsMixin + implements ProgressProps { + _$$ProgressProps._(); + + factory _$$ProgressProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ProgressProps$JsMap(backingMap); + } else { + return new _$$ProgressProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $ProgressComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ProgressProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ProgressProps$PlainMap extends _$$ProgressProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ProgressProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ProgressProps$JsMap extends _$$ProgressProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ProgressProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$ProgressStateAccessorsMixin implements _$ProgressState { + @override + Map get state; + + /// An autogenerated GUID, used as a fallback when [ProgressProps.id] is unspecified, and + /// saved on the state so it will persist across remounts. + /// + /// HTML id attributes are needed on `` elements for proper accessibility support, + /// so this state value ensures there's always a valid ID value to use. + /// + /// + @override + String get id => + state[_$key__id___$ProgressState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// An autogenerated GUID, used as a fallback when [ProgressProps.id] is unspecified, and + /// saved on the state so it will persist across remounts. + /// + /// HTML id attributes are needed on `` elements for proper accessibility support, + /// so this state value ensures there's always a valid ID value to use. + /// + /// + @override + set id(String value) => state[_$key__id___$ProgressState] = value; + /* GENERATED CONSTANTS */ + static const StateDescriptor _$prop__id___$ProgressState = + const StateDescriptor(_$key__id___$ProgressState); + static const String _$key__id___$ProgressState = 'ProgressState.id'; + + static const List $state = const [ + _$prop__id___$ProgressState + ]; + static const List $stateKeys = const [_$key__id___$ProgressState]; +} + +const StateMeta _$metaForProgressState = const StateMeta( + fields: _$ProgressStateAccessorsMixin.$state, + keys: _$ProgressStateAccessorsMixin.$stateKeys, +); + +class ProgressState extends _$ProgressState with _$ProgressStateAccessorsMixin { + static const StateMeta meta = _$metaForProgressState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$ProgressState extends _$ProgressState + with _$ProgressStateAccessorsMixin + implements ProgressState { + _$$ProgressState._(); + + factory _$$ProgressState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ProgressState$JsMap(backingMap); + } else { + return new _$$ProgressState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$ProgressState$PlainMap extends _$$ProgressState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ProgressState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ProgressState$JsMap extends _$$ProgressState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ProgressState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ProgressComponent extends ProgressComponent { + _$$ProgressProps$JsMap _cachedTypedProps; + + @override + _$$ProgressProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ProgressProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ProgressProps$JsMap(backingMap); + + @override + _$$ProgressProps typedPropsFactory(Map backingMap) => + new _$$ProgressProps(backingMap); + + _$$ProgressState$JsMap _cachedTypedState; + @override + _$$ProgressState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$ProgressState$JsMap typedStateFactoryJs(JsBackedMap backingMap) => + new _$$ProgressState$JsMap(backingMap); + + @override + _$$ProgressState typedStateFactory(Map backingMap) => + new _$$ProgressState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ProgressProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForProgressProps + ]; +} diff --git a/web/component2/src/demo_components/tag.dart b/web/component2/src/demo_components/tag.dart new file mode 100644 index 000000000..5b6d5cb18 --- /dev/null +++ b/web/component2/src/demo_components/tag.dart @@ -0,0 +1,79 @@ +import 'package:over_react/over_react.dart'; +part 'tag.over_react.g.dart'; + +/// Bootstrap's `Tag` component renders a small and adaptive tag +/// for adding context to just about any content. +/// +/// See: +@Factory() +UiFactory Tag = _$Tag; + +@Props() +class _$TagProps extends UiProps { + /// The skin / "context" for the [Tag]. + /// + /// See: . + /// + /// Default: [TagSkin.DEFAULT] + TagSkin skin; + + /// Whether to render the [Tag] with rounded corners that make it look + /// more like a "pill" (a.k.a Bootstrap v3 "badge") + /// + /// See: . + /// + /// Default: false + bool isPill; +} + +@Component() +class TagComponent extends UiComponent2 { + @override + Map getDefaultProps() => (newProps() + ..skin = TagSkin.DEFAULT + ..isPill = false + ); + + @override + render() { + var classes = forwardingClassNameBuilder() + ..add('tag') + ..add('tag-pill', props.isPill) + ..add(props.skin.className); + + return (Dom.span() + ..addProps(copyUnconsumedDomProps()) + ..className = classes.toClassName() + )(props.children); + } +} + +/// Contextual skin options for a [Tag] component. +class TagSkin extends ClassNameConstant { + const TagSkin._(String name, String className) : super(name, className); + + /// [className] value: 'tag-default' + static const TagSkin DEFAULT = + const TagSkin._('DEFAULT', 'tag-default'); + + /// [className] value: 'tag-primary' + static const TagSkin PRIMARY = + const TagSkin._('PRIMARY', 'tag-primary'); + + /// [className] value: 'tag-danger' + static const TagSkin DANGER = + const TagSkin._('DANGER', 'tag-danger'); + + /// [className] value: 'tag-success' + static const TagSkin SUCCESS = + const TagSkin._('SUCCESS', 'tag-success'); + + /// [className] value: 'tag-warning' + static const TagSkin WARNING = + const TagSkin._('WARNING', 'tag-warning'); + + /// [className] value: 'tag-info' + static const TagSkin INFO = + const TagSkin._('INFO', 'tag-info'); +} + diff --git a/web/component2/src/demo_components/tag.over_react.g.dart b/web/component2/src/demo_components/tag.over_react.g.dart new file mode 100644 index 000000000..e3ad907c6 --- /dev/null +++ b/web/component2/src/demo_components/tag.over_react.g.dart @@ -0,0 +1,190 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tag.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $TagComponentFactory = registerComponent(() => new _$TagComponent(), + builderFactory: Tag, + componentClass: TagComponent, + isWrapper: false, + parentType: null, + displayName: 'Tag'); + +abstract class _$TagPropsAccessorsMixin implements _$TagProps { + @override + Map get props; + + /// The skin / "context" for the [Tag]. + /// + /// See: . + /// + /// Default: [TagSkin.DEFAULT] + /// + /// + @override + TagSkin get skin => + props[_$key__skin___$TagProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// The skin / "context" for the [Tag]. + /// + /// See: . + /// + /// Default: [TagSkin.DEFAULT] + /// + /// + @override + set skin(TagSkin value) => props[_$key__skin___$TagProps] = value; + + /// Whether to render the [Tag] with rounded corners that make it look + /// more like a "pill" (a.k.a Bootstrap v3 "badge") + /// + /// See: . + /// + /// Default: false + /// + /// + @override + bool get isPill => + props[_$key__isPill___$TagProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether to render the [Tag] with rounded corners that make it look + /// more like a "pill" (a.k.a Bootstrap v3 "badge") + /// + /// See: . + /// + /// Default: false + /// + /// + @override + set isPill(bool value) => props[_$key__isPill___$TagProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__skin___$TagProps = + const PropDescriptor(_$key__skin___$TagProps); + static const PropDescriptor _$prop__isPill___$TagProps = + const PropDescriptor(_$key__isPill___$TagProps); + static const String _$key__skin___$TagProps = 'TagProps.skin'; + static const String _$key__isPill___$TagProps = 'TagProps.isPill'; + + static const List $props = const [ + _$prop__skin___$TagProps, + _$prop__isPill___$TagProps + ]; + static const List $propKeys = const [ + _$key__skin___$TagProps, + _$key__isPill___$TagProps + ]; +} + +const PropsMeta _$metaForTagProps = const PropsMeta( + fields: _$TagPropsAccessorsMixin.$props, + keys: _$TagPropsAccessorsMixin.$propKeys, +); + +class TagProps extends _$TagProps with _$TagPropsAccessorsMixin { + static const PropsMeta meta = _$metaForTagProps; +} + +_$$TagProps _$Tag([Map backingProps]) => backingProps == null + ? new _$$TagProps$JsMap(new JsBackedMap()) + : new _$$TagProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$TagProps extends _$TagProps + with _$TagPropsAccessorsMixin + implements TagProps { + _$$TagProps._(); + + factory _$$TagProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$TagProps$JsMap(backingMap); + } else { + return new _$$TagProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => $TagComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'TagProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$TagProps$PlainMap extends _$$TagProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$TagProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$TagProps$JsMap extends _$$TagProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$TagProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$TagComponent extends TagComponent { + _$$TagProps$JsMap _cachedTypedProps; + + @override + _$$TagProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$TagProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$TagProps$JsMap(backingMap); + + @override + _$$TagProps typedPropsFactory(Map backingMap) => new _$$TagProps(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$TagProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [_$metaForTagProps]; +} diff --git a/web/component2/src/demo_components/toggle_button.dart b/web/component2/src/demo_components/toggle_button.dart new file mode 100644 index 000000000..2113252fa --- /dev/null +++ b/web/component2/src/demo_components/toggle_button.dart @@ -0,0 +1,217 @@ +import 'dart:html'; + +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'toggle_button.over_react.g.dart'; + +/// Use [ToggleButton]s in order to render functional `` +/// or `` elements that look like a [Button]. +/// +/// See: +@Factory() +UiFactory ToggleButton = _$ToggleButton; + +@Props() +class _$ToggleButtonProps extends ButtonProps with + AbstractInputPropsMixin { + /// Whether the `` rendered by the [ToggleButton] should have focus upon mounting. + /// + /// _Proxies [DomProps.autoFocus]._ + /// + /// Default: `false` + @Accessor(keyNamespace: '') + bool autoFocus; + + /// Whether the [ToggleButton] is checked by default. + /// + /// Setting this without the setting the [checked] prop to will make the + /// [ToggleButton] _uncontrolled_; it will initially render checked or unchecked + /// depending on the value of this prop, and then update itself automatically + /// in response to user input, like a normal HTML input. + /// + /// Related: [checked] + /// + /// _Proxies [DomProps.defaultChecked]._ + /// + /// See: . + @Accessor(keyNamespace: '') + bool defaultChecked; + + /// Whether the [ToggleButton] is checked. + /// + /// Setting this will make the [ToggleButton] _controlled_; it will not update + /// automatically in response to user input, but instead will always render + /// checked or unchecked depending on the value of this prop. + /// + /// Related: [defaultChecked] + /// + /// _Proxies [DomProps.checked]._ + /// + /// See: . + @Accessor(keyNamespace: '') + bool checked; +} + +@State() +class _$ToggleButtonState extends ButtonState with + AbstractInputStateMixin { + /// Tracks if the [ToggleButton] is focused. Determines whether to render with the `js-focus` CSS + /// class. + /// + /// Initial: [ToggleButtonProps.autoFocus] + bool isFocused; + + /// Tracks if the [ToggleButton] input is `checked`. Determines whether to render with the `active` CSS class. + /// + /// Initial: [ToggleButtonProps.checked] `??` [ToggleButtonProps.defaultChecked] `?? false` + bool isChecked; +} + +@Component(subtypeOf: ButtonComponent) +class ToggleButtonComponent extends ButtonComponent { + // Refs + + /// A reference to the [Dom.input] rendered via [renderInput] within the [ToggleButton]. + InputElement inputRef; + + @override + Map getDefaultProps() => (newProps() + ..addProps(super.getDefaultProps()) + ..toggleType = ToggleBehaviorType.CHECKBOX + ); + + @override + Map getInitialState() => (newState() + ..id = 'toggle_button_' + generateGuid() + ..isFocused = props.autoFocus + ..isChecked = props.checked ?? props.defaultChecked ?? false + ); + + @override + get consumedProps => const [ + ToggleButtonProps.meta, + ButtonProps.meta, + AbstractInputPropsMixin.meta, + ]; + + @override + void componentWillMount() { + super.componentWillMount(); + + _validateProps(props); + } + + @override + void componentWillReceiveProps(Map newProps) { + super.componentWillReceiveProps(newProps); + var tNewProps = typedPropsFactory(newProps); + + _validateProps(tNewProps); + + if (tNewProps.checked != null && props.checked != tNewProps.checked) { + setState(newState()..isChecked = tNewProps.checked); + } + } + + @override + render() { + return renderButton( + [ + renderInput(), + props.children + ] + ); + } + + ReactElement renderInput() { + var builder = Dom.input() + ..type = props.toggleType.typeName + ..id = id + ..name = props.name + ..tabIndex = props.tabIndex + ..disabled = props.isDisabled + ..autoFocus = props.autoFocus + ..onChange = props.onChange + ..onClick = props.onClick + ..style = makeInputNodeInvisible + ..ref = (ref) { inputRef = ref; } + ..key = 'input'; + + // ******************************************************** + // + // React JS 15.0 Workarounds + // + // [1] Starting from React 15.0, the checked/defaultChecked + // props should not be set with a cascading setter + // because it will recognize the null as a "clear input" + // rather than a request to make the input controlled + // vs uncontrolled. + // + // [2] React 15.0 introduced a bug that warns when setting + // value to null on an input even if that input is of + // type radio or checkbox. This comes from treating + // setting value as a controlled input even when it + // should not. + // + // See: https://github.com/facebook/react/issues/6779 + // + // ******************************************************** + + if (props.defaultChecked != null) builder.defaultChecked = state.isChecked; // [1] + if (props.checked != null) builder.checked = state.isChecked; // [1] + if (props.value != null) builder.value = props.value; // [2] + + return builder(); + } + + /// Returns a map of inline CSS styles to be applied to the HTML `` node. + /// + /// These styles are a workaround to hide the input in an a11y-friendly manner since + /// the bootstrap styles we are using for the demo components uses an HTML attribute + /// CSS selector that we do not want to use since we're demoing how to build a stateful + /// toggle button with OverReact, not with Bootstrap's jQuery plugin data-api hook. + /// + /// In an actual implementation, you would want to add a unique class to the root of this + /// component, and add these styles in your app / component library stylesheet. + Map get makeInputNodeInvisible => { + 'position': 'absolute', + 'clip': 'rect(0,0,0,0)', + 'pointerEvents': 'none' + }; + + /// Checks the `` element to ensure that [ToggleButtonState.isChecked] + /// matches the value of the [InputElement.checked] attribute. + /// + /// Does not refresh the state if [ToggleButtonProps.checked] is not null + /// (the component is a "controlled" component). + void refreshState() { + if (!_isControlled) setState(newState()..isChecked = inputRef.checked); + } + + void _validateProps(ToggleButtonProps props) { + assert( + (props.toggleType == ToggleBehaviorType.RADIO && props.name != null) || + props.toggleType == ToggleBehaviorType.CHECKBOX + ); + } + + /// Used to check if the `input` element is controlled or not. + bool get _isControlled => props.checked != null; + + @override + bool get isActive => state.isChecked; + + @override + String get type => null; + + @override + BuilderOnlyUiFactory get buttonDomNodeFactory => Dom.label; + + /// The id to use for a [ToggleButton]. + /// + /// Attempts to use [AbstractInputPropsMixin.id] _(specified by the consumer)_, falling back to + /// [AbstractInputStateMixin.id] _(auto-generated)_. + String get id => props.id ?? state.id; +} + diff --git a/web/component2/src/demo_components/toggle_button.over_react.g.dart b/web/component2/src/demo_components/toggle_button.over_react.g.dart new file mode 100644 index 000000000..38e715520 --- /dev/null +++ b/web/component2/src/demo_components/toggle_button.over_react.g.dart @@ -0,0 +1,401 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'toggle_button.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ToggleButtonComponentFactory = + registerComponent(() => new _$ToggleButtonComponent(), + builderFactory: ToggleButton, + componentClass: ToggleButtonComponent, + isWrapper: false, + parentType: $ButtonComponentFactory, + /* from `subtypeOf: ButtonComponent` */ + displayName: 'ToggleButton'); + +abstract class _$ToggleButtonPropsAccessorsMixin + implements _$ToggleButtonProps { + @override + Map get props; + + /// Whether the `` rendered by the [ToggleButton] should have focus upon mounting. + /// + /// _Proxies [DomProps.autoFocus]._ + /// + /// Default: `false` + /// + /// + @override + @Accessor(keyNamespace: '') + bool get autoFocus => + props[_$key__autoFocus___$ToggleButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the `` rendered by the [ToggleButton] should have focus upon mounting. + /// + /// _Proxies [DomProps.autoFocus]._ + /// + /// Default: `false` + /// + /// + @override + @Accessor(keyNamespace: '') + set autoFocus(bool value) => + props[_$key__autoFocus___$ToggleButtonProps] = value; + + /// Whether the [ToggleButton] is checked by default. + /// + /// Setting this without the setting the [checked] prop to will make the + /// [ToggleButton] _uncontrolled_; it will initially render checked or unchecked + /// depending on the value of this prop, and then update itself automatically + /// in response to user input, like a normal HTML input. + /// + /// Related: [checked] + /// + /// _Proxies [DomProps.defaultChecked]._ + /// + /// See: . + /// + /// + @override + @Accessor(keyNamespace: '') + bool get defaultChecked => + props[_$key__defaultChecked___$ToggleButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [ToggleButton] is checked by default. + /// + /// Setting this without the setting the [checked] prop to will make the + /// [ToggleButton] _uncontrolled_; it will initially render checked or unchecked + /// depending on the value of this prop, and then update itself automatically + /// in response to user input, like a normal HTML input. + /// + /// Related: [checked] + /// + /// _Proxies [DomProps.defaultChecked]._ + /// + /// See: . + /// + /// + @override + @Accessor(keyNamespace: '') + set defaultChecked(bool value) => + props[_$key__defaultChecked___$ToggleButtonProps] = value; + + /// Whether the [ToggleButton] is checked. + /// + /// Setting this will make the [ToggleButton] _controlled_; it will not update + /// automatically in response to user input, but instead will always render + /// checked or unchecked depending on the value of this prop. + /// + /// Related: [defaultChecked] + /// + /// _Proxies [DomProps.checked]._ + /// + /// See: . + /// + /// + @override + @Accessor(keyNamespace: '') + bool get checked => + props[_$key__checked___$ToggleButtonProps] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Whether the [ToggleButton] is checked. + /// + /// Setting this will make the [ToggleButton] _controlled_; it will not update + /// automatically in response to user input, but instead will always render + /// checked or unchecked depending on the value of this prop. + /// + /// Related: [defaultChecked] + /// + /// _Proxies [DomProps.checked]._ + /// + /// See: . + /// + /// + @override + @Accessor(keyNamespace: '') + set checked(bool value) => props[_$key__checked___$ToggleButtonProps] = value; + /* GENERATED CONSTANTS */ + static const PropDescriptor _$prop__autoFocus___$ToggleButtonProps = + const PropDescriptor(_$key__autoFocus___$ToggleButtonProps); + static const PropDescriptor _$prop__defaultChecked___$ToggleButtonProps = + const PropDescriptor(_$key__defaultChecked___$ToggleButtonProps); + static const PropDescriptor _$prop__checked___$ToggleButtonProps = + const PropDescriptor(_$key__checked___$ToggleButtonProps); + static const String _$key__autoFocus___$ToggleButtonProps = 'autoFocus'; + static const String _$key__defaultChecked___$ToggleButtonProps = + 'defaultChecked'; + static const String _$key__checked___$ToggleButtonProps = 'checked'; + + static const List $props = const [ + _$prop__autoFocus___$ToggleButtonProps, + _$prop__defaultChecked___$ToggleButtonProps, + _$prop__checked___$ToggleButtonProps + ]; + static const List $propKeys = const [ + _$key__autoFocus___$ToggleButtonProps, + _$key__defaultChecked___$ToggleButtonProps, + _$key__checked___$ToggleButtonProps + ]; +} + +const PropsMeta _$metaForToggleButtonProps = const PropsMeta( + fields: _$ToggleButtonPropsAccessorsMixin.$props, + keys: _$ToggleButtonPropsAccessorsMixin.$propKeys, +); + +class ToggleButtonProps extends _$ToggleButtonProps + with _$ToggleButtonPropsAccessorsMixin { + static const PropsMeta meta = _$metaForToggleButtonProps; +} + +_$$ToggleButtonProps _$ToggleButton([Map backingProps]) => backingProps == null + ? new _$$ToggleButtonProps$JsMap(new JsBackedMap()) + : new _$$ToggleButtonProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ToggleButtonProps extends _$ToggleButtonProps + with _$ToggleButtonPropsAccessorsMixin + implements ToggleButtonProps { + _$$ToggleButtonProps._(); + + factory _$$ToggleButtonProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ToggleButtonProps$JsMap(backingMap); + } else { + return new _$$ToggleButtonProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $ToggleButtonComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ToggleButtonProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ToggleButtonProps$PlainMap extends _$$ToggleButtonProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ToggleButtonProps$JsMap extends _$$ToggleButtonProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$ToggleButtonStateAccessorsMixin + implements _$ToggleButtonState { + @override + Map get state; + + /// Tracks if the [ToggleButton] is focused. Determines whether to render with the `js-focus` CSS + /// class. + /// + /// Initial: [ToggleButtonProps.autoFocus] + /// + /// + @override + bool get isFocused => + state[_$key__isFocused___$ToggleButtonState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Tracks if the [ToggleButton] is focused. Determines whether to render with the `js-focus` CSS + /// class. + /// + /// Initial: [ToggleButtonProps.autoFocus] + /// + /// + @override + set isFocused(bool value) => + state[_$key__isFocused___$ToggleButtonState] = value; + + /// Tracks if the [ToggleButton] input is `checked`. Determines whether to render with the `active` CSS class. + /// + /// Initial: [ToggleButtonProps.checked] `??` [ToggleButtonProps.defaultChecked] `?? false` + /// + /// + @override + bool get isChecked => + state[_$key__isChecked___$ToggleButtonState] ?? + null; // Add ` ?? null` to workaround DDC bug: ; + /// Tracks if the [ToggleButton] input is `checked`. Determines whether to render with the `active` CSS class. + /// + /// Initial: [ToggleButtonProps.checked] `??` [ToggleButtonProps.defaultChecked] `?? false` + /// + /// + @override + set isChecked(bool value) => + state[_$key__isChecked___$ToggleButtonState] = value; + /* GENERATED CONSTANTS */ + static const StateDescriptor _$prop__isFocused___$ToggleButtonState = + const StateDescriptor(_$key__isFocused___$ToggleButtonState); + static const StateDescriptor _$prop__isChecked___$ToggleButtonState = + const StateDescriptor(_$key__isChecked___$ToggleButtonState); + static const String _$key__isFocused___$ToggleButtonState = + 'ToggleButtonState.isFocused'; + static const String _$key__isChecked___$ToggleButtonState = + 'ToggleButtonState.isChecked'; + + static const List $state = const [ + _$prop__isFocused___$ToggleButtonState, + _$prop__isChecked___$ToggleButtonState + ]; + static const List $stateKeys = const [ + _$key__isFocused___$ToggleButtonState, + _$key__isChecked___$ToggleButtonState + ]; +} + +const StateMeta _$metaForToggleButtonState = const StateMeta( + fields: _$ToggleButtonStateAccessorsMixin.$state, + keys: _$ToggleButtonStateAccessorsMixin.$stateKeys, +); + +class ToggleButtonState extends _$ToggleButtonState + with _$ToggleButtonStateAccessorsMixin { + static const StateMeta meta = _$metaForToggleButtonState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$ToggleButtonState extends _$ToggleButtonState + with _$ToggleButtonStateAccessorsMixin + implements ToggleButtonState { + _$$ToggleButtonState._(); + + factory _$$ToggleButtonState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ToggleButtonState$JsMap(backingMap); + } else { + return new _$$ToggleButtonState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$ToggleButtonState$PlainMap extends _$$ToggleButtonState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ToggleButtonState$JsMap extends _$$ToggleButtonState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ToggleButtonComponent extends ToggleButtonComponent { + _$$ToggleButtonProps$JsMap _cachedTypedProps; + + @override + _$$ToggleButtonProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ToggleButtonProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ToggleButtonProps$JsMap(backingMap); + + @override + _$$ToggleButtonProps typedPropsFactory(Map backingMap) => + new _$$ToggleButtonProps(backingMap); + + _$$ToggleButtonState$JsMap _cachedTypedState; + @override + _$$ToggleButtonState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$ToggleButtonState$JsMap typedStateFactoryJs(JsBackedMap backingMap) => + new _$$ToggleButtonState$JsMap(backingMap); + + @override + _$$ToggleButtonState typedStateFactory(Map backingMap) => + new _$$ToggleButtonState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ToggleButtonProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForToggleButtonProps + ]; +} diff --git a/web/component2/src/demo_components/toggle_button_group.dart b/web/component2/src/demo_components/toggle_button_group.dart new file mode 100644 index 000000000..91d6b9afe --- /dev/null +++ b/web/component2/src/demo_components/toggle_button_group.dart @@ -0,0 +1,98 @@ +import 'package:over_react/over_react.dart'; + +import '../demo_components.dart'; +part 'toggle_button_group.over_react.g.dart'; + +/// A specialized [ButtonGroup] component that will surround one or more child +/// [ToggleButton] components so that a single shared [ToggleButtonGroupProps.name] +/// value can be applied to the aforementioned children via [cloneElement]. +/// +/// __Renders HTML Markup:__ +/// +///
    +/// +///
    +///
    +/// {props.children} +///
    +///
    +///
    +/// +/// See: +@Factory() +UiFactory ToggleButtonGroup = _$ToggleButtonGroup; + +@Props() +class _$ToggleButtonGroupProps extends ButtonGroupProps with + AbstractInputPropsMixin {} + +@State() +class _$ToggleButtonGroupState extends ButtonGroupState with + AbstractInputStateMixin {} + +@Component(subtypeOf: ButtonGroupComponent) +class ToggleButtonGroupComponent extends ButtonGroupComponent { + // Refs + + Map _toggleButtonRefs = {}; + + /// The name to use for all children of a [ToggleButtonGroup]. + /// + /// Attempts to use [ToggleButtonGroupProps.name] _(specified by the consumer)_, falling back to + /// [ToggleButtonGroupState.name] _(auto-generated)_. + String get name => props.name ?? state.name; + + @override + Map getDefaultProps() => (newProps() + ..addProps(super.getDefaultProps()) + ..toggleType = ToggleBehaviorType.CHECKBOX + ); + + @override + Map getInitialState() => (newState() + ..addAll(super.getInitialState()) + ..name = 'toggle_button_group_' + generateGuid() + ); + + @override + get consumedProps => const [ + ToggleButtonGroupProps.meta, + ]; + + /// The props that should be added when we clone the given [child] using + /// [cloneElement] via [renderButton]. + @override + ToggleButtonProps buttonPropsToAdd(dynamic child, int index) { + var childProps = childFactory(getProps(child)); + + ButtonProps superPropsToAdd = super.buttonPropsToAdd(child, index); + + return childFactory() + ..addProps(superPropsToAdd) + ..name = name + ..toggleType = props.toggleType + ..onChange = formEventCallbacks.chain(props.onChange, _handleOnChange) + ..value = childProps.value ?? index + ..ref = chainRef(child, (ref) { _toggleButtonRefs[index] = ref; }); + } + + @override + ClassNameBuilder getButtonGroupClasses() { + return super.getButtonGroupClasses() + ..add('btn-toggle-group'); + } + + /// The handler for when one of the children of the [ToggleButtonGroup] is changed or unchecked + void _handleOnChange(SyntheticFormEvent event) { + _toggleButtonRefs.values.forEach((childComponent) { + if (childComponent is ToggleButtonComponent) childComponent.refreshState(); + }); + } + + /// The factory expected for each child of [ToggleButtonGroup]. + @override + UiFactory get childFactory => ToggleButton; +} + diff --git a/web/component2/src/demo_components/toggle_button_group.over_react.g.dart b/web/component2/src/demo_components/toggle_button_group.over_react.g.dart new file mode 100644 index 000000000..a5bb05ccf --- /dev/null +++ b/web/component2/src/demo_components/toggle_button_group.over_react.g.dart @@ -0,0 +1,237 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'toggle_button_group.dart'; + +// ************************************************************************** +// OverReactGenerator +// ************************************************************************** + +// React component factory implementation. +// +// Registers component implementation and links type meta to builder factory. +final $ToggleButtonGroupComponentFactory = + registerComponent(() => new _$ToggleButtonGroupComponent(), + builderFactory: ToggleButtonGroup, + componentClass: ToggleButtonGroupComponent, + isWrapper: false, + parentType: $ButtonGroupComponentFactory, + /* from `subtypeOf: ButtonGroupComponent` */ + displayName: 'ToggleButtonGroup'); + +abstract class _$ToggleButtonGroupPropsAccessorsMixin + implements _$ToggleButtonGroupProps { + @override + Map get props; + + /* GENERATED CONSTANTS */ + + static const List $props = const []; + static const List $propKeys = const []; +} + +const PropsMeta _$metaForToggleButtonGroupProps = const PropsMeta( + fields: _$ToggleButtonGroupPropsAccessorsMixin.$props, + keys: _$ToggleButtonGroupPropsAccessorsMixin.$propKeys, +); + +class ToggleButtonGroupProps extends _$ToggleButtonGroupProps + with _$ToggleButtonGroupPropsAccessorsMixin { + static const PropsMeta meta = _$metaForToggleButtonGroupProps; +} + +_$$ToggleButtonGroupProps _$ToggleButtonGroup([Map backingProps]) => + backingProps == null + ? new _$$ToggleButtonGroupProps$JsMap(new JsBackedMap()) + : new _$$ToggleButtonGroupProps(backingProps); + +// Concrete props implementation. +// +// Implements constructor and backing map, and links up to generated component factory. +abstract class _$$ToggleButtonGroupProps extends _$ToggleButtonGroupProps + with _$ToggleButtonGroupPropsAccessorsMixin + implements ToggleButtonGroupProps { + _$$ToggleButtonGroupProps._(); + + factory _$$ToggleButtonGroupProps(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ToggleButtonGroupProps$JsMap(backingMap); + } else { + return new _$$ToggleButtonGroupProps$PlainMap(backingMap); + } + } + + /// Let [UiProps] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The [ReactComponentFactory] associated with the component built by this class. + @override + ReactComponentFactoryProxy get componentFactory => + $ToggleButtonGroupComponentFactory; + + /// The default namespace for the prop getters/setters generated for this class. + @override + String get propKeyNamespace => 'ToggleButtonGroupProps.'; +} + +// Concrete props implementation that can be backed by any [Map]. +class _$$ToggleButtonGroupProps$PlainMap extends _$$ToggleButtonGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonGroupProps$PlainMap(Map backingMap) + : this._props = {}, + super._() { + this._props = backingMap ?? {}; + } + + /// The backing props map proxied by this class. + @override + Map get props => _props; + Map _props; +} + +// Concrete props implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ToggleButtonGroupProps$JsMap extends _$$ToggleButtonGroupProps { + // This initializer of `_props` to an empty map, as well as the reassignment + // of `_props` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonGroupProps$JsMap(JsBackedMap backingMap) + : this._props = new JsBackedMap(), + super._() { + this._props = backingMap ?? new JsBackedMap(); + } + + /// The backing props map proxied by this class. + @override + JsBackedMap get props => _props; + JsBackedMap _props; +} + +abstract class _$ToggleButtonGroupStateAccessorsMixin + implements _$ToggleButtonGroupState { + @override + Map get state; + + /* GENERATED CONSTANTS */ + + static const List $state = const []; + static const List $stateKeys = const []; +} + +const StateMeta _$metaForToggleButtonGroupState = const StateMeta( + fields: _$ToggleButtonGroupStateAccessorsMixin.$state, + keys: _$ToggleButtonGroupStateAccessorsMixin.$stateKeys, +); + +class ToggleButtonGroupState extends _$ToggleButtonGroupState + with _$ToggleButtonGroupStateAccessorsMixin { + static const StateMeta meta = _$metaForToggleButtonGroupState; +} + +// Concrete state implementation. +// +// Implements constructor and backing map. +abstract class _$$ToggleButtonGroupState extends _$ToggleButtonGroupState + with _$ToggleButtonGroupStateAccessorsMixin + implements ToggleButtonGroupState { + _$$ToggleButtonGroupState._(); + + factory _$$ToggleButtonGroupState(Map backingMap) { + if (backingMap is JsBackedMap) { + return new _$$ToggleButtonGroupState$JsMap(backingMap); + } else { + return new _$$ToggleButtonGroupState$PlainMap(backingMap); + } + } + + /// Let [UiState] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; +} + +// Concrete state implementation that can be backed by any [Map]. +class _$$ToggleButtonGroupState$PlainMap extends _$$ToggleButtonGroupState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonGroupState$PlainMap(Map backingMap) + : this._state = {}, + super._() { + this._state = backingMap ?? {}; + } + + /// The backing state map proxied by this class. + @override + Map get state => _state; + Map _state; +} + +// Concrete state implementation that can only be backed by [JsMap], +// allowing dart2js to compile more optimal code for key-value pair reads/writes. +class _$$ToggleButtonGroupState$JsMap extends _$$ToggleButtonGroupState { + // This initializer of `_state` to an empty map, as well as the reassignment + // of `_state` in the constructor body is necessary to work around a DDC bug: https://github.com/dart-lang/sdk/issues/36217 + _$$ToggleButtonGroupState$JsMap(JsBackedMap backingMap) + : this._state = new JsBackedMap(), + super._() { + this._state = backingMap ?? new JsBackedMap(); + } + + /// The backing state map proxied by this class. + @override + JsBackedMap get state => _state; + JsBackedMap _state; +} + +// Concrete component implementation mixin. +// +// Implements typed props/state factories, defaults `consumedPropKeys` to the keys +// generated for the associated props class. +class _$ToggleButtonGroupComponent extends ToggleButtonGroupComponent { + _$$ToggleButtonGroupProps$JsMap _cachedTypedProps; + + @override + _$$ToggleButtonGroupProps$JsMap get props => _cachedTypedProps; + + @override + set props(Map value) { + super.props = value; + _cachedTypedProps = typedPropsFactoryJs(value); + } + + @override + _$$ToggleButtonGroupProps$JsMap typedPropsFactoryJs(JsBackedMap backingMap) => + new _$$ToggleButtonGroupProps$JsMap(backingMap); + + @override + _$$ToggleButtonGroupProps typedPropsFactory(Map backingMap) => + new _$$ToggleButtonGroupProps(backingMap); + + _$$ToggleButtonGroupState$JsMap _cachedTypedState; + @override + _$$ToggleButtonGroupState$JsMap get state => _cachedTypedState; + + @override + set state(Map value) { + super.state = value; + _cachedTypedState = typedStateFactoryJs(value); + } + + @override + _$$ToggleButtonGroupState$JsMap typedStateFactoryJs(JsBackedMap backingMap) => + new _$$ToggleButtonGroupState$JsMap(backingMap); + + @override + _$$ToggleButtonGroupState typedStateFactory(Map backingMap) => + new _$$ToggleButtonGroupState(backingMap); + + /// Let [UiComponent] internals know that this class has been generated. + @override + bool get $isClassGenerated => true; + + /// The default consumed props, taken from _$ToggleButtonGroupProps. + /// Used in [UiProps.consumedProps] if [consumedProps] is not overridden. + @override + final List $defaultConsumedProps = const [ + _$metaForToggleButtonGroupProps + ]; +} diff --git a/web/component2/src/demos.dart b/web/component2/src/demos.dart new file mode 100644 index 000000000..f244fe08a --- /dev/null +++ b/web/component2/src/demos.dart @@ -0,0 +1,27 @@ +export 'shared/constants.dart'; + +export 'demos/button/button-examples.dart'; +export 'demos/button/button-types.dart'; +export 'demos/button/button-outline.dart'; +export 'demos/button/button-sizes.dart'; +export 'demos/button/button-block.dart'; +export 'demos/button/button-active.dart'; +export 'demos/button/button-disabled.dart'; + +export 'demos/list-group/list-group-basic.dart'; +export 'demos/list-group/list-group-tags.dart'; +export 'demos/list-group/list-group-anchors-and-buttons.dart'; +export 'demos/list-group/list-group-contextual.dart'; +export 'demos/list-group/list-group-header.dart'; + +export 'demos/progress/progress-basic.dart'; +export 'demos/progress/progress-contextual.dart'; +export 'demos/progress/progress-striped.dart'; +export 'demos/progress/progress-animated-stripes.dart'; + +export 'demos/tag/tag-basic.dart'; +export 'demos/tag/tag-contextual.dart'; +export 'demos/tag/tag-pills.dart'; + +export 'demos/toggle-button/toggle-button-checkbox.dart'; +export 'demos/toggle-button/toggle-button-radio.dart'; diff --git a/web/component2/src/demos/button/button-active.dart b/web/component2/src/demos/button/button-active.dart new file mode 100644 index 000000000..5b58aa30f --- /dev/null +++ b/web/component2/src/demos/button/button-active.dart @@ -0,0 +1,14 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonActiveDemo() => + (Dom.div()..className = 'btn-toolbar')( + (Button() + ..isActive = true + )('Primary button'), + (Button() + ..isActive = true + ..skin = ButtonSkin.SECONDARY + )('Button') + ); diff --git a/web/component2/src/demos/button/button-block.dart b/web/component2/src/demos/button/button-block.dart new file mode 100644 index 000000000..88f10131c --- /dev/null +++ b/web/component2/src/demos/button/button-block.dart @@ -0,0 +1,13 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonBlockDemo() => Dom.div()( + (Button() + ..isBlock = true + )('Block level button'), + (Button() + ..isBlock = true + ..skin = ButtonSkin.SECONDARY + )('Block level button') +); diff --git a/web/component2/src/demos/button/button-disabled.dart b/web/component2/src/demos/button/button-disabled.dart new file mode 100644 index 000000000..52dc3375b --- /dev/null +++ b/web/component2/src/demos/button/button-disabled.dart @@ -0,0 +1,15 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonDisabledDemo() => + (Dom.div()..className = 'btn-toolbar')( + (Button() + ..isDisabled = true + )('Primary button'), + (Button() + ..href = '#' + ..isDisabled = true + ..skin = ButtonSkin.SECONDARY + )('Link') + ); diff --git a/web/component2/src/demos/button/button-examples.dart b/web/component2/src/demos/button/button-examples.dart new file mode 100644 index 000000000..68e8f12ff --- /dev/null +++ b/web/component2/src/demos/button/button-examples.dart @@ -0,0 +1,17 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonExamplesDemo() => + (Dom.div()..className = 'btn-toolbar')( + Button()('Primary'), + (Button()..skin = ButtonSkin.SECONDARY)('Secondary'), + (Button()..skin = ButtonSkin.SUCCESS)('Success'), + (Button()..skin = ButtonSkin.INFO)('Info'), + (Button()..skin = ButtonSkin.WARNING)('Warning'), + (Button()..skin = ButtonSkin.DANGER)('Danger'), + (Button() + ..href = '#' + ..skin = ButtonSkin.LINK + )('Link') + ); diff --git a/web/component2/src/demos/button/button-outline.dart b/web/component2/src/demos/button/button-outline.dart new file mode 100644 index 000000000..d66bc6a47 --- /dev/null +++ b/web/component2/src/demos/button/button-outline.dart @@ -0,0 +1,13 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonOutlineDemo() => + (Dom.div()..className = 'btn-toolbar')( + (Button()..skin = ButtonSkin.PRIMARY_OUTLINE)('Primary'), + (Button()..skin = ButtonSkin.SECONDARY_OUTLINE)('Secondary'), + (Button()..skin = ButtonSkin.SUCCESS_OUTLINE)('Success'), + (Button()..skin = ButtonSkin.INFO_OUTLINE)('Info'), + (Button()..skin = ButtonSkin.WARNING_OUTLINE)('Warning'), + (Button()..skin = ButtonSkin.DANGER_OUTLINE)('Danger') + ); diff --git a/web/component2/src/demos/button/button-sizes.dart b/web/component2/src/demos/button/button-sizes.dart new file mode 100644 index 000000000..3804d6fc1 --- /dev/null +++ b/web/component2/src/demos/button/button-sizes.dart @@ -0,0 +1,10 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonSizesDemo() => + (Dom.div()..className = 'btn-toolbar')( + (Button()..size = ButtonSize.SMALL)('Small'), + Button()('Default'), + (Button()..size = ButtonSize.LARGE)('Large') + ); diff --git a/web/component2/src/demos/button/button-types.dart b/web/component2/src/demos/button/button-types.dart new file mode 100644 index 000000000..8e8d7393f --- /dev/null +++ b/web/component2/src/demos/button/button-types.dart @@ -0,0 +1,11 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement buttonTypesDemo() => + (Dom.div()..className = 'btn-toolbar')( + Button()('Button'), + (Button()..href = '#')('Link'), + (Button()..type = ButtonType.SUBMIT)('Submit'), + (Button()..type = ButtonType.RESET)('Reset') + ); diff --git a/web/component2/src/demos/button/index.dart b/web/component2/src/demos/button/index.dart new file mode 100644 index 000000000..d58f4f208 --- /dev/null +++ b/web/component2/src/demos/button/index.dart @@ -0,0 +1,31 @@ +import 'dart:html'; + +import 'package:over_react/react_dom.dart' as react_dom; +import 'package:over_react/over_react.dart'; + +import '../../demos.dart'; + +main() { + setClientConfiguration(); + + react_dom.render(buttonExamplesDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-examples')); + + react_dom.render(buttonTypesDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-types')); + + react_dom.render(buttonOutlineDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-outline')); + + react_dom.render(buttonSizesDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-sizes')); + + react_dom.render(buttonBlockDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-block')); + + react_dom.render(buttonActiveDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-active')); + + react_dom.render(buttonDisabledDemo(), + querySelector('$demoMountNodeSelectorPrefix--button-disabled')); +} diff --git a/web/component2/src/demos/list-group/index.dart b/web/component2/src/demos/list-group/index.dart new file mode 100644 index 000000000..4eb0436d8 --- /dev/null +++ b/web/component2/src/demos/list-group/index.dart @@ -0,0 +1,25 @@ +import 'dart:html'; + +import 'package:over_react/react_dom.dart' as react_dom; +import 'package:over_react/over_react.dart'; + +import '../../demos.dart'; + +main() { + setClientConfiguration(); + + react_dom.render(listGroupBasicDemo(), + querySelector('$demoMountNodeSelectorPrefix--list-group-basic')); + + react_dom.render(listGroupTagsDemo(), + querySelector('$demoMountNodeSelectorPrefix--list-group-tags')); + + react_dom.render(listGroupAnchorsAndButtonsDemo(), + querySelector('$demoMountNodeSelectorPrefix--list-group-anchors-and-buttons')); + + react_dom.render(listGroupContextualSkinDemo(), + querySelector('$demoMountNodeSelectorPrefix--list-group-contextual')); + + react_dom.render(listGroupHeaderDemo(), + querySelector('$demoMountNodeSelectorPrefix--list-group-header')); +} diff --git a/web/component2/src/demos/list-group/list-group-anchors-and-buttons.dart b/web/component2/src/demos/list-group/list-group-anchors-and-buttons.dart new file mode 100644 index 000000000..41fd1dd58 --- /dev/null +++ b/web/component2/src/demos/list-group/list-group-anchors-and-buttons.dart @@ -0,0 +1,24 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement listGroupAnchorsAndButtonsDemo() => + ListGroup()( + (ListGroupItem() + ..isActive = true + ..href = '#' + )('Cras justo odio'), + (ListGroupItem() + ..onClick = (_) {} + )('Dapibus ac facilisis in'), + (ListGroupItem() + ..onClick = (_) {} + )('Morbi leo risus'), + (ListGroupItem() + ..onClick = (_) {} + )('Porta ac consectetur ac'), + (ListGroupItem() + ..isDisabled = true + ..onClick = (_) {} + )('Vestibulum at eros') + ); diff --git a/web/component2/src/demos/list-group/list-group-basic.dart b/web/component2/src/demos/list-group/list-group-basic.dart new file mode 100644 index 000000000..8f954354d --- /dev/null +++ b/web/component2/src/demos/list-group/list-group-basic.dart @@ -0,0 +1,11 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement listGroupBasicDemo() => + ListGroup()( + ListGroupItem()('Dapibus ac facilisis in'), + ListGroupItem()('Cras sit amet nibh libero'), + ListGroupItem()('Porta ac consectetur ac'), + ListGroupItem()('Vestibulum at eros') + ); diff --git a/web/component2/src/demos/list-group/list-group-contextual.dart b/web/component2/src/demos/list-group/list-group-contextual.dart new file mode 100644 index 000000000..523aac994 --- /dev/null +++ b/web/component2/src/demos/list-group/list-group-contextual.dart @@ -0,0 +1,23 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement listGroupContextualSkinDemo() => + ListGroup()( + (ListGroupItem() + ..onClick = (_) {} + ..skin = ListGroupItemSkin.SUCCESS + )('Dapibus ac facilisis in'), + (ListGroupItem() + ..onClick = (_) {} + ..skin = ListGroupItemSkin.INFO + )('Cras sit amet nibh libero'), + (ListGroupItem() + ..onClick = (_) {} + ..skin = ListGroupItemSkin.WARNING + )('Porta ac consectetur ac'), + (ListGroupItem() + ..onClick = (_) {} + ..skin = ListGroupItemSkin.DANGER + )('Vestibulum at eros') + ); diff --git a/web/component2/src/demos/list-group/list-group-header.dart b/web/component2/src/demos/list-group/list-group-header.dart new file mode 100644 index 000000000..de131adc2 --- /dev/null +++ b/web/component2/src/demos/list-group/list-group-header.dart @@ -0,0 +1,31 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement listGroupHeaderDemo() => + ListGroup()( + (ListGroupItem() + ..header = 'List group item heading' + ..onClick = (_) {} + ..isActive = true + )( + 'Donec id elit non mi porta gravida at eget metus. ' + 'Maecenas sed diam eget risus varius blandit.' + ), + (ListGroupItem() + ..header = 'List group item heading' + ..headerSize = ListGroupItemHeaderElementSize.H4 + ..onClick = (_) {} + )( + 'Donec id elit non mi porta gravida at eget metus. ' + 'Maecenas sed diam eget risus varius blandit.' + ), + (ListGroupItem() + ..header = 'List group item heading' + ..headerSize = ListGroupItemHeaderElementSize.H3 + ..onClick = (_) {} + )( + 'Donec id elit non mi porta gravida at eget metus. ' + 'Maecenas sed diam eget risus varius blandit.' + ) + ); diff --git a/web/component2/src/demos/list-group/list-group-tags.dart b/web/component2/src/demos/list-group/list-group-tags.dart new file mode 100644 index 000000000..08f0c1c6d --- /dev/null +++ b/web/component2/src/demos/list-group/list-group-tags.dart @@ -0,0 +1,28 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement listGroupTagsDemo() => + ListGroup()( + ListGroupItem()( + (Tag() + ..className = 'float-xs-right' + ..isPill = true + )(14), + 'Cras justo odio' + ), + ListGroupItem()( + (Tag() + ..className = 'float-xs-right' + ..isPill = true + )(2), + 'Dapibus ac facilisis in' + ), + ListGroupItem()( + (Tag() + ..className = 'float-xs-right' + ..isPill = true + )(1), + 'Morbi leo risus' + ) + ); diff --git a/web/component2/src/demos/progress/index.dart b/web/component2/src/demos/progress/index.dart new file mode 100644 index 000000000..f24cae739 --- /dev/null +++ b/web/component2/src/demos/progress/index.dart @@ -0,0 +1,22 @@ +import 'dart:html'; + +import 'package:over_react/react_dom.dart' as react_dom; +import 'package:over_react/over_react.dart'; + +import '../../demos.dart'; + +main() { + setClientConfiguration(); + + react_dom.render(progressBasicDemo(), + querySelector('$demoMountNodeSelectorPrefix--progress-basic')); + + react_dom.render(progressContextualDemo(), + querySelector('$demoMountNodeSelectorPrefix--progress-contextual')); + + react_dom.render(progressStripedDemo(), + querySelector('$demoMountNodeSelectorPrefix--progress-striped')); + + react_dom.render(progressAnimatedStripesDemo(), + querySelector('$demoMountNodeSelectorPrefix--progress-animated-stripes')); +} diff --git a/web/component2/src/demos/progress/progress-animated-stripes.dart b/web/component2/src/demos/progress/progress-animated-stripes.dart new file mode 100644 index 000000000..661e5dc9c --- /dev/null +++ b/web/component2/src/demos/progress/progress-animated-stripes.dart @@ -0,0 +1,10 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement progressAnimatedStripesDemo() => + (Progress() + ..value = 25.0 + ..isStriped = true + ..isAnimated = true + )(); diff --git a/web/component2/src/demos/progress/progress-basic.dart b/web/component2/src/demos/progress/progress-basic.dart new file mode 100644 index 000000000..62d4d81d1 --- /dev/null +++ b/web/component2/src/demos/progress/progress-basic.dart @@ -0,0 +1,35 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement progressBasicDemo() => Dom.div()( + (Progress() + ..showCaption = true + ..captionProps = (domProps()..className = 'text-xs-center') + ..caption = 'Reticulating splines...' + )(), + (Progress() + ..value = 25.0 + ..showCaption = true + ..captionProps = (domProps()..className = 'text-xs-center') + ..caption = 'Reticulating splines...' + )(), + (Progress() + ..value = 50.0 + ..showCaption = true + ..captionProps = (domProps()..className = 'text-xs-center') + ..caption = 'Reticulating splines...' + )(), + (Progress() + ..value = 75.0 + ..showCaption = true + ..captionProps = (domProps()..className = 'text-xs-center') + ..caption = 'Reticulating splines...' + )(), + (Progress() + ..value = 100.0 + ..showCaption = true + ..captionProps = (domProps()..className = 'text-xs-center') + ..caption = 'Reticulating splines...' + )() +); diff --git a/web/component2/src/demos/progress/progress-contextual.dart b/web/component2/src/demos/progress/progress-contextual.dart new file mode 100644 index 000000000..7c485d28b --- /dev/null +++ b/web/component2/src/demos/progress/progress-contextual.dart @@ -0,0 +1,22 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement progressContextualDemo() => Dom.div()( + (Progress() + ..value = 25.0 + ..skin = ProgressSkin.SUCCESS + )(), + (Progress() + ..value = 50.0 + ..skin = ProgressSkin.INFO + )(), + (Progress() + ..value = 75.0 + ..skin = ProgressSkin.WARNING + )(), + (Progress() + ..value = 100.0 + ..skin = ProgressSkin.DANGER + )() +); diff --git a/web/component2/src/demos/progress/progress-striped.dart b/web/component2/src/demos/progress/progress-striped.dart new file mode 100644 index 000000000..d028bcb1f --- /dev/null +++ b/web/component2/src/demos/progress/progress-striped.dart @@ -0,0 +1,30 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement progressStripedDemo() => Dom.div()( + (Progress() + ..value = 10.0 + ..isStriped = true + )(), + (Progress() + ..value = 25.0 + ..skin = ProgressSkin.SUCCESS + ..isStriped = true + )(), + (Progress() + ..value = 50.0 + ..skin = ProgressSkin.INFO + ..isStriped = true + )(), + (Progress() + ..value = 75.0 + ..skin = ProgressSkin.WARNING + ..isStriped = true + )(), + (Progress() + ..value = 100.0 + ..skin = ProgressSkin.DANGER + ..isStriped = true + )() +); diff --git a/web/component2/src/demos/tag/index.dart b/web/component2/src/demos/tag/index.dart new file mode 100644 index 000000000..66f8c921f --- /dev/null +++ b/web/component2/src/demos/tag/index.dart @@ -0,0 +1,16 @@ +import 'dart:html'; + +import 'package:over_react/react_dom.dart' as react_dom; +import 'package:over_react/over_react.dart'; + +import '../../demos.dart'; + +main() { + setClientConfiguration(); + + react_dom.render(tagBasicDemo(), querySelector('$demoMountNodeSelectorPrefix--tag-basic')); + + react_dom.render(tagContextualDemo(), querySelector('$demoMountNodeSelectorPrefix--tag-contextual')); + + react_dom.render(tagPillsDemo(), querySelector('$demoMountNodeSelectorPrefix--tag-pills')); +} diff --git a/web/component2/src/demos/tag/tag-basic.dart b/web/component2/src/demos/tag/tag-basic.dart new file mode 100644 index 000000000..f39e8986a --- /dev/null +++ b/web/component2/src/demos/tag/tag-basic.dart @@ -0,0 +1,12 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement tagBasicDemo() => Dom.div()( + Dom.h1()('Example heading ', Tag()('New')), + Dom.h2()('Example heading ', Tag()('New')), + Dom.h3()('Example heading ', Tag()('New')), + Dom.h4()('Example heading ', Tag()('New')), + Dom.h5()('Example heading ', Tag()('New')), + Dom.h6()('Example heading ', Tag()('New')) +); diff --git a/web/component2/src/demos/tag/tag-contextual.dart b/web/component2/src/demos/tag/tag-contextual.dart new file mode 100644 index 000000000..168b8df72 --- /dev/null +++ b/web/component2/src/demos/tag/tag-contextual.dart @@ -0,0 +1,12 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement tagContextualDemo() => Dom.div()( + (Tag()..skin = TagSkin.DEFAULT)('Default'), + (Tag()..skin = TagSkin.PRIMARY)('Primary'), + (Tag()..skin = TagSkin.SUCCESS)('Success'), + (Tag()..skin = TagSkin.INFO)('Info'), + (Tag()..skin = TagSkin.WARNING)('Warning'), + (Tag()..skin = TagSkin.DANGER)('Danger') +); diff --git a/web/component2/src/demos/tag/tag-pills.dart b/web/component2/src/demos/tag/tag-pills.dart new file mode 100644 index 000000000..56af9d90e --- /dev/null +++ b/web/component2/src/demos/tag/tag-pills.dart @@ -0,0 +1,30 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement tagPillsDemo() => Dom.div()( + (Tag() + ..isPill = true + ..skin = TagSkin.DEFAULT + )('Default'), + (Tag() + ..isPill = true + ..skin = TagSkin.PRIMARY + )('Primary'), + (Tag() + ..isPill = true + ..skin = TagSkin.SUCCESS + )('Success'), + (Tag() + ..isPill = true + ..skin = TagSkin.INFO + )('Info'), + (Tag() + ..isPill = true + ..skin = TagSkin.WARNING + )('Warning'), + (Tag() + ..isPill = true + ..skin = TagSkin.DANGER + )('Danger') +); diff --git a/web/component2/src/demos/toggle-button/toggle-button-checkbox.dart b/web/component2/src/demos/toggle-button/toggle-button-checkbox.dart new file mode 100644 index 000000000..ccf9c98ac --- /dev/null +++ b/web/component2/src/demos/toggle-button/toggle-button-checkbox.dart @@ -0,0 +1,19 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement checkboxToggleButtonDemo() => + (ToggleButtonGroup() + ..toggleType = ToggleBehaviorType.CHECKBOX + )( + (ToggleButton() + ..value = '1' + )('Checkbox 1'), + (ToggleButton() + ..value = '2' + ..defaultChecked = true + )('Checkbox 2'), + (ToggleButton() + ..value = '3' + )('Checkbox 3') + ); diff --git a/web/component2/src/demos/toggle-button/toggle-button-radio.dart b/web/component2/src/demos/toggle-button/toggle-button-radio.dart new file mode 100644 index 000000000..633f6b2fd --- /dev/null +++ b/web/component2/src/demos/toggle-button/toggle-button-radio.dart @@ -0,0 +1,19 @@ +import 'package:over_react/over_react.dart'; + +import '../../demo_components.dart'; + +ReactElement radioToggleButtonDemo() => + (ToggleButtonGroup() + ..toggleType = ToggleBehaviorType.RADIO + )( + (ToggleButton() + ..value = '1' + )('Radio 1'), + (ToggleButton() + ..value = '2' + ..defaultChecked = true + )('Radio 2'), + (ToggleButton() + ..value = '3' + )('Radio 3') + ); diff --git a/web/component2/src/shared/constants.dart b/web/component2/src/shared/constants.dart new file mode 100644 index 000000000..e448aabbc --- /dev/null +++ b/web/component2/src/shared/constants.dart @@ -0,0 +1,98 @@ +import 'package:over_react/over_react.dart'; +part 'constants.over_react.g.dart'; + +const String demoMountNodeSelectorPrefix = '.component-demo__mount'; + +/// A class of possible HTML `type` attribute values to be placed on a [Dom.button]. +class ButtonType extends DebugFriendlyConstant { + /// The DOM `