-
-
Notifications
You must be signed in to change notification settings - Fork 622
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
Provide available terminal space #5
Comments
I think figuring this out would also solve the nested-div-newline problem. |
Perhaps this is overcomplicating things, but introducing a
Is this something you'd be interested in? |
I think this is definitely interesting, but might be an overkill for now. I still hope there will be a simple solution to that issue. |
I'd like to give this one a try. What exactly are we looking for? Should it be that every element past the first one should render in less space than the entire terminal based on the previous elements? Should that happen for elements in a Also, would it make sense to automatically cut anything that goes over the terminal length for each line (instead of creating another line)? Or just let the developer take care of making sure all lines are shorter than the total available space? |
I thought each component would have access to these props:
I think exposing these props would allow components to calculate the available space in the current row. Ink would also have to rerender the tree whenever terminal is resized. This is ideal implementation, but might be complex to implement.
I think all elements should have access to these props.
I think given the props above, developer should decide themselves whether to cut the output or not. I just had an idea to perhaps simplify the first implementation and experiment: <SpaceAware>
<SpaceAware.Item>
<Color red>Progress: </Color>
</SpaceAware.Item>
<SpaceAware.Item>
{({ spaceAvailable }) => (
<ProgressBar width={spaceAvailable} value={0.5}/>
)}
</SpaceAware.Item>
</SpaceAware> Naming isn't final of course, but the idea is this: @karaggeorge @sindresorhus What do you think? |
@vadimdemedes I'm a bit confused with the It might be also weird to use The Another idea might be having the components pass a |
You can get the available space using I think having a Let me play with my idea and see if it even works. I'll submit it as a PR and ping you. |
that would be true only if the component is the last one on the line, right? |
Yes, I totally missed that, good catch. |
@karaggeorge I implemented my idea but indeed is limited to 2 components on one row, side by side. I rethinked your idea with flex and I think it's the best way to solve this. My idea is to implement an alternative of CSS flexbox in Ink. That way layout is clearly determined and straightforward to understand. My thoughts: // Progress: [======] (ProgressBar takes all the available space)
<Box>
<Box>
Progress:
</Box>
<Box flex={1}>
<ProgressBar/>
</Box>
<Box>
15%
</Box>
</Box> <Box height={20} alignItems="center" justifyContent="center">
<HelloWorld/>
</Box> It's indeed going to be a basic reimplementation of CSS flexbox, but using rows and columns instead of px. |
@vadimdemedes Yeah, CSS flexbox is where I got that idea. I think it would make sense in this case, and it solves a couple of problems. What are you thinking about a full set of props? I was thinking just the I'm wondering about the height. How would that display with the children of that element? Would it be a new line before and after the box? Like a div with a set height? |
I think we should start with the minimum set first and expand over time.
Exactly 🙂 |
@vadimdemedes
or |
@karaggeorge Sorry for late response. I thought we could go with #5 (comment) to provide a complete layout solution. I tried implementing |
@vadimdemedes Does it make sense to explore |
@marionebl I guess this means that Ink will have to include a native dependency, which I'd like to avoid. |
Yoga has an asm.js build for browsers, which we could use in Node.js to not need a native dependency: https://github.com/facebook/yoga#build-platforms |
I tried to implement something similar. export function AppTitle(props: Props) {
const text = props.children;
const width = props.width;
const middle = Math.floor((width - text.length)/ 2) + text.length;
return (
<Color bgBlue white bold>
{text.padStart(middle, ' ').padEnd(width, ' ')}
</Color>
);
} Works like a charm. But there's a problem (of course), and it's that the component is rendered multiple times instead of being replaced (probably a different issue #153 ?) |
Going to close this issue, as there's a |
I'm curious how this is implemented under the hood: How does ink get the number of rows/cols for the current tty, and detect when that changes? I'm currently interested in serving Ink sessions over a custom SSH server. The SSH protocol gives the the rows/cols of the user's terminal, but it's not clear to me how to pass these values to Ink's |
See #3 (comment).
The problem is demonstrated perfectly when rendering a progress bar:
In order to render a progress bar that takes entire terminal space (width),
<ProgressBar>
needs to know how much space<Label>
takes.I'm short of ideas on how to implement this properly, so any thoughts are welcome!
The text was updated successfully, but these errors were encountered: