-
-
Notifications
You must be signed in to change notification settings - Fork 197
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
add input component and example #205
add input component and example #205
Conversation
The reconciler is I think behaving oddly as when I try and set state in the example component it doesn't get updated correctly |
src/UI_Components/Input.re
Outdated
~children, | ||
~window, | ||
~color=Colors.black, | ||
~fontSize=18, |
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.
For some of these properties (fontSize
, color
, etc) - would it make it sense to take in a style
instead? I think the tricky thing is letting a user set Style
but having a set of default values that aren't set (and if they aren't set, they get overridden) - we don't have a good solution for that yet (but we should)
For example, I could see customizing the fontFamily
, border
, or backgroundColor
as common scenarios here too.
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.
Have you thought about using polymorphic lists instead of records for style? You could then have a common set of props and extra props per component. (and do not set values for props that are not set)
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.
@rauanmayemir @bryphe I've been thinking about that a lot recently (was going to raise an issue) as I've used https://github.com/SentiaAnalytics/bs-css which looks like -
let card = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
backgroundColor(white),
boxShadow(~y=px(3), ~blur=px(5), rgba(0, 0, 0, 0.3)),
/* You can place all your theme styles in Theme.re and access as normal Reason module */
padding(Theme.basePadding)
]);
and bs-nice which has an even nicer API imo
let className = css([|
Display(Flex),
AlignItems(Center),
Color(Red),
Select(":hover", [Color(Blue)])
|]);
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.
css
is sort of odd when it comes to styling because all style properties are accepted by all components.
Polymorphic variants allow us to have one style (a list
) used by several components at the same time, as long as the list only contains styles that are shared by them. Taking Input
and View
as an example this would work: [`BackgroundColor(c), `Width(300.)]
but this would not [`BackgroundColor(c), `ContentsAspectRatio(x)]
because aspect ratio does not make sense for View
. The actual api can be a little different, i.e. we could use functions like backgroundColor(c)
but I'm talking about types specifically now.
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.
quite new to reason but could the style
function take something like
style(ViewStyles, [/* list specific to view styles */])
and have the first argument somehow 🤔 😕 inform the type of the second, or just have different style functions for what I imagine will be a small subset of components 🤷♂️ . Although so far we don't really have that kind of variation in what nodes expect, also our current api allows for that i.e. Style.make(// all possible style arguments
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.
@Akin909 it could! Let me elaborate what we meant in more detail. When you define a shared style like let highlightedText = [`Color(red)]
you might want to use it for both an Input and normal Text. However, `Color
does not make sense for a View
for instance, which already has the background color style. Because of that I'd like to get a type error when I pass such style to a View. Now, non-polymorphic variants are nominally typed, i.e. even if you have two types like this:
type a = | A;
type a' = | A;
let f = (x: a) => x
let g = (x: a') => f(x);
g
won't compile because the two variants have nominally different types despite being identical constructors. Polymorphic variants are type checked according to their constructors so we could pass the same list with the `Color
style for multiple components even though each of them has its own style type.
src/UI_Components/Input.re
Outdated
~width=200, | ||
~height=50, | ||
~value=None, | ||
~placeholder="", |
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.
That's really neat that there is placeholder text - just tried out the demo 💯
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.
Looks great to me overall! This is awesome @Akin909, thank you!
Just had a question about the plan for styling this custom component. I'm wondering how we can handle custom styling on some of these built-in components, and I think it will be particularly important for this one.
I think having a place where we can start to invest in these components is important - it's so cool to see a functional <Input />
component (with blinking cursor and everything!) come together.
@bryphe I've played around with this a little trying to work with Not sure where you land on this but I think a list of functions or types as discussed above is a much easier to work with api, but would involve a larger scale change (if you agree), in which case for the time being I can pass in a subset of the style props optionally for this PR and look at the bigger change separately |
59d262b
to
8b56a46
Compare
@bryphe I've made some tweaks to this in response to your feedback and commented a bit above about the why I've gone this way a bit more. Lemme know what you think |
40dc007
to
8d29986
Compare
examples/Examples.re
Outdated
@@ -97,11 +97,18 @@ let reducer = (s: state, a: action) => { | |||
let init = app => { | |||
let maximized = Environment.webGL; | |||
|
|||
let size = Monitor.getPrimaryMonitor() |> Monitor.getSize; |
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 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.
@bryphe no worries can change that back. On my machine it opens as a really small window in the corner and when I go to maximize it crashes due to the resize bug, thought it was a "bug" that it didn't open with a larger size
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.
Reverted 👍 @bryphe
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.
Hmm, strange - sounds like a bug! Would you mind logging an issue with a screenshot? Would be nice to also include the display + machine details. There might be other high-dpi issues that haven't been addressed - hopefully we can address them in a holistic way.
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.
Will do 👍
/* | ||
TODO: Setting the hook to run only on mount means that the onChange | ||
handler is only called with a stale version of state | ||
BUT setting the value to ALWAYS causes one handler to to seize |
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.
Interesting! This sounds like a bug. What does it mean by causes one handler to seize control of event listening?
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 other handler doesn't respond at all it's almost as if only one handler is registered, I only noticed when I added the second input example basically with Always
set the key events registered for any other component that implements a handler for the same event aren't called / don't respond.
) => | ||
component(slots => { | ||
let initialState = {value, placeholder, isFocused: false}; | ||
let (state, dispatch, slots) = |
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.
Nice use of the new hooks API!
src/UI_Components/Input.re
Outdated
<Text style=innerTextStyles text=content /> | ||
/* | ||
TODO: | ||
1. Show and hide cursor based on focus |
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.
Nice progress!
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 cursor bit is actually tied to having mouseover and mouseout, what I meant by the remaining comment there is that the mouse cursor currently responds to clicks but not to mousing over (although that's not actually browser behaviour so think the comment is invalid)
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 just checked and the cursor doesn't appear or disappear in a browser based on mousing over or out only as a result of clicking in or out
Sorry for the delay on reviewing this @Akin909 ! The Thank you for thinking about the I only had one piece of feedback - can we leave the example size as-is for now? Or is there a reason it needs to be maximized for the sample? Thanks for the work on this! It's great progress (will be very useful for Oni2 also - we need this for the command palette / quick open / etc) |
Remove no longer relevant comment from input
6640759
to
d6e382e
Compare
This fixes the input component example which #205 broke, it involves having to pull values out of the style list which I wanted to create a sort of *getter* for but having done a bit of reading and wrangling with the compiler doesn't seem straight forward, typing gets a little tricky with variants will keep it in mind and revisit once I've leveled up my reason/ocaml know-how (tracked by #239)
This is a v. basic implementation of an input component there's a fair bit that could be added (down the line I think) like some padding, Events (mouse, focus etc), but this is a starting point for that.
Updated
Issues/Bugs discovered
Always
means that a handler is never missed, example