-
-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve text field input #27
Conversation
…ngs & checking methods. Add mark or checkmark image for feedback on valid text input. Fix SwiftLint warnings.
Thanks for working on this. I don't think this is the right approach though. Here's what I'm thinking:
I'm also not a big fan of the symbols. We don't need a success indication, just a failure one. So I think just coloring the text red if it's invalid is enough. |
Ok, I'll work on that and update accordingly
I didn't realize all the logic was already there 😅 Thanks for pointing this out !
Ok, simple and straightforward is good 😄 I'll update accordingly |
…r text input validation. Keep SwiftLint warning fixes.
…ndition to change text color if color code is invalid. Add condition to limit character input. Add textColor to NativeTextField for use in updateNSView method. Update other ColorViews to use textColor.
So this is still WIP, but some feedback to know if this is more inline with the proposed approach would be nice 😃 As for hex codes: they are limited to a small set of characters and also in length, I've added some code to filter and trim hex inputs (ex: #123456, FFFFFF, etc). This helps users input only valid hex codes but also makes the input rigid and removes the need to indicate (in red) an invalid input. Maybe a compromise of just trimming excess characters without filtering is a good balance ? |
… Add hsl ColorInputView to ColorPickerScreen. Update comments.
Color Picker/ColorPickerScreen.swift
Outdated
case rgb = "RGB" | ||
case lch = "LCH" | ||
} | ||
var colorKeyboardShortcut: KeyEquivalent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be on a private extension on the ColorFormat
enum, placed in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved keyboardShortcut
into an extension of ColorFormat
within ColorPickerScreen
.
Would it be better to centralise this extension in Constants
as not to have class extensions in different files ? or is it better to keep here, in order to limit access control of extension to this file only ?
Yes, it's the correct direction. |
Trimming whitespace is ok, but I don't think we should prevent some characters. Users will not understand that it's because it's not valid Hex. I think it's better to just make it red in that case. |
On user color input,
What's your opinion on this @sindresorhus ? |
…properties. Move updateColorsFromPanel method to AppState. Refactor ColorInputView & ColorPickerScreen to use @published properties from AppState. Delete unused textColor variable. Update comments.
@Published var hslColor = "" | ||
@Published var rgbColor = "" | ||
@Published var lchColor = "" | ||
@Published var isPreventingUpdate = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these moved to AppState? AppState is for state that is required globally. This state is only needed for picker screen. I think you can just pass updateColorsFromPanel
to the ColorPickerScreen
view.
@@ -127,22 +127,149 @@ private struct BarView: View { | |||
} | |||
} | |||
|
|||
struct ColorInputView: View { | |||
@EnvironmentObject private var appState: AppState | |||
@State private var textColor: Color = .primary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to use an optional and default to nil
.
textColor: textColor | ||
) | ||
.controlSize(.large) | ||
.onChange(of: inputColorText) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the body out into a private function on the view. It makes it easier to see just the view logic.
|
||
if !appState.isPreventingUpdate { | ||
appState.updateColorsFromPanel(excludeLCH: true, preventUpdate: true, color: colorPanel.color) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of duplicated logic in each case here. Would be good to reduce that.
For example, appState.updateColorsFromPanel
could be updated to accept an enum instead of excludeLCH: true
type parameters.
ColorInputView( | ||
inputColorText: $appState.lchColor, | ||
isTextFieldFocused: $isTextFieldFocusedLCH, | ||
colorPanel: colorPanel, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The color panel is available on the AppState, so you can access it from there instead.
isTextFieldFocused: $isTextFieldFocusedLCH, | ||
colorPanel: colorPanel, | ||
textFieldFontSize: textFieldFontSize, | ||
inputColorType: .lch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parameter should be first.
.keyboardShortcut("l", modifiers: [.shift, .command]) | ||
} | ||
} | ||
|
||
var body: some View { | ||
VStack { | ||
BarView() | ||
if shownColorFormats.contains(.hex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just loop over the enum instead of manually defining each view. That was the point of extracting it into a reusable view.
@@ -1021,6 +1021,7 @@ struct NativeTextField: NSViewRepresentable { | |||
var isFirstResponder = false | |||
@Binding var isFocused: Bool // Note: This is only readable. | |||
var isSingleLine = true | |||
var textColor: Color |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Should be below font
.
@State private var hexColor = "" | ||
@State private var hslColor = "" | ||
@State private var rgbColor = "" | ||
@State private var lchColor = "" | ||
@State private var isTextFieldFocusedHex = false | ||
@State private var isTextFieldFocusedHSL = false | ||
@State private var isTextFieldFocusedRGB = false | ||
@State private var isTextFieldFocusedLCH = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a single state that accepts an optional ColorFormat
.
68fbb92
to
cf553c1
Compare
1fe36bd
to
189b45f
Compare
Closing for lack of activity. |
Hi @sindresorhus
This PR is a first draft for issue #3 Validate text fields
I first tried a border color for the hex text field but it interfered with blue border when the text field is focused. Instead I added a SF symbol image that switches depending if the field is valid.
The implemented colorChecker class uses ObservedObject and the onChange modifier to run on user input, it also trims unwanted characters.
The code still needs to be implemented for hsl, rgb & lch text inputs. Also needs cleaning, optimizing & testing but I wanted an initial 👍 before going ahead.
Regards
PS : I have more experience with iOS app development, this is helping me get to grips with Mac app development 😄