Skip to content

Commit f0ebbee

Browse files
committed
Added support for percentage sizing
1 parent ac79b08 commit f0ebbee

File tree

3 files changed

+147
-44
lines changed

3 files changed

+147
-44
lines changed

demo/src/App.tsx

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ const App: React.FC = () => {
4242
<Anchor.Link href="#non-resizable" title="Non-resizable" />
4343
<Anchor.Link href="#resizable" title="Resizable" />
4444
<Anchor.Link href="#nested" title="Nested" />
45-
<Anchor.Link href="#stacked" title="Stacked" />
4645
<Anchor.Link href="#scrollable" title="Scrollable" />
46+
<Anchor.Link href="#percent" title="Percent sizing" />
47+
<Anchor.Link href="#stacked" title="Stacked" />
4748
<Anchor.Link href="#sizeinfo" title="Sizing information" />
4849
<Anchor.Link href="#changes" title="Version history" />
4950
</Anchor>
@@ -146,13 +147,13 @@ const App: React.FC = () => {
146147
</SyntaxHighlighter>
147148

148149
<Space.Fixed height={400}>
149-
<Space.Left size={200} style={{ backgroundColor: '#e0eae0' }}>
150+
<Space.Left size="20%" style={{ backgroundColor: '#e0eae0' }}>
150151
{Description("Left")}
151152
</Space.Left>
152153
<Space.Fill style={{ backgroundColor: '#eee0e0' }}>
153154
{Description("Fill")}
154155
</Space.Fill>
155-
<Space.Right size={200} style={{ backgroundColor: '#e0eee0' }}>
156+
<Space.Right size="20%" style={{ backgroundColor: '#e0eee0' }}>
156157
{Description("Right")}
157158
</Space.Right>
158159
</Space.Fixed>
@@ -186,7 +187,7 @@ const App: React.FC = () => {
186187

187188
</Tabs.TabPane>
188189
</Tabs>
189-
190+
190191
<h2 id="resizable">Resizable spaces</h2>
191192

192193
<p>
@@ -376,6 +377,75 @@ const App: React.FC = () => {
376377

377378
</Tabs.TabPane>
378379
</Tabs>
380+
381+
<h2 id="scrollable">Scrollable spaces</h2>
382+
383+
<p>
384+
By default, all spaces hide content that overflows the space. To make a particular space scrollable,
385+
set the scrollable property to true. The space will then be scrollable horizontally or vertically if
386+
the content overflows the space.
387+
</p>
388+
389+
<h2 id="percent">Percentage sizing</h2>
390+
391+
<p>
392+
Anchored spaces support sizes as percentages. The specified percentage will be used as the initial size
393+
of the space. Resizing a space will still adjust the space size.
394+
</p>
395+
396+
<Tabs defaultActiveKey="1">
397+
<Tabs.TabPane tab="Percentage left" key="1">
398+
399+
<SyntaxHighlighter language="html">
400+
{
401+
"const App = () => (\r\n" +
402+
" <Space.Fixed height={400}>\r\n" +
403+
" <Space.LeftResizable size=\"50%\" />\r\n" +
404+
" <Space.Fill />\r\n" +
405+
" </Space.Fixed>\r\n" +
406+
")"
407+
}
408+
</SyntaxHighlighter>
409+
410+
<Space.Fixed height={400}>
411+
<Space.LeftResizable trackSize={true} size="50%" style={{ backgroundColor: '#e0eee0' }}>
412+
{Description("Left 50%")}
413+
</Space.LeftResizable>
414+
<Space.Fill trackSize={true} style={{ backgroundColor: '#eee0e0' }}>
415+
{Description("Fill")}
416+
</Space.Fill>
417+
</Space.Fixed>
418+
419+
</Tabs.TabPane>
420+
421+
<Tabs.TabPane tab="Percentage left / right" key="2">
422+
423+
<SyntaxHighlighter language="html">
424+
{
425+
"const App = () => (\r\n" +
426+
" <Space.Fixed height={400}>\r\n" +
427+
" <Space.LeftResizable size=\"25%\" />\r\n" +
428+
" <Space.Fill />\r\n" +
429+
" <Space.RightResizable size=\"25%\" />\r\n" +
430+
" </Space.Fixed>\r\n" +
431+
")"
432+
}
433+
</SyntaxHighlighter>
434+
435+
<Space.Fixed height={400}>
436+
<Space.LeftResizable trackSize={true} size="25%" style={{ backgroundColor: '#e0eee0' }}>
437+
{Description("Left 25%")}
438+
</Space.LeftResizable>
439+
<Space.Fill trackSize={true} style={{ backgroundColor: '#eee0e0' }}>
440+
{Description("Fill")}
441+
</Space.Fill>
442+
<Space.RightResizable trackSize={true} size="25%" style={{ backgroundColor: '#e0eee0' }}>
443+
{Description("Right 25%")}
444+
</Space.RightResizable>
445+
</Space.Fixed>
446+
447+
</Tabs.TabPane>
448+
</Tabs>
379449

380450
<h2 id="stacked">Stacked spaces</h2>
381451

@@ -392,45 +462,37 @@ const App: React.FC = () => {
392462
{
393463
"const App = () => (\r\n" +
394464
" <Space.Fixed height={400}>\r\n" +
395-
" <Space.LeftResizable size={75} order={1} />\r\n" +
396-
" <Space.LeftResizable size={75} order={2} />\r\n" +
465+
" <Space.LeftResizable size=\"10%\" order={1} />\r\n" +
466+
" <Space.LeftResizable size=\"10%\" order={2} />\r\n" +
397467
" <Space.Fill />\r\n" +
398-
" <Space.RightResizable size={75} order={2} />\r\n" +
399-
" <Space.RightResizable size={75} order={1} />\r\n" +
468+
" <Space.RightResizable size=\"10%\" order={2} />\r\n" +
469+
" <Space.RightResizable size=\"10%\" order={1} />\r\n" +
400470
" </Space.Fixed>\r\n" +
401471
")"
402472
}
403473
</SyntaxHighlighter>
404474

405475
<Space.Fixed height={400}>
406-
<Space.LeftResizable trackSize={true} size={75} order={1} style={{ backgroundColor: '#e0eee0' }}>
476+
<Space.LeftResizable trackSize={true} size="10%" order={1} style={{ backgroundColor: '#e0eee0' }}>
407477
{Description("Left 1")}
408478
</Space.LeftResizable>
409-
<Space.LeftResizable trackSize={true} size={75} order={2} style={{ backgroundColor: '#e0eeee' }}>
479+
<Space.LeftResizable trackSize={true} size="10%" order={2} style={{ backgroundColor: '#e0eeee' }}>
410480
{Description("Left 2")}
411481
</Space.LeftResizable>
412482
<Space.Fill trackSize={true} style={{ backgroundColor: '#eee0e0' }}>
413483
{Description("Fill")}
414484
</Space.Fill>
415-
<Space.RightResizable trackSize={true} size={75} order={2} style={{ backgroundColor: '#e0eeee' }}>
485+
<Space.RightResizable trackSize={true} size="10%" order={2} style={{ backgroundColor: '#e0eeee' }}>
416486
{Description("Right 2")}
417487
</Space.RightResizable>
418-
<Space.RightResizable trackSize={true} size={75} order={1} style={{ backgroundColor: '#e0eee0' }}>
488+
<Space.RightResizable trackSize={true} size="10%" order={1} style={{ backgroundColor: '#e0eee0' }}>
419489
{Description("Right 1")}
420490
</Space.RightResizable>
421491
</Space.Fixed>
422492

423493
</Tabs.TabPane>
424494
</Tabs>
425495

426-
<h2 id="scrollable">Scrollable spaces</h2>
427-
428-
<p>
429-
By default, all spaces hide content that overflows the space. To make a particular space scrollable,
430-
set the scrollable property to true. The space will then be scrollable horizontally or vertically if
431-
the content overflows the space.
432-
</p>
433-
434496
<h2 id="sizeinfo">Getting size information for a space</h2>
435497

436498
<p>
@@ -454,27 +516,33 @@ const App: React.FC = () => {
454516

455517
<h2 id="changes">Version history</h2>
456518

457-
<p>
519+
<div>
520+
<strong>0.1.4</strong>
521+
<ul>
522+
<li>Add support for percentage sizing on anchored spaces</li>
523+
</ul>
524+
</div>
525+
<div>
458526
<strong>0.1.3</strong>
459527
<ul>
460528
<li>Added readme</li>
461529
<li>Updated documentation</li>
462530
</ul>
463-
</p>
464-
<p>
531+
</div>
532+
<div>
465533
<strong>0.1.2</strong>
466534
<ul>
467535
<li>Removed ResizeSensor from spaces by default and now optionally allow live size updates with <strong>trackSize</strong> property</li>
468536
<li>Added <strong>VerticallyCentered</strong> component to vertically centre content within space</li>
469537
<li>Allow class names to be specified on top-level spaces <strong>ViewPort</strong> and <strong>Fixed</strong></li>
470538
</ul>
471-
</p>
472-
<p>
539+
</div>
540+
<div>
473541
<strong>0.1.0 - 0.1.1</strong>
474542
<ul>
475543
<li>Initial version</li>
476544
</ul>
477-
</p>
545+
</div>
478546

479547
</Space.Fill>
480548

react-spaces/src/components/Space.tsx

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ interface ISpaceInfo {
6464

6565
const SpaceInfoContext = React.createContext<ISpaceInfo | null>(null);
6666

67+
const getSizeString = (size: string | number) =>
68+
typeof(size) === "string" ? size : `${size}px`;
69+
6770
class Space extends React.Component<AllProps, IState> {
6871
private divElementRef = React.createRef<HTMLDivElement>();
6972
private resizeSensor?: ResizeSensor;
@@ -123,19 +126,30 @@ class Space extends React.Component<AllProps, IState> {
123126
{
124127
parentContext => {
125128
const style = {
126-
left: this.state.left,
127-
top: this.state.top,
128-
right: this.state.right,
129-
bottom: this.state.bottom,
130-
width: this.isHorizontalSpace() ? (this.state.parsedSize || 0) + this.state.adjustedSize : undefined,
131-
height: this.isVerticalSpace() ? (this.state.parsedSize || 0) + this.state.adjustedSize : undefined
129+
left: (this.state.left !== undefined ? `calc(${this.state.left}px)` : undefined) as string | number | undefined,
130+
top: (this.state.top !== undefined ? `calc(${this.state.top}px)` : undefined) as string | number,
131+
right: (this.state.right !== undefined ? `calc(${this.state.right}px)` : undefined) as string | number,
132+
bottom: (this.state.bottom !== undefined ? `calc(${this.state.bottom}px)` : undefined) as string | number,
133+
width:
134+
this.isHorizontalSpace() ?
135+
`calc(${getSizeString(this.props.size || 0)} + ${this.state.adjustedSize}px)`
136+
: undefined,
137+
height:
138+
this.isVerticalSpace() ?
139+
`calc(${getSizeString(this.props.size || 0)} + ${this.state.adjustedSize}px)`
140+
: undefined,
132141
};
133142

134143
if (parentContext) {
135144
this.onRemove = () => {
136145
parentContext.removeSpaceTaker(this.state.id);
137146
}
138-
147+
148+
let adjustedTop: string[] = [];
149+
let adjustedLeft: string[] = [];
150+
let adjustedRight: string[] = [];
151+
let adjustedBottom: string[] = [];
152+
139153
[ AnchorType.Left,
140154
AnchorType.Right,
141155
AnchorType.Bottom,
@@ -153,39 +167,60 @@ class Space extends React.Component<AllProps, IState> {
153167
if (this.isFilledSpace())
154168
{
155169
if (t.anchorType === AnchorType.Top) {
156-
style.top! += t.size + t.adjustedSize;
170+
adjustedTop.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
171+
//style.top! += t.size + t.adjustedSize;
157172
} else if (t.anchorType === AnchorType.Left) {
158-
style.left! += t.size + t.adjustedSize;
173+
adjustedLeft.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
174+
//style.left! += t.size + t.adjustedSize;
159175
} else if (t.anchorType === AnchorType.Bottom) {
160-
style.bottom! += t.size + t.adjustedSize;
176+
adjustedBottom.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
177+
//style.bottom! += t.size + t.adjustedSize;
161178
} else if (t.anchorType === AnchorType.Right) {
162-
style.right! += t.size + t.adjustedSize;
179+
adjustedRight.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
180+
//style.right! += t.size + t.adjustedSize;
163181
}
164182
}
165183
else
166184
{
167185
if (t.anchorType === AnchorType.Top && style.top !== undefined) {
168-
style.top += t.size + t.adjustedSize;
186+
adjustedTop.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
187+
//style.top += t.size + t.adjustedSize;
169188
} else if (t.anchorType === AnchorType.Left && style.left !== undefined) {
170-
style.left += t.size + t.adjustedSize;
189+
adjustedLeft.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
190+
//style.left += t.size + t.adjustedSize;
171191
} else if (t.anchorType === AnchorType.Bottom && style.bottom !== undefined) {
172-
style.bottom += t.size + t.adjustedSize;
192+
adjustedBottom.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
193+
//style.bottom += t.size + t.adjustedSize;
173194
} else if (t.anchorType === AnchorType.Right && style.right !== undefined) {
174-
style.right += t.size + t.adjustedSize;
195+
adjustedRight.push(`${getSizeString(t.size)} + ${t.adjustedSize}px`);
196+
//style.right += t.size + t.adjustedSize;
175197
}
176198
}
177199
} else {
178200
break;
179201
}
180202
}
181203
});
204+
205+
if (adjustedTop.length > 0) {
206+
style.top = `calc(${adjustedTop.join(" + ")})`;
207+
}
208+
if (adjustedLeft.length > 0) {
209+
style.left = `calc(${adjustedLeft.join(" + ")})`;
210+
}
211+
if (adjustedRight.length > 0) {
212+
style.right = `calc(${adjustedRight.join(" + ")})`;
213+
}
214+
if (adjustedBottom.length > 0) {
215+
style.bottom = `calc(${adjustedBottom.join(" + ")})`;
216+
}
182217

183218
if (this.props.anchor) {
184219
parentContext.registerSpaceTaker({
185220
id: this.state.id,
186221
order: this.props.order || 1,
187222
anchorType: this.props.anchor,
188-
size: (this.state.parsedSize || 0),
223+
size: this.props.size || 0,
189224
adjustedSize: 0
190225
});
191226
}

react-spaces/src/components/SpaceContext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export interface ISpaceContext {
1515
export interface ISpaceTaker {
1616
id: Guid,
1717
order: number,
18-
anchorType: AnchorType
19-
size: number,
18+
anchorType: AnchorType,
19+
size: number | string,
2020
adjustedSize: number
2121
}
2222

0 commit comments

Comments
 (0)