@spark-web/row 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +130 -0
- package/dist/declarations/src/Row.d.ts +25 -0
- package/dist/declarations/src/alignment.d.ts +26 -0
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/spark-web-row.cjs.d.ts +1 -0
- package/dist/spark-web-row.cjs.dev.js +73 -0
- package/dist/spark-web-row.cjs.js +7 -0
- package/dist/spark-web-row.cjs.prod.js +73 -0
- package/dist/spark-web-row.esm.js +65 -0
- package/package.json +22 -0
- package/src/Row.stories.tsx +27 -0
- package/src/Row.tsx +60 -0
- package/src/alignment.ts +15 -0
- package/src/index.ts +5 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @spark-web/row
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#27](https://github.com/brighte-labs/spark-web/pull/27)
|
|
8
|
+
[`4c8e398`](https://github.com/brighte-labs/spark-web/commit/4c8e3988f8a59d3dab60a6b67b1128b6ff2a5f2c)
|
|
9
|
+
Thanks [@JedWatson](https://github.com/JedWatson)! - Initial Version
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
[[`4c8e398`](https://github.com/brighte-labs/spark-web/commit/4c8e3988f8a59d3dab60a6b67b1128b6ff2a5f2c)]:
|
|
15
|
+
- @spark-web/box@1.0.0
|
|
16
|
+
- @spark-web/divider@1.0.0
|
|
17
|
+
- @spark-web/theme@1.0.0
|
|
18
|
+
- @spark-web/utils@1.0.0
|
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Row
|
|
3
|
+
storybookPath: page-layout-row--default
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Used to distribute children horizontally, with even spacing between each child.
|
|
7
|
+
|
|
8
|
+
```jsx live
|
|
9
|
+
<Row gap="large">
|
|
10
|
+
<Placeholder />
|
|
11
|
+
<Placeholder />
|
|
12
|
+
<Placeholder />
|
|
13
|
+
</Row>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Examples
|
|
17
|
+
|
|
18
|
+
### Gap
|
|
19
|
+
|
|
20
|
+
The spacing between children can be adjusted using the `gap` prop.
|
|
21
|
+
|
|
22
|
+
```jsx live
|
|
23
|
+
<Inline gap="xxlarge">
|
|
24
|
+
<Row gap="small">
|
|
25
|
+
<Placeholder />
|
|
26
|
+
<Placeholder />
|
|
27
|
+
<Placeholder />
|
|
28
|
+
</Row>
|
|
29
|
+
<Row gap="medium">
|
|
30
|
+
<Placeholder />
|
|
31
|
+
<Placeholder />
|
|
32
|
+
<Placeholder />
|
|
33
|
+
</Row>
|
|
34
|
+
<Row gap="large">
|
|
35
|
+
<Placeholder />
|
|
36
|
+
<Placeholder />
|
|
37
|
+
<Placeholder />
|
|
38
|
+
</Row>
|
|
39
|
+
<Row gap="xlarge">
|
|
40
|
+
<Placeholder />
|
|
41
|
+
<Placeholder />
|
|
42
|
+
<Placeholder />
|
|
43
|
+
</Row>
|
|
44
|
+
</Inline>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Vertical alignment
|
|
48
|
+
|
|
49
|
+
Items can be aligned vertically using the `alignY` prop.
|
|
50
|
+
|
|
51
|
+
```jsx live
|
|
52
|
+
<Stack gap="medium" align="center" dividers>
|
|
53
|
+
<Row gap="small" alignY="top">
|
|
54
|
+
<Placeholder />
|
|
55
|
+
<Placeholder label="top" height={64} width={128} />
|
|
56
|
+
<Placeholder />
|
|
57
|
+
</Row>
|
|
58
|
+
<Row gap="small" alignY="center">
|
|
59
|
+
<Placeholder />
|
|
60
|
+
<Placeholder label="center" height={64} width={128} />
|
|
61
|
+
<Placeholder />
|
|
62
|
+
</Row>
|
|
63
|
+
<Row gap="small" alignY="bottom">
|
|
64
|
+
<Placeholder />
|
|
65
|
+
<Placeholder label="bottom" height={64} width={128} />
|
|
66
|
+
<Placeholder />
|
|
67
|
+
</Row>
|
|
68
|
+
<Row gap="small" alignY="stretch">
|
|
69
|
+
<Placeholder />
|
|
70
|
+
<Placeholder label="stretch" height={64} width={128} />
|
|
71
|
+
<Placeholder />
|
|
72
|
+
</Row>
|
|
73
|
+
</Stack>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Horizontal alignment
|
|
77
|
+
|
|
78
|
+
Items can be aligned horizontally using the `align` prop.
|
|
79
|
+
|
|
80
|
+
```jsx live
|
|
81
|
+
<Stack gap="medium" dividers>
|
|
82
|
+
<Row gap="small" align="left">
|
|
83
|
+
<Placeholder label="left" width={128} />
|
|
84
|
+
<Placeholder />
|
|
85
|
+
<Placeholder />
|
|
86
|
+
</Row>
|
|
87
|
+
<Row gap="small" align="center">
|
|
88
|
+
<Placeholder />
|
|
89
|
+
<Placeholder label="center" width={128} />
|
|
90
|
+
<Placeholder />
|
|
91
|
+
</Row>
|
|
92
|
+
<Row gap="small" align="right">
|
|
93
|
+
<Placeholder />
|
|
94
|
+
<Placeholder />
|
|
95
|
+
<Placeholder label="right" width={128} />
|
|
96
|
+
</Row>
|
|
97
|
+
</Stack>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Dividers
|
|
101
|
+
|
|
102
|
+
Use the `dividers` property to render a [Divider](/package/divider) between each
|
|
103
|
+
element in the Row.
|
|
104
|
+
|
|
105
|
+
```jsx live
|
|
106
|
+
<Row gap="medium" dividers>
|
|
107
|
+
<Text>First item</Text>
|
|
108
|
+
<Text>Second item</Text>
|
|
109
|
+
<Text>Third item</Text>
|
|
110
|
+
</Row>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Props
|
|
114
|
+
|
|
115
|
+
| Prop | Type | Default | Description |
|
|
116
|
+
| --------- | ---------------------------------- | --------- | ----------------------------------------------------- |
|
|
117
|
+
| align? | [ResponsiveProp<Align\>][align] | 'left' | Horizontally align items within the container. |
|
|
118
|
+
| alignY? | [ResponsiveProp<AlignY\>][align-y] | 'stretch' | Vertically align items within the container. |
|
|
119
|
+
| dividers? | boolean | | Sets whether to place a divider between each element. |
|
|
120
|
+
|
|
121
|
+
`Row` props also include [`Box`](/package/box) props and are not listed here
|
|
122
|
+
(excludes `display`, `alignItems`, `flexDirection`, `justifyContent` and
|
|
123
|
+
`flexWrap`).
|
|
124
|
+
|
|
125
|
+
Extra props are also passed into the underlying [`Box`](/package/box) component.
|
|
126
|
+
|
|
127
|
+
[align]:
|
|
128
|
+
https://bitbucket.org/brighte-energy/energy/src/537c678a81090af545969504776c6b3d2e67743e/spark-web/packages/inline/src/Inline.tsx#spark-web/packages/inline/src/Inline.tsx-20
|
|
129
|
+
[align-y]:
|
|
130
|
+
https://bitbucket.org/brighte-energy/energy/src/537c678a81090af545969504776c6b3d2e67743e/spark-web/packages/inline/src/Inline.tsx#spark-web/packages/inline/src/Inline.tsx-22
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BoxProps } from '@spark-web/box';
|
|
2
|
+
import type { ResponsiveProp } from '@spark-web/theme';
|
|
3
|
+
import type { ReactElement } from 'react';
|
|
4
|
+
import type { Align, AlignY } from './alignment';
|
|
5
|
+
declare type ValidBoxProps = Omit<BoxProps, 'display' | 'alignItems' | 'flexDirection' | 'justifyContent' | 'flexWrap'>;
|
|
6
|
+
export declare type RowProps = {
|
|
7
|
+
/** Horizontally align items within the container. */
|
|
8
|
+
align?: ResponsiveProp<Align>;
|
|
9
|
+
/** Vertically align items within the container. */
|
|
10
|
+
alignY?: ResponsiveProp<AlignY>;
|
|
11
|
+
/** Place a divider between each element. */
|
|
12
|
+
dividers?: boolean;
|
|
13
|
+
} & ValidBoxProps;
|
|
14
|
+
export declare const Row: <Comp extends import("react").ElementType<any> = "div">(props: {
|
|
15
|
+
as?: Comp | undefined;
|
|
16
|
+
ref?: import("react").Ref<Comp extends "symbol" | "clipPath" | "filter" | "mask" | "marker" | "text" | "circle" | "svg" | "animate" | "animateMotion" | "animateTransform" | "defs" | "desc" | "ellipse" | "feBlend" | "feColorMatrix" | "feComponentTransfer" | "feComposite" | "feConvolveMatrix" | "feDiffuseLighting" | "feDisplacementMap" | "feDistantLight" | "feDropShadow" | "feFlood" | "feFuncA" | "feFuncB" | "feFuncG" | "feFuncR" | "feGaussianBlur" | "feImage" | "feMerge" | "feMergeNode" | "feMorphology" | "feOffset" | "fePointLight" | "feSpecularLighting" | "feSpotLight" | "feTile" | "feTurbulence" | "foreignObject" | "g" | "image" | "line" | "linearGradient" | "metadata" | "mpath" | "path" | "pattern" | "polygon" | "polyline" | "radialGradient" | "rect" | "stop" | "switch" | "textPath" | "tspan" | "use" | "view" | keyof HTMLElementTagNameMap | "set" ? (HTMLElementTagNameMap & Pick<SVGElementTagNameMap, "symbol" | "clipPath" | "filter" | "mask" | "marker" | "text" | "circle" | "svg" | "animate" | "animateMotion" | "animateTransform" | "defs" | "desc" | "ellipse" | "feBlend" | "feColorMatrix" | "feComponentTransfer" | "feComposite" | "feConvolveMatrix" | "feDiffuseLighting" | "feDisplacementMap" | "feDistantLight" | "feDropShadow" | "feFlood" | "feFuncA" | "feFuncB" | "feFuncG" | "feFuncR" | "feGaussianBlur" | "feImage" | "feMerge" | "feMergeNode" | "feMorphology" | "feOffset" | "fePointLight" | "feSpecularLighting" | "feSpotLight" | "feTile" | "feTurbulence" | "foreignObject" | "g" | "image" | "line" | "linearGradient" | "metadata" | "mpath" | "path" | "pattern" | "polygon" | "polyline" | "radialGradient" | "rect" | "stop" | "switch" | "textPath" | "tspan" | "use" | "view" | "set">)[Comp] : Comp extends new (...args: any) => any ? InstanceType<Comp> : undefined> | undefined;
|
|
17
|
+
} & Omit<import("react").PropsWithoutRef<import("react").ComponentProps<Comp>>, "as"> & {
|
|
18
|
+
/** Horizontally align items within the container. */
|
|
19
|
+
align?: ResponsiveProp<"left" | "right" | "center"> | undefined;
|
|
20
|
+
/** Vertically align items within the container. */
|
|
21
|
+
alignY?: ResponsiveProp<"bottom" | "top" | "stretch" | "center"> | undefined;
|
|
22
|
+
/** Place a divider between each element. */
|
|
23
|
+
dividers?: boolean | undefined;
|
|
24
|
+
} & ValidBoxProps) => ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare const alignLookup: {
|
|
2
|
+
readonly left: "start";
|
|
3
|
+
readonly center: "center";
|
|
4
|
+
readonly right: "end";
|
|
5
|
+
};
|
|
6
|
+
declare const alignYLookup: {
|
|
7
|
+
readonly top: "start";
|
|
8
|
+
readonly center: "center";
|
|
9
|
+
readonly bottom: "end";
|
|
10
|
+
readonly stretch: "stretch";
|
|
11
|
+
};
|
|
12
|
+
export declare type Align = keyof typeof alignLookup;
|
|
13
|
+
export declare type AlignY = keyof typeof alignYLookup;
|
|
14
|
+
export declare const alignToJustifyContent: (prop?: import("@spark-web/theme").ResponsiveProp<"left" | "right" | "center"> | undefined) => "center" | "end" | "start" | {
|
|
15
|
+
mobile: "center" | "end" | "start" | undefined;
|
|
16
|
+
tablet: "center" | "end" | "start" | undefined;
|
|
17
|
+
desktop: "center" | "end" | "start" | undefined;
|
|
18
|
+
wide: "center" | "end" | "start" | undefined;
|
|
19
|
+
} | undefined;
|
|
20
|
+
export declare const alignYToAlignItems: (prop?: import("@spark-web/theme").ResponsiveProp<"bottom" | "top" | "stretch" | "center"> | undefined) => "stretch" | "center" | "end" | "start" | {
|
|
21
|
+
mobile: "stretch" | "center" | "end" | "start" | undefined;
|
|
22
|
+
tablet: "stretch" | "center" | "end" | "start" | undefined;
|
|
23
|
+
desktop: "stretch" | "center" | "end" | "start" | undefined;
|
|
24
|
+
wide: "stretch" | "center" | "end" | "start" | undefined;
|
|
25
|
+
} | undefined;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./declarations/src/index";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _defineProperty = require('@babel/runtime/helpers/esm/defineProperty');
|
|
6
|
+
var _objectWithoutProperties = require('@babel/runtime/helpers/esm/objectWithoutProperties');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var box = require('@spark-web/box');
|
|
9
|
+
var divider = require('@spark-web/divider');
|
|
10
|
+
var ts = require('@spark-web/utils/ts');
|
|
11
|
+
var theme = require('@spark-web/theme');
|
|
12
|
+
|
|
13
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
16
|
+
|
|
17
|
+
var alignLookup = {
|
|
18
|
+
left: 'start',
|
|
19
|
+
center: 'center',
|
|
20
|
+
right: 'end'
|
|
21
|
+
};
|
|
22
|
+
var alignYLookup = {
|
|
23
|
+
top: 'start',
|
|
24
|
+
center: 'center',
|
|
25
|
+
bottom: 'end',
|
|
26
|
+
stretch: 'stretch'
|
|
27
|
+
};
|
|
28
|
+
var alignToJustifyContent = theme.createResponsiveMapFn(alignLookup);
|
|
29
|
+
var alignYToAlignItems = theme.createResponsiveMapFn(alignYLookup);
|
|
30
|
+
|
|
31
|
+
var _excluded = ["align", "alignY", "children", "dividers"];
|
|
32
|
+
var __jsx = React__default["default"].createElement;
|
|
33
|
+
|
|
34
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
35
|
+
|
|
36
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
37
|
+
var Row = ts.forwardRefWithAs(function (_ref, forwardedRef) {
|
|
38
|
+
var _ref$align = _ref.align,
|
|
39
|
+
align = _ref$align === void 0 ? 'left' : _ref$align,
|
|
40
|
+
_ref$alignY = _ref.alignY,
|
|
41
|
+
alignY = _ref$alignY === void 0 ? 'stretch' : _ref$alignY,
|
|
42
|
+
children = _ref.children,
|
|
43
|
+
dividers = _ref.dividers,
|
|
44
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
45
|
+
|
|
46
|
+
var justifyContent = alignToJustifyContent(align);
|
|
47
|
+
var alignItems = alignYToAlignItems(alignY);
|
|
48
|
+
|
|
49
|
+
var rootProps = _objectSpread({
|
|
50
|
+
ref: forwardedRef,
|
|
51
|
+
display: 'flex',
|
|
52
|
+
alignItems: alignItems,
|
|
53
|
+
justifyContent: justifyContent
|
|
54
|
+
}, props); // bail early w/o dividers to avoid unnecessary map
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if (!dividers) {
|
|
58
|
+
return __jsx(box.Box, rootProps, children);
|
|
59
|
+
} // map over children to insert dividers
|
|
60
|
+
// remove falsy values before mapping, keeps the index in sync
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
var childArray = React.Children.toArray(children);
|
|
64
|
+
return __jsx(box.Box, rootProps, childArray.map(function (child, idx) {
|
|
65
|
+
return __jsx(React.Fragment, {
|
|
66
|
+
key: child.key || idx
|
|
67
|
+
}, dividers && idx ? __jsx(divider.Divider, {
|
|
68
|
+
vertical: true
|
|
69
|
+
}) : null, child);
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
exports.Row = Row;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _defineProperty = require('@babel/runtime/helpers/esm/defineProperty');
|
|
6
|
+
var _objectWithoutProperties = require('@babel/runtime/helpers/esm/objectWithoutProperties');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var box = require('@spark-web/box');
|
|
9
|
+
var divider = require('@spark-web/divider');
|
|
10
|
+
var ts = require('@spark-web/utils/ts');
|
|
11
|
+
var theme = require('@spark-web/theme');
|
|
12
|
+
|
|
13
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
16
|
+
|
|
17
|
+
var alignLookup = {
|
|
18
|
+
left: 'start',
|
|
19
|
+
center: 'center',
|
|
20
|
+
right: 'end'
|
|
21
|
+
};
|
|
22
|
+
var alignYLookup = {
|
|
23
|
+
top: 'start',
|
|
24
|
+
center: 'center',
|
|
25
|
+
bottom: 'end',
|
|
26
|
+
stretch: 'stretch'
|
|
27
|
+
};
|
|
28
|
+
var alignToJustifyContent = theme.createResponsiveMapFn(alignLookup);
|
|
29
|
+
var alignYToAlignItems = theme.createResponsiveMapFn(alignYLookup);
|
|
30
|
+
|
|
31
|
+
var _excluded = ["align", "alignY", "children", "dividers"];
|
|
32
|
+
var __jsx = React__default["default"].createElement;
|
|
33
|
+
|
|
34
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
35
|
+
|
|
36
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
37
|
+
var Row = ts.forwardRefWithAs(function (_ref, forwardedRef) {
|
|
38
|
+
var _ref$align = _ref.align,
|
|
39
|
+
align = _ref$align === void 0 ? 'left' : _ref$align,
|
|
40
|
+
_ref$alignY = _ref.alignY,
|
|
41
|
+
alignY = _ref$alignY === void 0 ? 'stretch' : _ref$alignY,
|
|
42
|
+
children = _ref.children,
|
|
43
|
+
dividers = _ref.dividers,
|
|
44
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
45
|
+
|
|
46
|
+
var justifyContent = alignToJustifyContent(align);
|
|
47
|
+
var alignItems = alignYToAlignItems(alignY);
|
|
48
|
+
|
|
49
|
+
var rootProps = _objectSpread({
|
|
50
|
+
ref: forwardedRef,
|
|
51
|
+
display: 'flex',
|
|
52
|
+
alignItems: alignItems,
|
|
53
|
+
justifyContent: justifyContent
|
|
54
|
+
}, props); // bail early w/o dividers to avoid unnecessary map
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if (!dividers) {
|
|
58
|
+
return __jsx(box.Box, rootProps, children);
|
|
59
|
+
} // map over children to insert dividers
|
|
60
|
+
// remove falsy values before mapping, keeps the index in sync
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
var childArray = React.Children.toArray(children);
|
|
64
|
+
return __jsx(box.Box, rootProps, childArray.map(function (child, idx) {
|
|
65
|
+
return __jsx(React.Fragment, {
|
|
66
|
+
key: child.key || idx
|
|
67
|
+
}, dividers && idx ? __jsx(divider.Divider, {
|
|
68
|
+
vertical: true
|
|
69
|
+
}) : null, child);
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
exports.Row = Row;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
2
|
+
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
|
|
3
|
+
import React, { Children, Fragment } from 'react';
|
|
4
|
+
import { Box } from '@spark-web/box';
|
|
5
|
+
import { Divider } from '@spark-web/divider';
|
|
6
|
+
import { forwardRefWithAs } from '@spark-web/utils/ts';
|
|
7
|
+
import { createResponsiveMapFn } from '@spark-web/theme';
|
|
8
|
+
|
|
9
|
+
var alignLookup = {
|
|
10
|
+
left: 'start',
|
|
11
|
+
center: 'center',
|
|
12
|
+
right: 'end'
|
|
13
|
+
};
|
|
14
|
+
var alignYLookup = {
|
|
15
|
+
top: 'start',
|
|
16
|
+
center: 'center',
|
|
17
|
+
bottom: 'end',
|
|
18
|
+
stretch: 'stretch'
|
|
19
|
+
};
|
|
20
|
+
var alignToJustifyContent = createResponsiveMapFn(alignLookup);
|
|
21
|
+
var alignYToAlignItems = createResponsiveMapFn(alignYLookup);
|
|
22
|
+
|
|
23
|
+
var _excluded = ["align", "alignY", "children", "dividers"];
|
|
24
|
+
var __jsx = React.createElement;
|
|
25
|
+
|
|
26
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
27
|
+
|
|
28
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
29
|
+
var Row = forwardRefWithAs(function (_ref, forwardedRef) {
|
|
30
|
+
var _ref$align = _ref.align,
|
|
31
|
+
align = _ref$align === void 0 ? 'left' : _ref$align,
|
|
32
|
+
_ref$alignY = _ref.alignY,
|
|
33
|
+
alignY = _ref$alignY === void 0 ? 'stretch' : _ref$alignY,
|
|
34
|
+
children = _ref.children,
|
|
35
|
+
dividers = _ref.dividers,
|
|
36
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
37
|
+
|
|
38
|
+
var justifyContent = alignToJustifyContent(align);
|
|
39
|
+
var alignItems = alignYToAlignItems(alignY);
|
|
40
|
+
|
|
41
|
+
var rootProps = _objectSpread({
|
|
42
|
+
ref: forwardedRef,
|
|
43
|
+
display: 'flex',
|
|
44
|
+
alignItems: alignItems,
|
|
45
|
+
justifyContent: justifyContent
|
|
46
|
+
}, props); // bail early w/o dividers to avoid unnecessary map
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if (!dividers) {
|
|
50
|
+
return __jsx(Box, rootProps, children);
|
|
51
|
+
} // map over children to insert dividers
|
|
52
|
+
// remove falsy values before mapping, keeps the index in sync
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
var childArray = Children.toArray(children);
|
|
56
|
+
return __jsx(Box, rootProps, childArray.map(function (child, idx) {
|
|
57
|
+
return __jsx(Fragment, {
|
|
58
|
+
key: child.key || idx
|
|
59
|
+
}, dividers && idx ? __jsx(Divider, {
|
|
60
|
+
vertical: true
|
|
61
|
+
}) : null, child);
|
|
62
|
+
}));
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export { Row };
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spark-web/row",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"main": "dist/spark-web-row.cjs.js",
|
|
6
|
+
"module": "dist/spark-web-row.esm.js",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/react": "^17.0.12"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@babel/runtime": "^7.14.6",
|
|
12
|
+
"@emotion/css": "^11.7.1",
|
|
13
|
+
"@spark-web/box": "^1.0.0",
|
|
14
|
+
"@spark-web/divider": "^1.0.0",
|
|
15
|
+
"@spark-web/theme": "^1.0.0",
|
|
16
|
+
"@spark-web/utils": "^1.0.0",
|
|
17
|
+
"react": "^17.0.2"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">= 14.13"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { Placeholder } from '../../../docs/components/example-helpers';
|
|
4
|
+
import type { RowProps } from './Row';
|
|
5
|
+
import { Row } from './Row';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Page & Layout / Row',
|
|
9
|
+
component: Row,
|
|
10
|
+
} as ComponentMeta<typeof Row>;
|
|
11
|
+
|
|
12
|
+
const RowStory: ComponentStory<typeof Row> = (
|
|
13
|
+
args: Omit<RowProps, 'className'>
|
|
14
|
+
) => <Row {...args} />;
|
|
15
|
+
|
|
16
|
+
export const Default = RowStory.bind({});
|
|
17
|
+
|
|
18
|
+
Default.args = {
|
|
19
|
+
gap: 'large',
|
|
20
|
+
children: (
|
|
21
|
+
<>
|
|
22
|
+
<Placeholder height={40} />
|
|
23
|
+
<Placeholder height={40} />
|
|
24
|
+
<Placeholder height={40} />
|
|
25
|
+
</>
|
|
26
|
+
),
|
|
27
|
+
} as RowProps;
|
package/src/Row.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { BoxProps } from '@spark-web/box';
|
|
2
|
+
import { Box } from '@spark-web/box';
|
|
3
|
+
import { Divider } from '@spark-web/divider';
|
|
4
|
+
import type { ResponsiveProp } from '@spark-web/theme';
|
|
5
|
+
import { forwardRefWithAs } from '@spark-web/utils/ts';
|
|
6
|
+
import type { ReactElement } from 'react';
|
|
7
|
+
import { Children, Fragment } from 'react';
|
|
8
|
+
|
|
9
|
+
import type { Align, AlignY } from './alignment';
|
|
10
|
+
import { alignToJustifyContent, alignYToAlignItems } from './alignment';
|
|
11
|
+
|
|
12
|
+
type ValidBoxProps = Omit<
|
|
13
|
+
BoxProps,
|
|
14
|
+
'display' | 'alignItems' | 'flexDirection' | 'justifyContent' | 'flexWrap'
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
export type RowProps = {
|
|
18
|
+
/** Horizontally align items within the container. */
|
|
19
|
+
align?: ResponsiveProp<Align>;
|
|
20
|
+
/** Vertically align items within the container. */
|
|
21
|
+
alignY?: ResponsiveProp<AlignY>;
|
|
22
|
+
/** Place a divider between each element. */
|
|
23
|
+
dividers?: boolean;
|
|
24
|
+
} & ValidBoxProps;
|
|
25
|
+
|
|
26
|
+
export const Row = forwardRefWithAs<'div', RowProps>(
|
|
27
|
+
(
|
|
28
|
+
{ align = 'left', alignY = 'stretch', children, dividers, ...props },
|
|
29
|
+
forwardedRef
|
|
30
|
+
) => {
|
|
31
|
+
const justifyContent = alignToJustifyContent(align);
|
|
32
|
+
const alignItems = alignYToAlignItems(alignY);
|
|
33
|
+
const rootProps = {
|
|
34
|
+
ref: forwardedRef,
|
|
35
|
+
display: 'flex',
|
|
36
|
+
alignItems,
|
|
37
|
+
justifyContent,
|
|
38
|
+
...props,
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
// bail early w/o dividers to avoid unnecessary map
|
|
42
|
+
if (!dividers) {
|
|
43
|
+
return <Box {...rootProps}>{children}</Box>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// map over children to insert dividers
|
|
47
|
+
// remove falsy values before mapping, keeps the index in sync
|
|
48
|
+
const childArray = Children.toArray(children) as ReactElement[];
|
|
49
|
+
return (
|
|
50
|
+
<Box {...rootProps}>
|
|
51
|
+
{childArray.map((child, idx) => (
|
|
52
|
+
<Fragment key={child.key || idx}>
|
|
53
|
+
{dividers && idx ? <Divider vertical /> : null}
|
|
54
|
+
{child}
|
|
55
|
+
</Fragment>
|
|
56
|
+
))}
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
);
|
package/src/alignment.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createResponsiveMapFn } from '@spark-web/theme';
|
|
2
|
+
|
|
3
|
+
const alignLookup = { left: 'start', center: 'center', right: 'end' } as const;
|
|
4
|
+
const alignYLookup = {
|
|
5
|
+
top: 'start',
|
|
6
|
+
center: 'center',
|
|
7
|
+
bottom: 'end',
|
|
8
|
+
stretch: 'stretch',
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
export type Align = keyof typeof alignLookup;
|
|
12
|
+
export type AlignY = keyof typeof alignYLookup;
|
|
13
|
+
|
|
14
|
+
export const alignToJustifyContent = createResponsiveMapFn(alignLookup);
|
|
15
|
+
export const alignYToAlignItems = createResponsiveMapFn(alignYLookup);
|