Releases: SaltyAom/niku
2.4 Yorugao
I'm happy to announce the stable release of Niku 2.4 named "Yorugao".
This may not be a big update with a big new feature, but is an essential one for the future of Niku to support Dart 3 and Material 3 for a better foundation.
Named after Yorugao composed by An & Ryunosuke Kudo, an unlockable perfect challenge featured in MaiMai DX Universe.
This version feature: A foundation for Material 3
Feature:
- Migrate update to Material 3 (Flutter 3.10)
- New Widget for Material 3:
- ActionChip
- SwitchListTile
- Add factory method for Material 3:
- IconButton
- outlined
- tonal
- filled
- Button
- outlined
- tonal
- filled
- IconButton
- New TextFormField property:
- contextMenuBuilder
- magnifierConfiguration
- spellCheckConfiguration
- New parent builder:
- badge
Bug Fix:
- Memory leak in
useTransition
Fix:
- Deprecated text factory of h1-h6, subtitle, headline, overline, button
2.3 Tempestissimo
I'm very proud to announce the new release of Niku.
A lot of research and effort into this version.
I'm excited to announce the stable release of Niku 2.3 named "Tempestissimo".
Named after Tempestissimo composed by t+pazolite, hardcore gothic boss music featured in Arcaea alongside a new character, Tairitsu (Tempest).
This version feature: Tempest Engine, a rewritten internal architecture entirely change.
Tempest Engine
Focused on performance improvement, reducing memory usage, and faster allocation time.
Make possible by new features like, "Flatten Merge", and lazy execution.
Flatten Merge
Flatten Merge is a technique that allows duplicated properties to merge together, allocating only one widget on the duplicated stack.
For example, Padding:
n.Box()
..px = 16
..py = 8
..px = 4
Normally, this would allocate 3 nested Padding widgets which is not good for both allocation time and memory usage.
But with Tempest Engine, it now allocates only 1 Padding instead of 3.
Lazy Execution
Previously, Niku eagerly allocate widgets on mutable getter/setter, which isn't good practice for a reference style like the Stylesheet pattern.
However, with the new architect, the property is now lazily constructed, which means the widget now only holds a "blueprint" for creating a widget instead of creating them instead before build
.
This reduced a lot of memory usage when used with the Stylesheet pattern and Psuedo const like ..deps
and ..freezed
.
Allowing fine tuning performance even better.
The allocation time of Tempest Engine is in fact, faster than native Flutter in terms of reference allocation.
Quotes:
The new Niku "Tempest" Engine outperforms native Flutter in terms of Widget initialization (creation), or near in the most case.
The test was conducted by measuring the creation time of generating 1 million Text with a Container of manual 40 iterations.
Average Result:
Niku: 63.86ms
Flutter: 68.83ms
Mutable Child
Tempest Engine also allows a child to be mutable.
This is why the change of the Niku widget for allowing mutable child matter.
Now it doesn’t have to store build stack anymore, because now Parent Proxy can ensure that the order of parent proxy will not block the child's property anymore.
All it has to do is to separately allocate Parent and Child.
When child property is set, it only affects the child the same as the Parent.
Now when the build method is called, all it has to do is, assign Parent-Child to child builder.
This eliminates the need for allocating the parent build stack., reducing the n amount of Parent widget allocation to only 1.
Codebase Reduction
With Tempest Engine writing for taking advantage of the new feature of Dart.
Rewritten, making everything modular and reusable with abstract class and extension and advantage of Tempest Engine.
Niku 2.3 is able to reduce an entire codebase reduction by 50%.
This means that the shipped version of your app will be even lighter by the currently very lightweight library and even faster.
Tempest Engine performance
With a lot of new micro-optimization, taking advantage of the new Dart feature, Tempest Engine increases a lot of performance your Niku app.
Notable improvements are:
- Parent Proxy is faster by 50%.
- Up to 40% better performance for Parent Builder without having to do anything.
- 8.75x faster for Text reference initialization.
Full Support for Parent Proxy
Parent Proxy allows you to call parent property without using useParent
, by accessing via n
prefix.
Available for every widget.
This helps developers to compose parent styling even easier on minimal change to parent property.
Read more at Parent Styling
Flutter 3 and Material 3 Support
Niku 2.3 also adds support for Flutter 3 and supports MacOS on Apple Silicon.
Not only partial supports but also taking advantage of the new property in Material 3 supports.
For example:
- New Typography in Material 3
- New ripple effects, like
.sparkle
No matter what Material version you're using, Niku is able to fully support both versions.
Extension Transformation
Niku 2.3 add a new extension widget transformation.
Notable usage is "Text".n, which transforms a String to Text as a shortcut.
Reducing character to type in order to allocate widget.
Extension Transformation also takes advantage of the Material Typography System.
Allowing you to directly apply style from Material 3 Typography without the need of context
thanks to Tempest Engine.
Recap
Phew, that's a lot to unpack.
But to recap:
- Featuring Tempest Engine, you will gain a free performance boost without having to do anything.
- 50% library size reduction.
- Flutter 3 supports, taking advantage of Material 3 and macOS.
- Extension Transformation, reducing the need for widget allocation with a new shortcut.
- And much more with notable change under the release note.
Tempest Engine is briefly discussed here, but if you want to understand how the new Tempest Engine works, you can take a look into But how does Tempest Engine in Niku work?.
So, that's pretty much all for this release, until the next time we meet again with a new exciting updates and features.
Now for notable change for this version and migration guide:
Breaking Change:
- Rename the following property on
Image
:circleProgress
->useCircleProgress
linearProgress
->useLinearProgress
- Rename
on
todeps
, anduseGesture
toon
. - Add
labelText
as replacement oflabel
which is now acceptWidget
- Move
useTextStyle
touseNikuTextStyle
inNikuButton
to adduseTextStyle
forNikuState
- Remove
useNiku
,nikuConstraints
,nikuPadding
,nikuMargin
fromNiku
and Parent Proxy.
Feature:
- Add material 3 shortcut.
sparkle
onNikuButton
as shortcut for..splashFactory = InkSparkle.splashFactory
- Add Material 3 Typography initialzation shortcut, and Text Factory
- displayLarge
- displayMedium
- displaySmall
- titleLarge
- titleMedium
- titleSmall
- bodyLarge
- bodyMedium
- bodySmall
- labelLarge
- labelMedium
- labelSmall
- Internal architecture changed called
Tempestissimo
.- Significant performance improvement, parent builder rewrite
- Parent Property builder now lazily executed
- Flatten and parent property
- Add
ExplictParentBuilder
to quickly handle single use of parent builder - New hook:
useShadow
- Add new property,
borderRadius
,shadow
,highlightColor
,focusColor
,hoverColor
Change:
- Add .offstage, .show shortcut
- Update .useScrollbar to Flutter 3
- .hidden now based on Offset
- Initial work with Flutter 3 and Material3.
useThemeSelector
now can accept nullable value- Refactored Proxy, now has 50% less code and much cleaner
- Parent Builder architecture rewrite, name
Tempestissimo
. rounded
now useNikuRounded
under the hood to auto inherit borderRadius for the next builder, eg.shadows
, andborder
.- Deprecate
UseQueryMacro<T>
, merged intoNikuBuildMacro<T>
Bug fix:
- Text Theme doesn't update on Brightness change
- _applyConstraints, _applyPadding, _applyPositions cause Stackoverflow
- Gap now doesn't use square ratio, the content cross-dimension is now preserved.
2.2 Aegleseeker
It's only been just 2 weeks since the latest release of 2.1.
Today, we're expanding the horizon of Niku across the board again with Niku 2.2
This time, the name "Aegleseeker" is from the name of music composed by "Silentroom" vs "Frums", which featured in Rhythm game called Arcaea.
This version features more of a parent proxy.
Extended Parent Proxy
Quote from 2.1 (Ga1ahad)
Parent Proxy allows you to compose your parent with access to parent property without having to create useParent.
Previously, only Column and Row got extended parent proxy which normal Niku widget only got margin
for parent proxy.
We investigated that Flutter developers commonly want more than just margin, but the more common proxy like width
, height
is also important, so we port all of the sizing shortcuts to every Niku widget.
We also add more proxy to AxisLayoutProxy
, which add more common pattern like parent alignment
.
Take a look at below figure, notice that there's no useParent
because it's now handled by common property builder provided by extended parent proxy.
Introducing useTransition
Ever want to animate property from one to another without hassle? Then you might want to use useTransition
!
With use transition, Niku auto animate property you provided from previous to new without you manually creating AnimationController or StatefulWidget, it can be used directly in StatelessWidget like any other property builder.
To see how clean the useTransition
can provide at the figure below.
Without useTransition:
Improvement of UseQueryMacro
Reduce Time Complexity of hooks from UseQueryMacro
from O(n(2i + p)) to O(n) where n is property, p is parent total call stack, and i is a total invocation.
Bypassing widget self as reference instead of immutable copied then diffing, and apply
The following hooks benefits in performance improvement:
- useQuery
- useSize
- useDarkMode
- useThemeSelector
- useScreen
Feature:
- New parent proxy available for all widget:
- expanded
- flex
- fullSize
- fullWidth, wFull, w100
- fullHeight, hFull, h100
- fractionSize, sizePercent
- fractionWidth, fractionW, fw, wFactor, widthPercent, wPercent
- fractionHeight, fractionH, hw, hFactor, heightPercent, hPercent
- boxConstraints
- nikuConstraints
- maxSize
- minSize
- maxWidth, maxW, wMax
- minWidth, minW, wMin
- maxHeight, maxH, hMax
- minHeight, minH, hMin
- width, w
- height, h
- useGesture
- New parent proxy available for AxisLayourProxy
- alignTopLeft
- alignTopCenter
- alignTopRight
- alignCenterLeft
- alignCenter
- alignCenterRight
- alignBottomLeft
- alignBottomCenter
- alignBottomRight
- New widget:
NikuRadio
,NikuRadioListTile
,NikuDismissible
- New hook:
useTransition
,useTransitions
- Add property:
splash
,wFactor
,hFactor
toNiku
- New utility widget
NikuAnimated
,NikuAnimateds
- New proxy:
ListTile
withdismiss
forNikuDismissible
Change:
- Move part of
AxisProxy
toNikuBuildMacro
- Refactor, and organize examples
Bug fixes:
obscureCharacter
not working inNikuTextFormField
2.1 Ga1ahad
It's been a wild ride of Niku with you all.
Since Niku 2.0 has been released, Niku has been getting a lot of attention lately, and we really want to say thank you to all for joining us on how we could reimagine composing UI in the Flutter together.
For this release, 2.1 or ga1ahad have been working on for quite some time, drafted even before the release of 2.0 rc.
The name "Ga1ahad" comes from Ga1ahad and Scientific Witchery.
Without further ado, let's see what's new in Niku 2.1~
Proxy
Previously, with Niku, composing nested objects would required you an additional, for example composing n.Button
.
n.Button(Text("Delete"))
..onPressed = log
..useTextStyle((v) => v..color = Colors.red)
..useButtonStyle((v) => v..splash = Colors.red.withOpacity(.15));
This is good for grouping the styling, easily indicating which style is for which part, but to be honest, it's slow and annoying to write.
That's why Proxy is created to fix this problem.
Proxy is an abstract class for mapping your setter and shortcut to a nested object property without using a hook.
It handles creating object if doesn't exist and just write the property, that's it, no magic or expensive calculation.
This allows you to write the direct setter without having useTextStyle
or useButtonStyle
hook.
n.Button(Text("Delete"))
..onPressed = log
..color = Colors.red
..splash = Colors.red.withOpacity(.15);
Not only that you can use Proxy to handle the style of nested objects, but you can also handle the parent property builder as well.
Proxy support Button
and TextFormField
with all properties, and shortcuts.
Parent Proxy
Same as Proxy but for parents.
Parent Proxy allows you to compose your parent with access to parent property without having to create useParent
.
For the layout widget like Column
and Row
which usually required explicit set of width or other property like w100
, bg
, scrollable
, rounded
, border
and etc.
Providing a shortcut proxy would be really convenient, so the parent proxy is here for the job.
With parent proxy, you can now compose some parent shortcut for some specific widget starting with Column
and Row
.
n.Row([])
..center
..wFull
..bg = Colors.red
..rounded = 8
Because some widgets might have conflict names with parent property and shortcuts like padding
, only a specific selection of widgets are get to have Parent Proxy.
But every parent has limited access to some convenient Parent Proxy, starting with margin
and m
.
useThemeSelector
Dark theme has become an essential part of app development, with Niku you can use useDarkMode
to handle the case.
But the handler is quite, imperative to say the least.
n.Box()
..useDarkMode((v, isDark) => v
..bg = isDark ? Colors.grey.shade800 : Colors.white);
You are provided with child and isDark
as an indicator for dark mode but you still have to handle the logic yourself.
For a single property, it's quite simple but when there's more property it gets annoying.
Besides what about some property you might want to have in specific mode only? You have to handle the case yourself.
This is why useThemeSelector
is introduced.
Basically, it provide you the same syntax as useScreen
but for dark mode and handle the rest of for diffing and applyment for you.
n.Box()
..useThemeSelector(
light: (v) => v..bg = Colors.white,
dark: (v) => v..bg = Colors.grey.shade800,
);
GridView and ListView
Gridview and ListView are now supported as Niku widgets, with all the factory property and utilities you can use.
It's recommended to use GridView and ListView for Style Sheet Pattern because of the redundant syntax provided.
Breaking Change
flexible
is nowflex
onNiku
- Deprecated required value of
TextFormField
in favor ofhint
.- To migrate, please add factory
.hint
or add it asnamed parameter
- To migrate, please add factory
Minor Feature
- Add
ConstraintsMacro
toNikuInputDecoration
- Add
useTextStyle
toDropdownButton
- Add State Utility Hooks to
NikuButton
- Add
color
setter toNikuButtonStyle
- Add
of
alias forapply
Change
border
is nowbaseBorder
, andallBorder
is nowborder
- margin property now uses
Padding
instead ofContainer
because that's how native Flutter doing it. Yes, margin is actually padding in Flutter. -
- Remove function allocation from
_init
ofMapTextStyleMacro
- Remove function allocation from
- Add
center
toNikuColumn
, andNikuRow
- Replace
childrenWithGap
with$internalComposeGap
inGapMacro
- Add
gap
property to AxisLayout - gap can now be applied
childrenWithGap
now only composed on buildborderWidth
is nowbaseBorderWidth
to follow the same convention withborder
,borderColor
, andborderStyle
on proxyAxisLayoutMacro
is nowAxisLayoutProxy
Fix
Bug fix:
- Remove
print
fromPaddingMacro
- Fix
'owner!._debugCurrentBuildTarget == this': is not true.
when usinguseDarkMode
useDarkMode
anduseThemeSelector
not switching context between
2.0.0 Stable
This day marks a milestone of a brighter new future in Flutter app development.
The release of Niku codename Heaven and Earth
or Niku 2.
After months of research and experiment, we finally settle down with the answer, and we think you going to love it.
Niku 2
TLDR; an entire rewrite, read more at Introducing Niku 2
Below is the Change Log from the previous 2.0 beta
[2.0.0-compat.0] - 2022/02/21
Base on 2.0.0-rc.8
A compatibility version for working with both v1 and v2 for gradually migrating from v1.
To gradually migrate from v1, simply replace all:
// From
import 'package:niku/niku.dart';
// into
import 'package:niku/v1/niku.dart';
You can easily use IDE like VS Code to find and replace all package:niku/
with package:niku/v1/
then it should work just fine, gradually migrate from v1.
[2.0.0-rc.8] - 2022/02/20
Bux Fix:
- Add
copied
to NikuImage, NikuSlider, NikuRangeSlider. - Apply parent builder to
copied
method
[2.0.0-rc.7] - 2022/02/20
Feature:
- New
use
onNikuWidget
to apply multiple styles at once - Add
useBorder
,useRoundedBorder
- Add
apply
toNikuIcon
- Add
WidthHeightMacro
Change:
- Add
Full Macro
conventions - Use Parent Builder stack instead of direct setter to support apply parent styling
Bux Fix:
- Fix wrong spelling of
actionPb
- Use
Full Macro
onAlert
- n.showDialog now accepts any widget
[2.0.0-rc.6] - 2022/02/19
Change:
- showNikuDialog now accepts any widget
[2.0.0-rc.5] - 2022/02/17
Bug Fix:
- Add default
.rounded
toNikuButton
- Fix gap inserted to last children
- Fix Column with gap required at least 1 children
[2.0.0-rc.4] - 2022/02/14
Breaking Change:
- Remove
NikuImage.file
factory to support web platform.
[2.0.0-rc.3] - 2022/02/14
Breaking Change:
- Remove cached network image due to not supporting all platform yet.
[2.0.0-rc.2] - 2022/02/13
Feature:
- Add
.quarterTurns
,bgBlur
,clipRect
,clipOval
toNiku
Change:
- Remove default styling from
NikuText
to match default Flutter Text, eg. TextBasis.
Bug fixes:
AxisMacro
not assigning wrong field name
[2.0.0-rc.1] - 2022/02/13
Breaking Change:
- Migrate
.useScreen
touseSize
- Migrate
.useQuery
to.useScreen
- Migrate
.useEvents
touseGesture
- Remove
TransformSelectableText
Feature:
- Add
.useQuery
to handleMediaQueryData
- Add
useBorder
,useNikuBorder
,useBorderColor
,useBorderWidth
hook - Add
.useDarkMode
to handle element styling on Dark Theme - Add
n.Image.cache
to useCacheNetworkImage
Bug fixes:
- Correct
focusedErrorBorder
setter name
[2.0.0-experimental.4] - 2022/01/31
Breaking Change:
- Remove
asNiku
on Widget (still working for object) - Migrate
.useOn
touseEvents
Feature:
- Add
.focusColor
,.splashColor
,highlightColor
,hoverColor
toNikuCheckboxListTile
- Add
.adaptive
toNikuAlert
- Add
.adaptive
toSwitch
- Add
.adaptive
toNikuTextFormField
- Add
NikuShowDialog
to handle adaptive dialog - New
NikuQuery
widget
Bug fixes:
.on
property inNiku
doesn't passing dependencies to concilation process
[2.0.0-experimental.3] - 2022/01/29
Feature:
- Add
useQuery
anduseScreen
property, read more about it here
Bug fixes:
.on
property inNiku
doesn't passing dependencies to concilation process
[2.0.0-experimental.2] - 2022/01/25
Feature:
- Game Changing,
NikuOn
,.on
and.freezed
property, read more about it here NikuDropdownButton
widget forDropdownButton
Bug fixes:
- Change from Nullish cascade equality to nullish check to override
useStyle
's style
Breaking Change:
- Migrate
.useStyle
to.useTextStyle()
onNikuText
. - Migrate
.useStyle
to.useButtonStyle()
onNikuButton
. - Change
.useStyle
to.useButtonStyle()
onNikuButton
. - Migrate
.useBuilder
,useParent
touseChild
onNiku
. - Migrate from
.value
to.widget
on every Niku component. - Migrate from
style
totextStyle
on every Niku component.
[2.0.0-experimental.1] - 2021/12/16
- Namespace
- Selectable Text
[2.0.0-experimental.0] - 2021/12/16
Selectable Text and Contribution
First of all, big thanks to @y-pakorn for this release!
He contributes to Niku for a several PR now, in fact, this entire release is happened because of his contribution which solved bug caused by my clumsiness, tee hee~
@y-pakorn's contributions: #3 #4 #5 #6.
Feature:
- Add NikuSelectableText.
- Add
mainAxisSize
toNikuColumn
andNikuRow
Bug fixes:
- Fixes
.fullWidth()
which cause full height. - Makes error text optional on
NikuTextField
.
Scrollbar and Theme
Niku Docs
Add Niku DOGcumentation and release change log so far.
[1.0.0-alpha.3] - 2021/3/31
Feature:
- Add
cursor
to IconButton. - Add the following property to
IconButton
:size
,minSize
,minimumSize
maxSize
,maximumSize
minWidth
,minimumWidth
minHeight
,minimumHeight
maxWidth
,maximumWidth
maxHeight
,maximumHeight
- Boolean method on
NikuTextField
now has default value oftrue
.
Breaking Change:
- Rename
border
tob
andsetBorder
toborder
. - Change
obscureTextFormField
toobscureText
on NikuTextField. - Add
asPassword
on NikuTextField. - Remove
disabledSmartDashes
anddisabledSmartQuotes
. enableSmartQuotes
andenableSmartDashes
now accept option boolean default as true.- Change from
inputDecorationEnable
toenableInputDecoration
. - Change from
...textFormField
to...text
in NikuTextField.
Bug fix:
- Fix Visual Density in NikuButton.
- Setting multiple border variant not working
[1.0.0-alpha.2] - 2021/3/28
Breaking Change:
- Swap arguments of animated
Change:
- Remove Nested instance from base property
- Add default value of
true
toabsortPointer
andignorePointer
[1.0.0-alpha.1] - 2021/3/25
Bug Fix:
- add Key
[1.0.0-alpha.0] - 2021/3/24
Feature:
- Remove
.build()
and.style()
- Niku Internal is now mutating property instead of stacking
- Add
.asNiku
on component instead of using Niku Component - Match
NikuButton
to idiomatic Dart - Add
TextStyle
to TextButton - Every Niku Component now support margin property
Breaking Change:
- Every Niku Component now extend
NikuCore
which extendsStatelessWidget
- Variant method
NikuButton
is removed.icon
toNikuButton.icon
.text
toNikuButton.text
.elevated
toNikuButton.elevated
.elevatedIcon
toNikuButton.elevatedIcon
.outlined
toNikuButton.outlined
.outlinedIcon
toNikuButton.outlinedIcon
Change:
- Remove usage of
this.
except for constructor - Every margin property is moved to
NikuCore
- Build is now using
internalBuild
- Remove container if margin is not presented
Bug fix:
- Foreground on text change background instead
- Fix margin not mistakenly setting on padding instead
wrap, wrap, wrap!
No more build
No more build
Niku 1.0.0 introduced breaking change. To remove build()
method!
Please remove your build method.
[1.0.0-alpha.0] - 2021/3/24
Feature:
- Remove
.build()
and.style()
- Niku Internal is now mutating property instead of stacking
- Add
.asNiku
on component instead of using Niku Component - Match
NikuButton
to idiomatic Dart - Add
TextStyle
to TextButton - Every Niku Component now support margin property
Breaking Change:
- Every Niku Component now extend
NikuCore
which extendsStatelessWidget
- Variant method
NikuButton
is removed.icon
toNikuButton.icon
.text
toNikuButton.text
.elevated
toNikuButton.elevated
.elevatedIcon
toNikuButton.elevatedIcon
.outlined
toNikuButton.outlined
.outlinedIcon
toNikuButton.outlinedIcon
Change:
- Remove usage of
this.
except for constructor - Every margin property is moved to
NikuCore
- Build is now using
internalBuild
- Remove container if margin is not presented
Bug fix:
- Foreground on text change background instead
- Fix margin not mistakenly setting on padding instead