Skip to content

Commit 3f1910c

Browse files
Merge pull request #501 from macintoshhelper/feat/artboard-dimensions
useWindowDimensions hook for Artboard viewport
2 parents a782a10 + 7292d64 commit 3f1910c

File tree

5 files changed

+145
-12
lines changed

5 files changed

+145
-12
lines changed

docs/API.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- [`<Svg>`](#svg)
1212
- [`<Text>`](#text)
1313
- [`<View>`](#view)
14+
- [`Hooks`](#hooks)
15+
- [`useWindowDimensions`](#usewindowdimensions)
1416
- [`Platform`](#platform)
1517
- [`OS`](#os)
1618
- [`Version`](#version)
@@ -25,7 +27,7 @@
2527
- [`create`](#createstyleoptionsstyles)
2628
- [`resolve`](#resolvestyle)
2729
- [`Symbols`](#symbols)
28-
- [`makeSymbol`](#makesymbolnode-name)
30+
- [`makeSymbol`](#makesymbolnode-props-document)
2931

3032
### `render(element, container)`
3133

@@ -147,9 +149,11 @@ Wrapper for Sketch's Artboards. Requires a [`<Page>`](#page) component as a pare
147149
| `name` | `String` | | The name to be displayed in the Sketch Layer List |
148150
| `children` | `Node` | | |
149151
| `style` | [`Style`](/docs/styling.md) | | |
150-
| `viewport` | `Viewport` | | Object: { name: string, width: number, height: number} |
152+
| `viewport` | `Viewport` | | Object: { name: string, width: number, height: number, scale?: number, fontScale?: number } |
151153
| `isHome` | `Boolean` | | Is prototype home screen if true |
152154

155+
The `scale` and `fontScale` attributes in the `viewport` prop are not used by Sketch, but can be used together with the [`useWindowDimensions`](#usewindowdimensions) hook for conditional styling/rendering.
156+
153157
#### Examples
154158

155159
Hello world with width of 480px.
@@ -382,6 +386,61 @@ View primitives
382386
</Document>
383387
```
384388

389+
## Hooks
390+
391+
### `useWindowDimensions()`
392+
393+
Returns the window dimensions of the parent `<Artboard>`. Returns `{ width: number, height: number, fontScale: number, scale: number }`.
394+
395+
#### Example
396+
397+
```js
398+
import { Page, Artboard, View, Text, useWindowDimensions } from 'react-sketchapp';
399+
400+
const HomePage = () => {
401+
const { height, width } = useWindowDimensions();
402+
403+
return (
404+
<View style={{ flex: 1 }}>
405+
<View style={{ height, width }}>
406+
<Text>Hello World</Text>
407+
</View>
408+
{(width >= 768) && (
409+
<View style={{ height, width, backgroundColor: 'blue' }}>
410+
<Text style={{ color: 'white' }}>
411+
You can only see this text on tablet/desktop
412+
</Text>
413+
</View>
414+
)}
415+
</View>
416+
);
417+
};
418+
419+
const devices = [{
420+
name: 'Mobile',
421+
width: 360,
422+
height: 640,
423+
}, {
424+
name: 'Tablet',
425+
width: 768
426+
height: 1024,
427+
}, {
428+
name: 'Desktop',
429+
width: 1024
430+
height: 1280,
431+
}];
432+
433+
render(
434+
<Page style={{ flexDirection: 'row' }}>
435+
{devices.map(viewport => (
436+
<Artboard viewport={viewport} style={{ marginRight: 80 }}>
437+
<HomePage />
438+
</Artboard>
439+
))}
440+
</Page>,
441+
);
442+
```
443+
385444
## Platform
386445

387446
### `OS`
@@ -734,7 +793,7 @@ export default () => {
734793
};
735794
```
736795

737-
####Nested symbol + override example
796+
#### Nested symbol + override example
738797

739798
```js
740799
import sketch from 'sketch';

src/components/Artboard.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ import * as PropTypes from 'prop-types';
33
import { or } from 'airbnb-prop-types';
44
import StyleSheet from '../stylesheet';
55
import ViewStylePropTypes from './ViewStylePropTypes';
6+
import { ArtboardProvider } from '../context';
67

78
const ViewportPropTypes = {
89
name: PropTypes.string,
910
width: PropTypes.number,
1011
height: PropTypes.number,
12+
scale: PropTypes.number,
13+
fontScale: PropTypes.number,
1114
};
1215

1316
export const ArtboardPropTypes = {
@@ -28,15 +31,18 @@ export default class Artboard extends React.Component<Props> {
2831
};
2932

3033
render() {
34+
const style = StyleSheet.flatten(this.props.style);
3135
return (
32-
<sketch_artboard
33-
style={StyleSheet.flatten(this.props.style)}
34-
name={this.props.name}
35-
viewport={this.props.viewport}
36-
isHome={this.props.isHome}
37-
>
38-
{this.props.children}
39-
</sketch_artboard>
36+
<ArtboardProvider viewport={this.props.viewport} style={style}>
37+
<sketch_artboard
38+
style={style}
39+
name={this.props.name}
40+
viewport={this.props.viewport}
41+
isHome={this.props.isHome}
42+
>
43+
{this.props.children}
44+
</sketch_artboard>
45+
</ArtboardProvider>
4046
);
4147
}
4248
}

src/context.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as React from 'react';
2+
import * as PropTypes from 'prop-types';
3+
4+
import { Style } from './stylesheet/types';
5+
6+
const initialArtboardState = {
7+
width: 0,
8+
height: 0,
9+
scale: 1,
10+
fontScale: 1,
11+
};
12+
13+
const ArtboardContext = React.createContext({
14+
state: initialArtboardState,
15+
});
16+
17+
export const useWindowDimensions = () => {
18+
const { state } = React.useContext(ArtboardContext);
19+
const { width, height, scale, fontScale } = state || {};
20+
21+
return { width, height, scale, fontScale };
22+
}
23+
24+
const ArtboardPropTypes = {
25+
viewport: PropTypes.shape({
26+
width: PropTypes.number,
27+
height: PropTypes.number,
28+
name: PropTypes.string,
29+
scale: PropTypes.number,
30+
fontScale: PropTypes.number,
31+
}),
32+
children: PropTypes.node,
33+
};
34+
35+
type ArtboardProps = PropTypes.InferProps<typeof ArtboardPropTypes> & {
36+
children: any,
37+
style?: Style,
38+
};
39+
40+
export const ArtboardProvider = ({ children, viewport, style }: ArtboardProps) => {
41+
if (!viewport) {
42+
return children;
43+
}
44+
45+
const { state: oState } = React.useContext(ArtboardContext);
46+
47+
const state = {
48+
...oState,
49+
width: viewport.width || (style || {}).width || oState.width,
50+
height: viewport.height || (style || {}).height || oState.height,
51+
scale: viewport.scale || oState.scale,
52+
fontScale: viewport.fontScale || oState.scale,
53+
};
54+
55+
return (
56+
<ArtboardContext.Provider value={{ state }}>
57+
{children}
58+
</ArtboardContext.Provider>
59+
)
60+
}
61+
62+
export default ArtboardContext;

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
getSymbolMasterByName as _getSymbolMasterByName,
1717
injectSymbols as _injectSymbols,
1818
} from './symbol';
19+
import { useWindowDimensions as _useWindowDimensions } from './context';
1920

2021
export const render = _render;
2122
export const renderToJSON = _renderToJSON;
@@ -34,6 +35,7 @@ export const makeSymbol = _makeSymbol;
3435
export const getSymbolComponentByName = _getSymbolComponentByName;
3536
export const getSymbolMasterByName = _getSymbolMasterByName;
3637
export const injectSymbols = _injectSymbols;
38+
export const useWindowDimensions = _useWindowDimensions;
3739

3840
export default {
3941
render,
@@ -53,4 +55,5 @@ export default {
5355
getSymbolComponentByName,
5456
getSymbolMasterByName,
5557
injectSymbols,
58+
useWindowDimensions,
5659
};

src/renderers/ArtboardRenderer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ export default class ArtboardRenderer extends SketchRenderer {
2626
presetDictionary: {
2727
allowResizedMatching: 0,
2828
offersLandscapeVariant: 1,
29-
...props.viewport,
29+
30+
name: props.viewport.name,
31+
width: props.viewport.width,
32+
height: props.viewport.height,
3033
},
3134
}),
3235
isFlippedHorizontal: false,

0 commit comments

Comments
 (0)