Repository navigation
Releases: B1Digital/fluent_ui_2_flutter
Release list
v0.0.7
0.0.7
Added
- Declarative routes to the two charts no schema could reach (extension, not upstream). A Plotly trace whose
metacarries{"fluentChart": "sparkline"}rendersFluentSparkline, and{"fluentChart": "horizontalBarChart"}renders the axis-free part-to-wholeFluentHorizontalBarChart— one row pery, one segment per trace. Without the marker every trace routes exactly as upstream does.FluentPlotlyChartKindgainssparklineandhorizontalBarChart.
Fixed
FluentGaugeChartunder an unbounded height (a scroll view, orFluentDeclarativeChart's own column for anindicatortrace) threw a flex errorerrorBuildernever saw; the arc box now sizes from the computed height.- Plotly labels drew their HTML entities (
R&D,TK'nin,a<brendered asR&D,TK'nin,a<b). The figure is now decoded once after routing; annotations no longer decode twice, so a typed&stays&. FluentHorizontalBarChartwith a series repeated across rows threw a duplicate-key error; one legend per title now.
v0.0.6
fluent_2 0.0.6
Added
-
FluentBoxDecorationpaintsboxShadowthe way CSS does — outside the box
only. ABoxDecorationshadow is a blurred copy of the box drawn under
it, which a transparent box shows as a grey wash (shadow16darkens the
inside to about 76%). Upstream shadows unfilled elements routinely, so this is
the decoration for them; the blur also uses CSS's σ = blur / 2. Everything
else paints asBoxDecoration. The CarouselNav and Carousel demos use it,
which is what stopped the CarouselNav card rendering solid grey. -
Charts:
calloutPropsPerDataPointonFluentHorizontalBarChartand
FluentDonutChart, spread over the built-in reading as ChartPopover does,
andlegends/enabledWrapLinesonFluentHorizontalBarChart
(upstream'slegendProps), whose wrapped rows render each legend's
annotationBuilder.FluentChartTooltipBox, the box a cut-short axis label shows its whole
text in on hover or a touch tap.FluentChartPopover.anchorRect,FluentChartPopoverData.isCartesianand
contentMaxWidth,FluentChartHitRegion.popoverAnchor,
FluentCartesianChartProps.popoverFollowsPointerand
FluentYValueHover.shouldDrawBorderBottom.FluentChartHitRegion.hitTest(a mark hovers and clicks as its painted
shape, a circle as a circle),focusableandfollowsPointer, and
FluentCartesianSeriesDelegate.hoveredRegionAt, which names the hovered
region on the same pointer event the chart hears.FluentCartesianSeriesDelegate.activationAt, consulted on a press that
hits no region (a line chart uses it to click its stroke), and
FluentCartesianChart.onFocusedRegionChange, fired as the arrow keys move
the roving focus index and with null on blur.FluentChartPopoverData.culture(upstream'sChartPopoverProps.culture),
in which a multi-value popover formats its rows.FluentDonutChart.popoverBuilder, which replaces the popover body for
the hovered or focused datum (upstream'sonRenderCalloutPerDataPoint);
a null return keeps the default body.FluentLineChart.eventAnnotationStrokeColor,eventAnnotationLabelColor
andeventAnnotationLabelWidth(upstream's
eventAnnotationProps.labelWidth, default 105), forwarded to the event
annotation layer.FluentCartesianChartProps.copyWith(useUTC:).FluentChartImageExportertakesclipHeight,continuationKeyand
continuationX, which the declarative chart's export uses to draw every
legend and a table's whole grid.
-
Components:
FluentSplitButton.menuExpandedand an optionalchild(an icon-only
primary half);FluentMenuTriggerScope, through whichFluentMenu
scopes its open state to its trigger so the split button's chevron half
takes its Selected tokens and announces expanded.FluentFocusRing's inset mode, andFluentButtonStyle.focusRingInsets,
focusRingInnerColorandshadow(upstream's ring sits inside the
button; primary adds a white inner ring andshadow2).FluentSpinnerPainter.textDirection(the arc mirrors in RTL),
FluentSpinnerMotion.reducedRotation,FluentSpinnerPose.reducedand
tailFades.FluentInputStyle.focusUnderlineWidth, the focus bar's thickness.FluentDatePickerValidationResult.message, theerrorStrings(or
ambient locale) text for the error, for aFluentFieldto show.FluentCalendarPanel.slideProgressandslideForwards.FluentButton.activeIcon(upstream'sbundleIconfilled glyph, shown
while a subtle or transparent button is hovered or pressed; also on
FluentCompoundButton) andFluentButton.menuIcon(MenuButton's chevron
slot: 12, or 16 at large, 4 after the label, in the label colour).FluentButtonStyle.iconColor,menuIconSizeandanimationDuration.FluentLinkUnderline, which paints a link's underline as a crisp 1px
line under every line of the label.FluentCarouselNavAppearance,FluentCarousel.navAppearanceand
FluentCarouselStep.appearance(upstream's brand CarouselNav).FluentTreeItem.aside, the always-visible trailing slot.FluentInteractive.disabledMouseCursorandpressedRequiresHover
(upstream's:hover:active).FluentInteractionTag.activeIcon, the filled glyph an outline tag shows
while hovered or pressed, andFluentTagStyle.iconColor.
Changed
- Requires
fluent_2_core0.0.4, which keepsFluentApp's tree when it
rebuilds after the fonts load and corrects eight palette tokens to Fluent UI
React v9 (lavender avatars no longer render navy). - Chart prop spellings fixed; the old names are deprecated, not removed.
showXAxisLablesTooltip,wrapXAxisLables,rotateXAxisLables,
showYAxisLablesandshowYAxisLablesTooltipon
FluentCartesianChartProps(andresolveShellXAxisTickPadding's
parameter) are now*Labels, andxAxistickSizeon
FluentCartesianChartPropsandFluentXAxisParamsisxAxisTickSize.
Each old name stays as a@Deprecatedconstructor argument, getter and
copyWithargument that forwards to the new one, so 0.0.5 code compiles. - Deprecated:
FluentChartLegendRow.listLength(now optional; Flutter
has noaria-setsizesemantics to carry it) and
FluentCartesianChartProps.enableFirstRenderOptimization(the port always
lays out with real constraints, so there is no first frame to skip). Both
were already ignored. tickPaddingis honoured. A caller'sFluentCartesianChartProps .tickPaddingused to be read only as a truth test (25 painted a 5 gap, 0
gave 10), copying a JavaScript precedence slip; it is now
tickPadding ?? (tooltip ? 5 : 10).- Button geometry follows upstream in Chrome (every
FluentButton): a
1px border that takes layout space on every appearance, labelled buttons
floored at 64/96/96 wide, icon-only buttons a 24/32/40 square with 1/5/7
padding, the focus ring inside the button, and a menu button's label and
chevron centred as one group. The legend's "+N more" button grows to the
floor as well. FluentSplitButtonmatches upstream: icon-only chevron half (large is
31 wide, the chevron 1px low as upstream's svg sits), the divider's tokens
per appearance and state, the open-menu Selected state, a whole-pixel
seam, and the edges drawn with CSS border geometry — a circular split
button is now a stadium, not two ellipses, and the outline no longer
notches at the seam.FluentSpinnermoves like react-spinner 9.4+ (two conic wedges behind
a mask) instead of the old stroke-dasharray keyframes: the arc grows from
30° to 255° and back with no snap at the cycle boundary, has flat ends,
and mirrors in RTL. Under reduced motion the ring keeps turning over 1.8s
with a fixed, fading comet tail, as upstream does, instead of freezing.
The ring repaints on its ownRepaintBoundary.FluentGanttChart's date axis honoursuseUtc(it built a local time
scale while the popover read UTC);props.useUTC ?? useUtcnow feeds both,
and onlytrueor'utc'enable UTC.FluentDataGridheaders and rows follow upstream: a sortable header is
one interactive surface with the subtle hover and press fill, a bare 12px
arrow shown only while it holds the sort (an unsorted column draws none,
keeping an empty slot), and regular-weight labels; a pressed row fills
subtleBackgroundPressed; a cell's focus ring shows for keyboard focus
only.- Nav rows follow the storybook: labels stay
neutralForeground2in
every state, a held plain row keeps the hover fill, and split-row
secondary actions fade in over the row end on hover, press or focus, so
the label keeps its width. - Horizontal bar rows fit their gaps. A row of n bars used to run
(n − 1) × 3px past its edge (past the start in RTL); bars now shrink into
the room the gaps leave, and a zero-width bar takes no gap
(FluentHorizontalBarRowLayout.compute, newabsoluteLabelIndex). - BREAKING (custom styles):
FluentInputStyle.borderWidth,
bottomBorderColorandbottomBorderWidthnow describe a real CSS-style
border. The border takes space and the content row sits inside it, on top
ofpadding— the bottom side used to be a rule overlaid on the box's bottom
edge that cost no layout. A nullborderColormeans no border and no inset
whateverborderWidthsays; a nullbottomBorderColormeans the bottom
followsborderColor. A custom style that set a wide bottom rule, or relied
on the border not moving the text, will lay out differently. The same holds
for the bottom-side fields ofFluentSearchBoxStyle,FluentTextareaStyle,
FluentSpinButtonStyle,FluentDropdownStyle,FluentTagPickerStyle,
FluentDatePickerStyleandFluentTimePickerStyle. - BREAKING (sibling APIs), each to match upstream:
FluentSpinButtonBaseState.inertis gone — read-only no longer styles the
surface, only the steppers go inert;FluentSpinButtonChevronPainterno longer takesglyphSizeor
strokeWidth: it fills upstream's 14px svg path;FluentTextarea.maxLines: nullholds the field atminLinesrows and
scrolls, as upstream'srowsdoes; passmaxLinesto let it grow;FluentTimePickerStyle.trailingGapis now the space between the text
field and the trailing glyph, andtrailingPaddingthe inset around the
text field;FluentDropdownandFluentTimePickertake upstream's 250px minimum
width;FluentTagPickerdraws upstream's expand chevron by default (expandIcon,
fluentTagPickerChevron), is 34/42/46 tall, and has 32px option rows and
upstream-sized tags;FluentTagDismissPainter.inkRatiois gone: the dismiss glyph fills
upstream'sDismissRegularpath instead of a scaled cross;FluentSpinButtonStepperis now aStatefulWidget(it repeats while
held).
- **...
v0.0.5
Fixed
Selected text stayed highlighted after clicking away from a field. Flutter hides a selection in exactly one way — by handing EditableText a null selectionColor. Blur does none of the work itself: _handleFocusChanged leaves controller.selection alone and RenderEditable's highlight painter draws from (range, colour) with no focus term, so a control that keeps passing a colour keeps painting the selection after the pointer has gone elsewhere. Focus was dropping correctly all along; only the paint outlived it. FluentInput (and so FluentDatePicker, FluentTimePicker and FluentTagPicker, which share buildFluentInput), FluentTextarea and FluentSearchBox now gate the colour on real focus, the way TextField and CupertinoTextField both do and FluentSpinButton already did. FluentSearchBox had a guard on enabled && !readOnly, which is true for an ordinary field's whole lifetime — it read as a gate in a diff and did nothing at runtime; both terms are now applied.
Pressing a field's own chrome dropped its focus. The padding, the border and the contentBefore/contentAfter slots are built around the EditableText, so they fall outside the TextFieldTapRegion it installs for itself and a pointer-down there ran _EditableTextTapOutsideAction. The selection gesture detector handed focus back on pointer-up, so it read as a flicker rather than a fault — but a focus-reactive slot unmounts under the cursor between press and release, and a spin button's steppers are outside the field too, so every increment blurred it. buildFluentInput, FluentTextarea, FluentSearchBox and FluentSpinButton now each wrap their faceplate, as TextField wraps its decoration. All use the default group id, so the pickers wrapping the result again for their popups stays a no-op.
Changed
Blurring a Fluent text control now collapses its selection, rather than only hiding the highlight. Material and Cupertino keep the range and restore it on refocus; these controls deliberately do not, so returning to a field lands a caret where the selection ended. The value is never touched — only controller.selection — but an application that reads a selection back from its own controller after the field has lost focus will now find it collapsed.
collapseFluentSelectionOnBlur is new. An internal helper in lib/src/internal/text_selection_dismiss.dart, called from the focus listener each control already owned. It writes as little as it can: nothing while focused, nothing for an invalid or already-collapsed range, and it clamps the caret to the current text — TextEditingController.selection's setter throws rather than asserts past text.length, so that guard holds in release too. FluentDatePicker and FluentTimePicker key it to focus leaving the whole control, not just the field, so an open calendar or listbox keeps its range.
v0.0.4
fluent_2 0.0.4
fluent_2
- Fix: a popup opened from inside a
FluentPopovercollapsed the popover on the first click - Affected controls now adopt the enclosing tap group: dropdown, tag picker, date/time pickers, info button, breadcrumb overflow, menu
- New internal helper
adoptFluentTapGroup(tap_group.dart)
Full changelog: https://github.com/B1Digital/fluent_ui_2_flutter/blob/main/packages/fluent_2/CHANGELOG.md
v0.0.3
fluent_2 0.0.3 / fluent_2_core 0.0.3
Published to pub.dev:
fluent_2_core
- Fix status token parity with Fluent UI React v9 (dark statusSuccessForegroundInverted, statusWarningForeground1/3, statusWarningBorder1)
- Add react-token parity test (228 alias tokens across 4 theme variants)
- FluentScrollBehavior now supplies a scrollbar
fluent_2
- Switch track width fix inside FluentField
- Input layout/a11y fixes (date/dropdown/info/tag/time pickers, swatch picker)
- Breadcrumb and menu fixes
- Regenerated golden images
v0.0.2
Highlights
- Adds FluentColorPicker, FluentColorArea, FluentColorSlider, and FluentAlphaSlider.
- Fixes FluentSlider touch dragging inside scrolling ancestors.
- Removes the obsolete FluentSpinButtonUnderlinePainter API.
- Uses the Fluent 2 Flutter logo as the pub.dev thumbnail for all eight packages.
- Aligns all package versions and internal constraints at 0.0.2.
Validation
- Full workspace CI passed: analysis, formatting, architecture invariants, license checks, and all Flutter tests.
- All eight pub.dev release archives validate cleanly.