@sproutsocial/racine 7.0.2-beta-maurice.1 → 7.1.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 +12 -0
- package/README.md +9 -38
- package/__flow__/Box/styles.js +5 -5
- package/__flow__/ChartLegend/styles.js +6 -6
- package/__flow__/Checkbox/index.js +4 -1
- package/__flow__/Checkbox/index.stories.js +16 -0
- package/__flow__/Checkbox/index.test.js +33 -0
- package/__flow__/Table/index.js +82 -54
- package/__flow__/Table/index.stories.js +41 -0
- package/__flow__/Table/index.test.js +14 -0
- package/__flow__/TableCell/index.js +17 -7
- package/__flow__/TableCell/index.test.js +8 -1
- package/__flow__/TableHeaderCell/index.js +26 -11
- package/__flow__/TableHeaderCell/index.test.js +16 -1
- package/__flow__/TableRowAccordion/index.js +1 -1
- package/__flow__/utils/theme.js +0 -1
- package/commonjs/Checkbox/index.js +6 -6
- package/commonjs/Table/index.js +80 -71
- package/commonjs/TableCell/index.js +4 -3
- package/commonjs/TableHeaderCell/index.js +35 -20
- package/commonjs/TableRowAccordion/index.js +2 -2
- package/lib/Checkbox/index.js +6 -6
- package/lib/Table/index.js +61 -64
- package/lib/TableCell/index.js +4 -3
- package/lib/TableHeaderCell/index.js +35 -20
- package/lib/TableRowAccordion/index.js +2 -2
- package/package.json +4 -9
- package/__flow__/.DS_Store +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ Test any local package in another project by utilizing [yarn link](https://yarnp
|
|
|
104
104
|
|
|
105
105
|
Contributions to Racine are welcomed and encouraged from every member of the team. Whether you're adding a new component or simply fixing a bug, every improvement to the library is future leverage for our peers, our product, and our customers.
|
|
106
106
|
|
|
107
|
-
###
|
|
107
|
+
### 🔍 Step 1: Find a way to contribute
|
|
108
108
|
|
|
109
109
|
There are a few ways to get involved:
|
|
110
110
|
|
|
@@ -113,7 +113,7 @@ There are a few ways to get involved:
|
|
|
113
113
|
- [Racine uses a GitHub project board to track our backlog, in-flight changes, and future changes](https://github.com/sproutsocial/racine/projects/2). It's a great way to get a broad look at what's happening in Racine.
|
|
114
114
|
- Come to the bi-weekly Racine Component Review meeting, where engineers gather to discuss new components and changes to existing ones.
|
|
115
115
|
|
|
116
|
-
###
|
|
116
|
+
### 🗺 Step 2: Find your way around
|
|
117
117
|
|
|
118
118
|
Racine's file structure is set up like this:
|
|
119
119
|
|
|
@@ -136,11 +136,11 @@ And you can interact with Racine via the command line with these commands:
|
|
|
136
136
|
- `yarn clean` - Delete all generated files and directories.
|
|
137
137
|
- `yarn release` - This will trigger the release process for creating a new version of the Racine package on npm. **Only Racine administrators can perform the release process.**
|
|
138
138
|
|
|
139
|
-
###
|
|
139
|
+
### ✅ Step 3: Make your changes
|
|
140
140
|
|
|
141
141
|
Racine uses a tool called [changesets](https://github.com/atlassian/changesets) to automatically pick new version numbers and update the changelog whenever we publish a new version of the package.
|
|
142
142
|
|
|
143
|
-
**
|
|
143
|
+
**If you are submitting a PR to Racine that should result in a version bump to the package, you should run `yarn change` to generate a changeset.**
|
|
144
144
|
|
|
145
145
|
We use semantic versioning for the Racine package, which allows users to understand the scope of a package's changes based on the version number, which is in the format `major.minor.patch`.
|
|
146
146
|
|
|
@@ -150,41 +150,12 @@ When running this command, you will be asked to select whether your change is a
|
|
|
150
150
|
- **minor** changes are for new features or improvements, and they bump the middle digit in the version number (`x.0.x`)
|
|
151
151
|
- **major** changes are *breaking changes*, and they bump the first digit (`0.x.x`). These types of changes are rare and should be coordinated in advance with the Design Systems team.
|
|
152
152
|
|
|
153
|
-
The changeset CLI will also ask you to input a message detailing your changes.
|
|
153
|
+
The changeset CLI will also ask you to input a message detailing your changes. Try to be as descriptive and informative as possible with these messages, as they will be used to build a changelog file when a new version is released. You may also use Markdown formatting within changesets.
|
|
154
154
|
|
|
155
|
-
**You can add as many changesets to a PR as you would like.** If your PR makes several distinct changes to Racine, you should create a changeset detailing each one individually.
|
|
155
|
+
**You can add as many changesets to a PR as you would like.** If your PR makes several distinct changes to Racine, you should create a changeset detailing each one individually.
|
|
156
156
|
|
|
157
|
-
### **β Step 4: Create a beta version *(optional)***
|
|
158
157
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
#### **Releasing a beta**
|
|
162
|
-
|
|
163
|
-
To release a beta version, commit your current changes and then run `yarn beta:release`. This command will create a new beta version with a semantic bump level based on your changeset(s), and include a differentiating identifier from your git user email name. For example, if [Bill Foehring](bfoehring@sproutsocial.com) was making a minor change to versions `6.55.3`, the command would:
|
|
164
|
-
1. create version `6.56.0-beta-bfoehring.0`,
|
|
165
|
-
1. add a corresponding tag in git,
|
|
166
|
-
1. and publish the new beta version to the npm registry.
|
|
167
|
-
|
|
168
|
-
Once a beta release is published you can include it as a dependency from `web-app-core` or `seeds`.
|
|
169
|
-
|
|
170
|
-
The differentiating identifier is necessary to enable if two or more developers to concurrently create their own beta versions from the current version of Racine. Without the identifiers, the name of the beta versions could collide.
|
|
171
|
-
|
|
172
|
-
#### **Checking beta status**
|
|
173
|
-
|
|
174
|
-
Run `yarn beta:status` to see the info Racine has about your current beta version.
|
|
175
|
-
|
|
176
|
-
As you continue to make changes, rerunning `yarn beta:release` will release a new version of your beta. From the example above, it would create `6.56.0-beta-bfoehring.1` as the next beta release. Running it again would create `6.56.0-beta-bfoehring.2` and so on...
|
|
177
|
-
|
|
178
|
-
#### **Deprecating a beta**
|
|
179
|
-
|
|
180
|
-
When you are satisfied that all of your changes are correct, you can end your beta by running `yarn beta:deprecate`. This will:
|
|
181
|
-
- delete any beta metadata,
|
|
182
|
-
- restore the original version within `package.json`,
|
|
183
|
-
- deprecate any beta releases on the registry for this version.
|
|
184
|
-
|
|
185
|
-
Doing so will prime the changeset mechanism to complete the standard release process. (Note: The version of the final release is set at the last moment to ensure it actually is properly set the next valid semantic version as other versions of Racine may have been released during the time you are working on yours.)
|
|
186
|
-
|
|
187
|
-
### **🗣 Step 5: Create a pull request**
|
|
158
|
+
### 🗣 Step 4: Create a pull request
|
|
188
159
|
|
|
189
160
|
Once you're ready to submit your changes for review, open a PR to this repository. A few things will happen:
|
|
190
161
|
|
|
@@ -194,12 +165,12 @@ Once you're ready to submit your changes for review, open a PR to this repositor
|
|
|
194
165
|
|
|
195
166
|
Once your tests are passing and you have at least one approving review, feel free to merge your changes into Racine!
|
|
196
167
|
|
|
197
|
-
###
|
|
168
|
+
### ☁️ Step 5: Publish your changes to npm
|
|
198
169
|
|
|
199
170
|
As PRs get merged into Racine, changsets will keep a running PR open called `Version Packages`. This PR will detail all of the changes that have been made to the package since the last publish. **Anyone can release a new version of Racine by merging this PR.**
|
|
200
171
|
|
|
201
172
|
When the PR is merged, [GitHub will kick off a publish of the new version](https://github.com/sproutsocial/racine/actions?query=workflow%3ARelease). There will be a notification in #eng-design-systems in Slack when the new version is available.
|
|
202
173
|
|
|
203
|
-
###
|
|
174
|
+
### ✍ Step 6: Document your changes
|
|
204
175
|
|
|
205
176
|
Racine components are documented in [Seeds](https://sproutsocial.com/seeds/components), Sprout's design system. You can open a PR to the [Seeds repository](https://github.com/sproutsocial/seeds) to add or edit component documentation. Reach out to the Design Systems team for help getting started.
|
package/__flow__/Box/styles.js
CHANGED
|
@@ -32,15 +32,15 @@ export type TypeContainerProps = $ReadOnly<{|
|
|
|
32
32
|
|
|
33
33
|
type TypeBoxContainer = StyledComponent<TypeContainerProps, TypeTheme, *>;
|
|
34
34
|
const Container: TypeBoxContainer = styled.div`
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
font-family: ${({ theme }) => theme.fontFamily};
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
${COMMON}
|
|
39
|
+
${BORDER}
|
|
40
40
|
${LAYOUT}
|
|
41
41
|
${POSITION}
|
|
42
42
|
${FLEXBOX}
|
|
43
43
|
${GRID}
|
|
44
|
-
|
|
44
|
+
`;
|
|
45
45
|
|
|
46
46
|
export default Container;
|
|
@@ -25,13 +25,13 @@ const Container: StyledComponent<any, TypeTheme, *> = styled.div`
|
|
|
25
25
|
${(props) =>
|
|
26
26
|
props.inline &&
|
|
27
27
|
css`
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
display: flex;
|
|
29
|
+
justify-content: center;
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
${Label} + ${Label} {
|
|
32
|
+
margin-left: ${(props) => props.theme.space[450]};
|
|
33
|
+
}
|
|
34
|
+
`}
|
|
35
35
|
|
|
36
36
|
${COMMON}
|
|
37
37
|
${LAYOUT}
|
|
@@ -25,6 +25,7 @@ export type TypeProps = {
|
|
|
25
25
|
appearance?: "pill" | "default",
|
|
26
26
|
qa?: Object,
|
|
27
27
|
tabIndex?: string | number,
|
|
28
|
+
inputProps?: Object,
|
|
28
29
|
...
|
|
29
30
|
};
|
|
30
31
|
|
|
@@ -66,6 +67,7 @@ export default class Checkbox extends React.Component<TypeProps> {
|
|
|
66
67
|
appearance = "default",
|
|
67
68
|
qa = {},
|
|
68
69
|
tabIndex,
|
|
70
|
+
inputProps = {},
|
|
69
71
|
...rest
|
|
70
72
|
} = this.props;
|
|
71
73
|
const isPill = appearance === "pill";
|
|
@@ -98,6 +100,7 @@ export default class Checkbox extends React.Component<TypeProps> {
|
|
|
98
100
|
data-qa-checkbox-isdisabled={disabled === true}
|
|
99
101
|
tabIndex={tabIndex}
|
|
100
102
|
{...qa}
|
|
103
|
+
{...inputProps}
|
|
101
104
|
/>
|
|
102
105
|
{label && <LabelText disabled={disabled}>{label}</LabelText>}
|
|
103
106
|
</CheckboxContainer>
|
|
@@ -125,6 +128,7 @@ export default class Checkbox extends React.Component<TypeProps> {
|
|
|
125
128
|
data-qa-checkbox-isdisabled={disabled === true}
|
|
126
129
|
tabIndex={tabIndex}
|
|
127
130
|
{...qa}
|
|
131
|
+
{...inputProps}
|
|
128
132
|
/>
|
|
129
133
|
<CheckboxBox>
|
|
130
134
|
<CheckIcon
|
|
@@ -134,7 +138,6 @@ export default class Checkbox extends React.Component<TypeProps> {
|
|
|
134
138
|
/>
|
|
135
139
|
</CheckboxBox>
|
|
136
140
|
</InputWrapper>
|
|
137
|
-
{label && !isPill && <LabelText disabled={disabled}>{label}</LabelText>}
|
|
138
141
|
</Container>
|
|
139
142
|
);
|
|
140
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { boolean } from "@storybook/addon-knobs";
|
|
3
|
+
import { action } from "@storybook/addon-actions";
|
|
3
4
|
|
|
4
5
|
import Checkbox from "./";
|
|
5
6
|
|
|
@@ -97,3 +98,18 @@ export const LabelledDisabled = () => (
|
|
|
97
98
|
LabelledDisabled.story = {
|
|
98
99
|
name: "Labelled/Disabled",
|
|
99
100
|
};
|
|
101
|
+
|
|
102
|
+
export const InputPropsOnMouseOver = () => (
|
|
103
|
+
<Checkbox
|
|
104
|
+
checked={boolean("checked", true)}
|
|
105
|
+
label="Check Me"
|
|
106
|
+
inputProps={{
|
|
107
|
+
onMouseOver: action("checkbox-mouseOver"),
|
|
108
|
+
onClick: action("checkbox-click"),
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
InputPropsOnMouseOver.story = {
|
|
114
|
+
name: "InputProps/OnMouseOver",
|
|
115
|
+
};
|
|
@@ -47,4 +47,37 @@ describe("Checkbox", () => {
|
|
|
47
47
|
);
|
|
48
48
|
expect(getByDataQaLabel({ "checkbox-isdisabled": true })).toBeTruthy();
|
|
49
49
|
});
|
|
50
|
+
|
|
51
|
+
it("should display label when label not undefined and appearance is default", () => {
|
|
52
|
+
const { getByLabelText } = render(
|
|
53
|
+
<Checkbox checked label="Checkbox Label" id="checkboxid" />
|
|
54
|
+
);
|
|
55
|
+
expect(getByLabelText("Checkbox Label")).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should not display label when label not undefined and appearance is pill", () => {
|
|
59
|
+
const { queryByLabelText } = render(
|
|
60
|
+
<Checkbox
|
|
61
|
+
checked
|
|
62
|
+
label="Checkbox Label"
|
|
63
|
+
id="checkboxid"
|
|
64
|
+
appearance="pill"
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
expect(queryByLabelText("Checkbox Label")).not.toBeInTheDocument();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should support events through inputProps", () => {
|
|
71
|
+
const mockHandleMouseOver = jest.fn();
|
|
72
|
+
const options = render(
|
|
73
|
+
<Checkbox
|
|
74
|
+
checked
|
|
75
|
+
inputProps={{ onMouseOver: mockHandleMouseOver }}
|
|
76
|
+
id="checkboxid"
|
|
77
|
+
label="checkbox"
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
fireEvent.mouseOver(options.getByLabelText("checkbox"));
|
|
81
|
+
expect(mockHandleMouseOver).toHaveBeenCalled();
|
|
82
|
+
});
|
|
50
83
|
});
|
package/__flow__/Table/index.js
CHANGED
|
@@ -17,9 +17,9 @@ export type TypeTableRow = {|
|
|
|
17
17
|
|
|
18
18
|
type TypeProps = {
|
|
19
19
|
/** Array of TableHeaderCells to render */
|
|
20
|
-
head
|
|
20
|
+
head?: TypeTableHeaderCell[],
|
|
21
21
|
/** Array of TableRows to render */
|
|
22
|
-
rows
|
|
22
|
+
rows?: TypeTableRow[],
|
|
23
23
|
/** Callback for Sorting Table Columns (optional) */
|
|
24
24
|
onSort?: (id: string) => void,
|
|
25
25
|
/** Controls which column is being sorted (optional) */
|
|
@@ -28,64 +28,92 @@ type TypeProps = {
|
|
|
28
28
|
sortDirection?: TypeEnumSortDirections,
|
|
29
29
|
/** Custom row render for flexibilty */
|
|
30
30
|
rowRender?: (row: TypeTableRow) => React.Node,
|
|
31
|
+
/**
|
|
32
|
+
* Including children will overwrite all head, rows, rowRender, and sorting props
|
|
33
|
+
* Should be used for manually rendering tables and ignoring data props
|
|
34
|
+
*/
|
|
35
|
+
children?: React.Node,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const renderTableRow = (row: TypeTableRow) => {
|
|
39
|
+
return (
|
|
40
|
+
<tbody key={row.id} data-qa-table-row={""}>
|
|
41
|
+
<tr>
|
|
42
|
+
{row.cells.map((td) => {
|
|
43
|
+
return <TableCell {...td} key={td.id} />;
|
|
44
|
+
})}
|
|
45
|
+
</tr>
|
|
46
|
+
</tbody>
|
|
47
|
+
);
|
|
31
48
|
};
|
|
32
49
|
|
|
33
50
|
/**
|
|
34
51
|
* The table component assist in rendering tablular data.
|
|
35
52
|
*/
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
export const Table = ({
|
|
54
|
+
head = [],
|
|
55
|
+
rows = [],
|
|
56
|
+
onSort,
|
|
57
|
+
sortId,
|
|
58
|
+
sortDirection,
|
|
59
|
+
rowRender,
|
|
60
|
+
children,
|
|
61
|
+
...rest
|
|
62
|
+
}: TypeProps) => {
|
|
63
|
+
if (children) {
|
|
43
64
|
return (
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
{row.cells.map((td) => {
|
|
47
|
-
return <TableCell key={td.id} {...td} />;
|
|
48
|
-
})}
|
|
49
|
-
</tr>
|
|
50
|
-
</tbody>
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
render() {
|
|
55
|
-
const {
|
|
56
|
-
head,
|
|
57
|
-
rows,
|
|
58
|
-
onSort,
|
|
59
|
-
sortId,
|
|
60
|
-
sortDirection,
|
|
61
|
-
rowRender,
|
|
62
|
-
...rest
|
|
63
|
-
} = this.props;
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
// $FlowIssue - upgrade v0.112.0
|
|
67
|
-
<Container data-qa-table={""} {...rest}>
|
|
68
|
-
{head.length > 0 && (
|
|
69
|
-
<thead data-qa-table-header={""}>
|
|
70
|
-
<tr>
|
|
71
|
-
{head.map((th) => {
|
|
72
|
-
return (
|
|
73
|
-
<TableHeaderCell
|
|
74
|
-
{...th}
|
|
75
|
-
key={th.id}
|
|
76
|
-
onSort={onSort}
|
|
77
|
-
sortId={sortId}
|
|
78
|
-
sortDirection={sortDirection}
|
|
79
|
-
/>
|
|
80
|
-
);
|
|
81
|
-
})}
|
|
82
|
-
</tr>
|
|
83
|
-
</thead>
|
|
84
|
-
)}
|
|
85
|
-
{rows.map((row) => {
|
|
86
|
-
return rowRender ? rowRender(row) : this.renderTableRow(row);
|
|
87
|
-
})}
|
|
65
|
+
<Container {...rest} data-qa-table={""}>
|
|
66
|
+
{children}
|
|
88
67
|
</Container>
|
|
89
68
|
);
|
|
90
69
|
}
|
|
91
|
-
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Container {...rest} data-qa-table={""}>
|
|
73
|
+
{head.length > 0 && (
|
|
74
|
+
<thead data-qa-table-header={""}>
|
|
75
|
+
<tr>
|
|
76
|
+
{head.map((th) => {
|
|
77
|
+
return (
|
|
78
|
+
<TableHeaderCell
|
|
79
|
+
{...th}
|
|
80
|
+
key={th.id}
|
|
81
|
+
onSort={onSort}
|
|
82
|
+
sortId={sortId}
|
|
83
|
+
sortDirection={sortDirection}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
})}
|
|
87
|
+
</tr>
|
|
88
|
+
</thead>
|
|
89
|
+
)}
|
|
90
|
+
{rows.map((row) => {
|
|
91
|
+
return rowRender ? rowRender(row) : renderTableRow(row);
|
|
92
|
+
})}
|
|
93
|
+
</Container>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
type TypePassthroughProps = {
|
|
98
|
+
children: React.Node,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const TableHead = ({ children, ...props }: TypePassthroughProps) => (
|
|
102
|
+
<thead {...props}>{children}</thead>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
export const TableBody = ({ children, ...props }: TypePassthroughProps) => (
|
|
106
|
+
<tbody {...props}>{children}</tbody>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
export const TableRow = ({ children, ...props }: TypePassthroughProps) => (
|
|
110
|
+
<tr {...props}>{children}</tr>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
Table.TableHead = TableHead;
|
|
114
|
+
Table.TableBody = TableBody;
|
|
115
|
+
Table.TableRow = TableRow;
|
|
116
|
+
Table.HeaderCell = TableHeaderCell;
|
|
117
|
+
Table.Cell = TableCell;
|
|
118
|
+
|
|
119
|
+
export default Table;
|
|
@@ -248,3 +248,44 @@ export const customRowRendering = () => (
|
|
|
248
248
|
customRowRendering.story = {
|
|
249
249
|
name: "Custom row rendering",
|
|
250
250
|
};
|
|
251
|
+
|
|
252
|
+
export const staticTable = () => {
|
|
253
|
+
const columns = ["Name", "Squad", "Favorite Color"];
|
|
254
|
+
const rows = [
|
|
255
|
+
{
|
|
256
|
+
name: "Mike R",
|
|
257
|
+
squad: "People and Community",
|
|
258
|
+
favoriteColor: "Green",
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: "Travis W",
|
|
262
|
+
squad: "Listening",
|
|
263
|
+
favoriteColor: "Blue",
|
|
264
|
+
},
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<Table>
|
|
269
|
+
<Table.TableHead>
|
|
270
|
+
<Table.TableRow>
|
|
271
|
+
{columns.map((c) => (
|
|
272
|
+
<Table.HeaderCell>{c} </Table.HeaderCell>
|
|
273
|
+
))}
|
|
274
|
+
</Table.TableRow>
|
|
275
|
+
</Table.TableHead>
|
|
276
|
+
<Table.TableBody>
|
|
277
|
+
{rows.map((r) => (
|
|
278
|
+
<Table.TableRow>
|
|
279
|
+
<Table.Cell>{r.name} </Table.Cell>
|
|
280
|
+
<Table.Cell>{r.squad} </Table.Cell>
|
|
281
|
+
<Table.Cell>{r.favoriteColor} </Table.Cell>
|
|
282
|
+
</Table.TableRow>
|
|
283
|
+
))}
|
|
284
|
+
</Table.TableBody>
|
|
285
|
+
</Table>
|
|
286
|
+
);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
staticTable.story = {
|
|
290
|
+
name: "Static Table",
|
|
291
|
+
};
|
|
@@ -73,4 +73,18 @@ describe("The Table Component", () => {
|
|
|
73
73
|
fireEvent.click(getAllByDataQaLabel({ "table-header-cell": "" })[0]);
|
|
74
74
|
expect(callback).toBeCalledWith("food_item");
|
|
75
75
|
});
|
|
76
|
+
|
|
77
|
+
it("renders the children if present", () => {
|
|
78
|
+
const { getByText } = render(
|
|
79
|
+
<Table>
|
|
80
|
+
<tbody>
|
|
81
|
+
<tr>
|
|
82
|
+
<td>Child</td>
|
|
83
|
+
</tr>
|
|
84
|
+
</tbody>
|
|
85
|
+
</Table>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect(getByText("Child")).toBeInTheDocument();
|
|
89
|
+
});
|
|
76
90
|
});
|
|
@@ -2,36 +2,46 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import Container from "./styles";
|
|
4
4
|
|
|
5
|
-
export type TypeTableCell = {
|
|
5
|
+
export type TypeTableCell = {
|
|
6
6
|
/** Table Cell Id */
|
|
7
7
|
id: string,
|
|
8
|
-
/** Content to be render */
|
|
9
|
-
content
|
|
8
|
+
/** Content is deprecated. Please use children instead. Content to be render */
|
|
9
|
+
content?: React.Node,
|
|
10
10
|
/** Controls the colSpan attribute (optional) */
|
|
11
11
|
colSpan?: number,
|
|
12
12
|
/** Controls the width attribute (optional) */
|
|
13
13
|
width?: number,
|
|
14
14
|
/** Controls the CSS text-align property (optional) */
|
|
15
15
|
align?: "left" | "right" | "center" | "justify",
|
|
16
|
-
|
|
16
|
+
/** Children to be rendered */
|
|
17
|
+
children?: React.Node,
|
|
18
|
+
};
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* The table cell component is for rendering table cells and is meant to be used with the table component.
|
|
20
22
|
*/
|
|
21
23
|
export default class TableCell extends React.Component<TypeTableCell> {
|
|
22
24
|
render() {
|
|
23
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
id,
|
|
27
|
+
content,
|
|
28
|
+
colSpan,
|
|
29
|
+
width,
|
|
30
|
+
align,
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
} = this.props;
|
|
24
34
|
|
|
25
35
|
return (
|
|
26
36
|
<Container
|
|
37
|
+
{...rest}
|
|
27
38
|
alignment={align || "left"}
|
|
28
39
|
key={id}
|
|
29
40
|
colSpan={colSpan}
|
|
30
41
|
width={width}
|
|
31
42
|
data-qa-table-cell={""}
|
|
32
|
-
{...rest}
|
|
33
43
|
>
|
|
34
|
-
{content}
|
|
44
|
+
{children || content}
|
|
35
45
|
</Container>
|
|
36
46
|
);
|
|
37
47
|
}
|
|
@@ -4,9 +4,16 @@ import TableCell from "./";
|
|
|
4
4
|
|
|
5
5
|
describe("TableCell", () => {
|
|
6
6
|
it("should render properly", () => {
|
|
7
|
-
const { getByDataQaLabel } = render(
|
|
7
|
+
const { getByDataQaLabel, getByText } = render(
|
|
8
8
|
<TableCell id="stuff" content="more stuff here" />
|
|
9
9
|
);
|
|
10
10
|
expect(getByDataQaLabel({ "table-cell": "" })).toBeTruthy();
|
|
11
|
+
expect(getByText("more stuff here")).toBeInTheDocument();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("renders the children if present", () => {
|
|
15
|
+
const { getByText } = render(<TableCell>Child</TableCell>);
|
|
16
|
+
|
|
17
|
+
expect(getByText("Child")).toBeInTheDocument();
|
|
11
18
|
});
|
|
12
19
|
});
|
|
@@ -13,22 +13,24 @@ export const SORT_DIRECTIONS = {
|
|
|
13
13
|
|
|
14
14
|
export type TypeEnumSortDirections = $Keys<typeof SORT_DIRECTIONS>;
|
|
15
15
|
|
|
16
|
-
export type TypeTableHeaderCell = {
|
|
16
|
+
export type TypeTableHeaderCell = {
|
|
17
17
|
...TypeTableCell,
|
|
18
|
-
/** Deteremines if a table column is sortable (optional) */
|
|
18
|
+
/** Legacy Deteremines if a table column is sortable (optional) */
|
|
19
19
|
isSortable?: boolean,
|
|
20
20
|
/** Truncates text into a singular line with ellipsis (optional) */
|
|
21
21
|
shouldTruncate?: boolean,
|
|
22
|
-
|
|
22
|
+
};
|
|
23
23
|
|
|
24
24
|
type TypeProps = {
|
|
25
25
|
...TypeTableHeaderCell,
|
|
26
|
-
/** Callback for Sorting Table Columns (optional) */
|
|
26
|
+
/** Legacy: Callback for Sorting Table Columns (optional) */
|
|
27
27
|
onSort?: (id: string) => void,
|
|
28
|
-
/** Controls which column is being sorted (optional) */
|
|
28
|
+
/** Legacy: Controls which column is being sorted (optional) */
|
|
29
29
|
sortId?: string,
|
|
30
|
-
/** Controls the current sort direction (optional) */
|
|
30
|
+
/** Legacy: Controls the current sort direction (optional) */
|
|
31
31
|
sortDirection?: TypeEnumSortDirections,
|
|
32
|
+
/** Callback for Click Events. If Included will override onSort prop */
|
|
33
|
+
onClick?: (e: SyntheticEvent<HTMLButtonElement>) => void,
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
/**
|
|
@@ -37,6 +39,7 @@ type TypeProps = {
|
|
|
37
39
|
export default class TableHeaderCell extends React.Component<TypeProps> {
|
|
38
40
|
getSortIcon = (isSorted: boolean) => {
|
|
39
41
|
const { sortDirection } = this.props;
|
|
42
|
+
|
|
40
43
|
let iconName = "chevron-up-down-filled";
|
|
41
44
|
|
|
42
45
|
if (isSorted && sortDirection === SORT_DIRECTIONS.ASC) {
|
|
@@ -52,6 +55,17 @@ export default class TableHeaderCell extends React.Component<TypeProps> {
|
|
|
52
55
|
);
|
|
53
56
|
};
|
|
54
57
|
|
|
58
|
+
handleClick = (e: SyntheticEvent<HTMLButtonElement>) => {
|
|
59
|
+
const { onClick, onSort, isSortable, id } = this.props;
|
|
60
|
+
if (onClick) {
|
|
61
|
+
onClick(e);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!isSortable || !onSort) return;
|
|
66
|
+
onSort(id);
|
|
67
|
+
};
|
|
68
|
+
|
|
55
69
|
render() {
|
|
56
70
|
const {
|
|
57
71
|
id,
|
|
@@ -64,25 +78,26 @@ export default class TableHeaderCell extends React.Component<TypeProps> {
|
|
|
64
78
|
onSort,
|
|
65
79
|
sortId,
|
|
66
80
|
sortDirection,
|
|
81
|
+
children,
|
|
82
|
+
onClick,
|
|
67
83
|
...rest
|
|
68
84
|
} = this.props;
|
|
69
85
|
|
|
70
86
|
return (
|
|
71
87
|
<Container
|
|
88
|
+
{...rest}
|
|
72
89
|
key={id}
|
|
73
90
|
alignment={align || "left"}
|
|
74
91
|
sortable={isSortable}
|
|
75
92
|
colSpan={colSpan}
|
|
76
93
|
width={width}
|
|
77
|
-
onClick={
|
|
94
|
+
onClick={this.handleClick}
|
|
78
95
|
data-tableheadercell-sortable={isSortable}
|
|
79
96
|
data-qa-table-header-cell={""}
|
|
80
97
|
data-qa-table-header-cell-sortdirection={sortDirection}
|
|
81
|
-
// $FlowIssue - upgrade v0.112.0
|
|
82
|
-
{...rest}
|
|
83
98
|
>
|
|
84
|
-
{content}
|
|
85
|
-
{isSortable && this.getSortIcon(id === sortId)}
|
|
99
|
+
{children || content}
|
|
100
|
+
{isSortable && !children && this.getSortIcon(id === sortId)}
|
|
86
101
|
</Container>
|
|
87
102
|
);
|
|
88
103
|
}
|
|
@@ -4,7 +4,22 @@ import TableHeaderCell from "./";
|
|
|
4
4
|
|
|
5
5
|
describe("TableHeaderCell", () => {
|
|
6
6
|
it("should render properly", () => {
|
|
7
|
-
const { getByDataQaLabel } = render(
|
|
7
|
+
const { getByDataQaLabel, getByText } = render(
|
|
8
|
+
<table>
|
|
9
|
+
<TableHeaderCell content="more stuff here" />
|
|
10
|
+
</table>
|
|
11
|
+
);
|
|
8
12
|
expect(getByDataQaLabel({ "table-header-cell": "" })).toBeTruthy();
|
|
13
|
+
expect(getByText("more stuff here")).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("renders the children if present", () => {
|
|
17
|
+
const { getByText } = render(
|
|
18
|
+
<table>
|
|
19
|
+
<TableHeaderCell content="content">Child</TableHeaderCell>
|
|
20
|
+
</table>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(getByText("Child")).toBeInTheDocument();
|
|
9
24
|
});
|
|
10
25
|
});
|
|
@@ -35,7 +35,7 @@ export default class TableRowAccordion extends React.Component<TypeProps> {
|
|
|
35
35
|
<Container {...rest} data-qa-table-row-accordion={isExpanded} key={id}>
|
|
36
36
|
<tr data-tablerowaccordion-summary onClick={this.handleToggle}>
|
|
37
37
|
{cells.map((td) => {
|
|
38
|
-
return <TableCell key={td.id}
|
|
38
|
+
return <TableCell {...td} key={td.id} />;
|
|
39
39
|
})}
|
|
40
40
|
<TableCell
|
|
41
41
|
id="tableRowAccordion_trigger"
|