show filter-box placeholders + make the search icon optional
The Search tab's Find mode stacked four ClideFilterBoxes (search, replace, include, exclude) that all looked identical: every box drew the magnifying glass and the hint was only a semantics label, never visible text — so they read as four blank search boxes. Render the hint as placeholder text while empty, and make the leading icon optional (the replace + glob fields pass icon: null). General win — every filter box now shows its placeholder. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ class ClideFilterBox extends StatefulWidget {
|
||||
this.hint = 'Filter…',
|
||||
this.debounce = const Duration(milliseconds: 200),
|
||||
this.onSubmitted,
|
||||
this.icon = PhosphorIcons.magnifyingGlass,
|
||||
});
|
||||
|
||||
final ValueChanged<String> onChanged;
|
||||
@@ -20,6 +21,10 @@ class ClideFilterBox extends StatefulWidget {
|
||||
final Duration debounce;
|
||||
final ValueChanged<String>? onSubmitted;
|
||||
|
||||
/// Leading glyph. Defaults to the search glass; pass null for inputs
|
||||
/// that aren't searches (e.g. a replace or glob field).
|
||||
final ClideIconPainter? icon;
|
||||
|
||||
@override
|
||||
State<ClideFilterBox> createState() => _ClideFilterBoxState();
|
||||
}
|
||||
@@ -68,18 +73,36 @@ class _ClideFilterBoxState extends State<ClideFilterBox> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 5),
|
||||
child: Row(
|
||||
children: [
|
||||
ClideIcon(PhosphorIcons.magnifyingGlass, size: 13, color: tokens.globalTextMuted),
|
||||
const SizedBox(width: 6),
|
||||
if (widget.icon != null) ...[
|
||||
ClideIcon(widget.icon!, size: 13, color: tokens.globalTextMuted),
|
||||
const SizedBox(width: 6),
|
||||
],
|
||||
Expanded(
|
||||
child: EditableText(
|
||||
controller: _controller,
|
||||
focusNode: _focus,
|
||||
style: TextStyle(fontSize: clideFontCaption, color: tokens.globalForeground),
|
||||
cursorColor: tokens.globalFocus,
|
||||
backgroundCursorColor: tokens.globalTextMuted,
|
||||
maxLines: 1,
|
||||
onChanged: _onChanged,
|
||||
onSubmitted: widget.onSubmitted != null ? (v) => widget.onSubmitted!(v) : null,
|
||||
child: Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
// Placeholder shown while empty — the hint was only a
|
||||
// semantics label before, so empty boxes looked blank.
|
||||
if (!hasText)
|
||||
IgnorePointer(
|
||||
child: Text(
|
||||
widget.hint,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: clideFontCaption, color: tokens.globalTextMuted),
|
||||
),
|
||||
),
|
||||
EditableText(
|
||||
controller: _controller,
|
||||
focusNode: _focus,
|
||||
style: TextStyle(fontSize: clideFontCaption, color: tokens.globalForeground),
|
||||
cursorColor: tokens.globalFocus,
|
||||
backgroundCursorColor: tokens.globalTextMuted,
|
||||
maxLines: 1,
|
||||
onChanged: _onChanged,
|
||||
onSubmitted: widget.onSubmitted != null ? (v) => widget.onSubmitted!(v) : null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (hasText)
|
||||
|
||||
Reference in New Issue
Block a user