plinth_components 0.10.0
plinth_components: ^0.10.0 copied to clipboard
Themeable, accessible Flutter widgets for Plinth UI.
Changelog #
All notable changes to this package will be documented in this file.
The format follows Keep a Changelog,
and this project intends to adhere to Semantic Versioning
once it reaches a 1.0.0 release. Versions before 1.0.0 may include
breaking changes without a major version bump.
0.10.0 #
Changed #
-
PlinthTablecells are now widgets. Its own doc comment had said "cells are plain strings; there's no per-cell custom-widget escape hatch yet — flag if you need that", and building a members table for the showcase is what flagged it: a status column wants a badge, an actions column a button, a person column an avatar.The default constructor takes
List<List<Widget>>. Existing string tables becomePlinthTable.text(...), which keeps themconstand avoids wrapping every value — a one-word change at each call site, rather than the churn of a singleObject-typed cell.A bare
Textin a widget cell inherits the table's size and text colour, so it lines up with the styled cells beside it. Rows now align vertically centred, since mixed-height cells are the reason widget cells exist.Note that columns share the available width, so a cell is width-bounded: a
Rowinside one needs aFlexibleorExpandedaround anything that can grow. The showcase smoke test caught exactly that while the first version of the members table was being written.
0.9.0 #
Added #
PlinthFileInput<T>— a file field that does not open a picker. Flutter has no built-in one, and takingfile_pickerorfile_selectoras a dependency would push it onto every app using any part of this library, for one component. SoonPickis the caller's: open whichever picker you use, return what it gives you, and this renders the field, the chips, the remove affordances, and the error state.Tis your own file type, so nothing needs converting.PlinthTagsInput— free-text entry producing removable chips, the counterpart toPlinthMultiSelect's fixed options. Enter or a comma commits, backspace on an empty field removes the last tag, and duplicates are rejected by default.PlinthAutocomplete— a text field with suggestions. UnlikePlinthSelectit accepts anything typed; the options are a convenience rather than a constraint. Matches anywhere in an option, somailstill offersGmail, and highlights the matched run.
Fixed #
PlinthMultiSelect's dropdown anchored to the whole widget rather than to its field. The outerColumnstretches to fill a tall parent, so in one the list rendered a screen-height below the field — off the bottom of the viewport and untappable. Found while buildingPlinthAutocomplete, which had inherited the same shape from it.
0.8.0 #
Added #
PlinthCloseButton— the dismiss affordancePlinthAlert,PlinthNotification,PlinthModal, andPlinthDrawereach built inline. They had drifted apart in the process: two used a bareIconinside anInkWellwith no semantics, so a screen reader announced nothing where a sighted user saw a close button. All four now share it, and it carries aCloselabel by default.PlinthCollapse— an animated height reveal for a filter panel, an "advanced options" section, or a validation summary. Keeps its child mounted so a half-filled form survives being hidden, and excludes it from semantics and hit-testing while closed, since a clipped child is still in the tree.PlinthHighlight— text with matching substrings marked.PlinthMarkhighlights a span you have already split out; this does the splitting, which is what a search result needs. Matching is case-insensitive, preserves the original casing, and escapes its terms — a query containing.matches a full stop rather than any character.
Changed #
PlinthAccordiondeliberately does not usePlinthCollapse. It was refactored to, and three tests caught the consequence:PlinthCollapsekeeps its child mounted, which left closed panels readable by a screen reader. An accordion holds page content and should unmount it, so the original behaviour stands and the difference is now documented on both.
0.7.0 #
Fixed #
-
Palette colours are now legible. Requires
plinth_core^0.2.0.A filled button, badge, chip, indicator, or theme icon picks its label colour from its own fill instead of always using white: white on
yellowmeasured 2.12:1 and onteal1.82:1, well under the 4.5:1 WCAG AA asks for. Those labels are now dark.A palette colour used as text —
PlinthText,PlinthTitle, and thelight/outline/subtle/transparentbutton variants — resolves to a shade that actually contrasts with what's behind it, rather than a fixed shade 6.cyanmeasured 2.19:1 as text on white.In dark mode, shades mirror across the ramp, so accents lighten instead of staying dark against a dark surface —
violetmeasured 1.97:1 there.blue,red,violet,indigo,grape, andpinkalready cleared the threshold and are unchanged; thePlinthButtongolden is byte-identical. The lighter half of the palette looks different, which is the fix.Contrast assertions now run as tests in
plinth_core, so a future palette or token change fails rather than quietly regressing.
0.6.1 #
Fixed #
-
Long labels overflowed instead of wrapping.
PlinthCheckbox,PlinthSwitch, andPlinthRadiolaid their label out at its full intrinsic width, so a checkbox reading "I agree to the terms of service" inside a narrow form painted overflow stripes rather than wrapping to a second line — the consent checkbox being the case where long labels are most common. -
PlinthButtonhad the same problem withfullWidth: trueand aleadingIcon: the label could not shrink to the width the button was given. Reachable whenever the width is constrained rather than derived from the content, including at a large text scale.Both were found by building a realistic sign-in form for the example app's showcase, not by a component test — the components look correct in isolation and only overflow once something else constrains them.
0.6.0 #
Added #
-
Dark mode support. Every component now reads its surfaces, text, and borders from
PlinthThemetokens instead of hardcoding them, so registeringPlinthTheme.darkThemeactually restyles the library. Previously aPlinthTextInputpainted a white box with black text whatever theme you gave it — 40 of the widget files carried literal colors.The light theme's token values are the exact literals they replaced, so this changes nothing visually in light mode; the golden test confirms it.
PlinthTooltipis the one component that consultsbrightnessdirectly: it is deliberately inverted against the surface it floats over, and following the surface token would make it disappear into the background in dark mode.
Changed #
- Requires
plinth_core^0.1.0, which widens the default palette from four colors to Mantine's standard thirteen. Colors that previously fell back to the primary blue —grape,orange, and the rest — now render as themselves.PlinthMark's highlight shifts slightly, since it picks up the realyellowramp instead of its literal amber fallback.
Added #
- Behavior tests for every previously untested component, including
PlinthTextInput's border precedence, the Modal/Drawer/Popover lifecycle, and the controlled-component contract shared by Checkbox/Switch/Slider/Radio/Select. Every public component now has at least one test.
0.5.0 #
Added #
PlinthAppShell— the page scaffold: header, footer, navbar, aside, and a main region, each optional and taking no space when omitted. Collapsing is controlled by the caller rather than by an internal breakpoint, since the surrounding page needs that same state to drive aPlinthBurgeror aPlinthDrawer.PlinthGrid+PlinthGridCol— a responsive 12-column grid where each column declares its span, optionally per breakpoint. Spans apply from their breakpoint upward, so the unqualifiedspanis the smallest case, matching CSS media queries. ComplementsPlinthSimpleGrid, which is for uniform equal-width items.PlinthLoader— a standalone loading indicator inoval,dots, andbarstypes.PlinthLoadingOverlayalready showed a spinner, but only while covering existing content.PlinthTitle— semantich1–h6headings. Unlike a largePlinthText, this exposes heading semantics and level to assistive technology, so a page becomes navigable by its headings.
75 components total.
0.4.1 #
Fixed #
PlinthSpoilerreported aRenderFlexoverflow (and painted overflow stripes) whenever its collapsed content was aColumnorRowtaller thanmaxHeight— the exact case it exists to handle. The child was laid out withinmaxHeight, so a widget that manages its own overflow reported one; the surroundingClipRecthid the painting but not the error. It is now laid out at its natural height and clipped to the viewport. ATextchild was unaffected, which is why every existing usage looked correct.
0.4.0 #
Added #
PlinthFlex— direction-configurable flex layout with a consistent gap;PlinthGroupspecialized to a fixed horizontal direction,PlinthFlexfor when the direction itself needs to vary.PlinthImage— network image with an automatic loading placeholder and error fallback.PlinthScrollArea— a scrollable region with a themed, always-visible, draggable scrollbar.PlinthPortal— renders its child into the ambientOverlayrather than in place; the primitive every other overlay component in this library is already built on, exposed directly.
71 components total.
0.3.0 #
Added #
PlinthCenter— thin themed wrapper aroundCenter, for API consistency with the rest of the library.PlinthAspectRatio— thin themed wrapper aroundAspectRatio, commonly paired with images or embeds.PlinthGroup— horizontal layout with a consistent gap, wraps onto a new line by default when children overflow (unlike a plainRow, which just overflows) — the common "row of chips/tags" need.PlinthList+PlinthListItem— bulleted or numbered list, with each item able to override its own marker (e.g. a checklist mixing checkmarks and crosses).PlinthContainer— max-width content wrapper that centers its child, the standard "page content shouldn't get absurdly wide" primitive.PlinthSpace— a themed fixed-size spacer resolved throughtheme.spacing.PlinthUnstyledButton— a bare tap target with no visual chrome, for fully custom-styled clickable elements.PlinthSimpleGrid— a non-scrolling grid with a fixed number of columns and consistent spacing.
67 components total.
0.2.0 #
Added #
PlinthPinInput— segmented OTP/PIN entry, one box per character, with auto-advancing focus as digits are typed and auto-retreating focus on backspace from an already-empty box.PlinthButtonGroup— visually joins a row of buttons into one connected group (shared borders, squared-off inner corners).PlinthOverlay— generic dimming backdrop, distinct fromPlinthLoadingOverlay(which always shows a spinner and always blocks pointer events) — this is the more general primitive for dimming a background without necessarily blocking interaction.PlinthVisuallyHidden— content visible to screen readers but not sighted users, for supplementary context on icon-only controls.
59 components total.
0.1.0 #
Added #
PlinthBurger— animated hamburger→X toggle icon.PlinthHoverCard— hover-triggered anchored panel (desktop/web), the same underlyingCompositedTransformTarget/Followertechnique asPlinthPopoverbut with its own implementation, since a hover trigger and a "stay open while the pointer travels onto the panel" grace period don't fitPopover's tap-based design.PlinthRangeSlider— dual-thumb range slider, wrapping Flutter's built-inRangeSlider(same rationale asPlinthSlider).PlinthMultiSelect<T>+PlinthMultiSelectOption<T>— multi-value select with removable chips in the field and a dropdown to add more.
55 components total.
0.0.1 — Initial development release #
51 themeable components, all reading color/spacing/radius from a single
PlinthTheme (plinth_core). See docs/COMPONENTS.md in the repository
for the full prop reference.
Primitives #
PlinthButton, PlinthActionIcon, PlinthBox, PlinthText,
PlinthDivider, PlinthKbd, PlinthCode, PlinthMark.
Forms #
PlinthTextInput, PlinthTextarea, PlinthPasswordInput,
PlinthCheckbox, PlinthRadio / PlinthRadioGroup, PlinthSelect,
PlinthSegmentedControl, PlinthNumberInput, PlinthChip,
PlinthRating, PlinthSlider, PlinthSwitch.
Feedback #
PlinthBadge, PlinthAlert, PlinthProgress, PlinthRingProgress,
PlinthNotification, PlinthSkeleton, PlinthSpoiler,
PlinthLoadingOverlay.
Data Display #
PlinthAvatar, PlinthThemeIcon, PlinthIndicator,
PlinthColorSwatch, PlinthTable.
Navigation #
PlinthTabs / PlinthTabView, PlinthAccordion, PlinthStepper,
PlinthBreadcrumbs, PlinthPagination, PlinthTimeline,
PlinthNavLink.
Surfaces #
PlinthPaper, PlinthCard, PlinthBlockquote, PlinthAnchor,
PlinthCopyButton.
Overlays #
PlinthModal, PlinthDrawer, PlinthPopover, PlinthMenu,
PlinthTooltip, PlinthAffix.
Notes on this release #
PlinthMarkandPlinthCode's single positional content field is namedlabel, matchingPlinthBadge/PlinthKbd/PlinthAnchor's convention for the same pattern (found and fixed during an API consistency pass — see the main README's "API consistency review" section for the full audit).- Golden (visual regression) test coverage currently exists only for
PlinthButton— other components have behavior tests but not appearance tests yet. - Widgetbook gallery entries use static per-variant use cases rather than interactive knobs; the knob API wasn't verified against a live SDK during initial development.