@thecb/components 4.3.0 → 4.3.1
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/.tool-versions +1 -1
- package/dist/index.cjs.js +13 -15
- package/package.json +1 -1
- package/src/components/atoms/layouts/Cluster.styled.js +0 -1
- package/src/components/atoms/tab/Tab.js +32 -0
- package/src/components/atoms/tab/Tab.stories.js +15 -0
- package/src/components/atoms/tab/Tab.theme.js +26 -0
- package/src/components/atoms/tab/index.js +3 -0
- package/src/components/molecules/tabs/Tabs.js +59 -0
- package/src/components/molecules/tabs/Tabs.stories.js +241 -0
- package/src/components/molecules/tabs/Tabs.theme.js +9 -0
- package/src/components/molecules/tabs/index.js +3 -0
package/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
nodejs
|
|
1
|
+
nodejs 15.5.1
|
package/dist/index.cjs.js
CHANGED
|
@@ -6471,7 +6471,7 @@ var Center = function Center(_ref) {
|
|
|
6471
6471
|
};
|
|
6472
6472
|
|
|
6473
6473
|
function _templateObject2$2() {
|
|
6474
|
-
var data = _taggedTemplateLiteral(["\n box-sizing: border-box;\n display: flex;\n flex-wrap: ", ";\n justify-content: ", ";\n align-items: ", ";\n margin: calc(", " / 2 * -1);\n min-height: ", ";\n min-width: ", ";\n
|
|
6474
|
+
var data = _taggedTemplateLiteral(["\n box-sizing: border-box;\n display: flex;\n flex-wrap: ", ";\n justify-content: ", ";\n align-items: ", ";\n margin: calc(", " / 2 * -1);\n min-height: ", ";\n min-width: ", ";\n > * {\n margin: calc(", " / 2);\n }\n"]);
|
|
6475
6475
|
|
|
6476
6476
|
_templateObject2$2 = function _templateObject2() {
|
|
6477
6477
|
return data;
|
|
@@ -15609,19 +15609,10 @@ function _assertThisInitialized(self) {
|
|
|
15609
15609
|
return self;
|
|
15610
15610
|
}
|
|
15611
15611
|
|
|
15612
|
-
function _setPrototypeOf(o, p) {
|
|
15613
|
-
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
15614
|
-
o.__proto__ = p;
|
|
15615
|
-
return o;
|
|
15616
|
-
};
|
|
15617
|
-
|
|
15618
|
-
return _setPrototypeOf(o, p);
|
|
15619
|
-
}
|
|
15620
|
-
|
|
15621
15612
|
function _inheritsLoose(subClass, superClass) {
|
|
15622
15613
|
subClass.prototype = Object.create(superClass.prototype);
|
|
15623
15614
|
subClass.prototype.constructor = subClass;
|
|
15624
|
-
|
|
15615
|
+
subClass.__proto__ = superClass;
|
|
15625
15616
|
}
|
|
15626
15617
|
|
|
15627
15618
|
function _getPrototypeOf(o) {
|
|
@@ -15631,6 +15622,15 @@ function _getPrototypeOf(o) {
|
|
|
15631
15622
|
return _getPrototypeOf(o);
|
|
15632
15623
|
}
|
|
15633
15624
|
|
|
15625
|
+
function _setPrototypeOf(o, p) {
|
|
15626
|
+
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
15627
|
+
o.__proto__ = p;
|
|
15628
|
+
return o;
|
|
15629
|
+
};
|
|
15630
|
+
|
|
15631
|
+
return _setPrototypeOf(o, p);
|
|
15632
|
+
}
|
|
15633
|
+
|
|
15634
15634
|
function _isNativeFunction(fn) {
|
|
15635
15635
|
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|
15636
15636
|
}
|
|
@@ -15641,7 +15641,7 @@ function _isNativeReflectConstruct() {
|
|
|
15641
15641
|
if (typeof Proxy === "function") return true;
|
|
15642
15642
|
|
|
15643
15643
|
try {
|
|
15644
|
-
|
|
15644
|
+
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
|
|
15645
15645
|
return true;
|
|
15646
15646
|
} catch (e) {
|
|
15647
15647
|
return false;
|
|
@@ -15781,9 +15781,7 @@ var ERRORS = {
|
|
|
15781
15781
|
"73": "Please provide a valid CSS variable.\n\n",
|
|
15782
15782
|
"74": "CSS variable not found and no default was provided.\n\n",
|
|
15783
15783
|
"75": "important requires a valid style object, got a %s instead.\n\n",
|
|
15784
|
-
"76": "fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n
|
|
15785
|
-
"77": "remToPx expects a value in \"rem\" but you provided it in \"%s\".\n\n",
|
|
15786
|
-
"78": "base must be set in \"px\" or \"%\" but you set it in \"%s\".\n"
|
|
15784
|
+
"76": "fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n"
|
|
15787
15785
|
};
|
|
15788
15786
|
/**
|
|
15789
15787
|
* super basic version of sprintf
|
package/package.json
CHANGED
|
@@ -22,7 +22,6 @@ export const ClusterInnerWrapper = styled.div`
|
|
|
22
22
|
margin: calc(${({ childGap }) => childGap} / 2 * -1);
|
|
23
23
|
min-height: ${({ minHeight }) => minHeight};
|
|
24
24
|
min-width: ${({ minWidth }) => minWidth};
|
|
25
|
-
|
|
26
25
|
> * {
|
|
27
26
|
margin: calc(${({ childGap }) => childGap} / 2);
|
|
28
27
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Text from "../text";
|
|
3
|
+
import { WHITE, GRECIAN_GREY } from "../../../constants/colors";
|
|
4
|
+
import { Box } from "../../atoms/layouts";
|
|
5
|
+
|
|
6
|
+
const Tab = ({ label, activeTab, setActiveTab }) => {
|
|
7
|
+
const onClick = () => {
|
|
8
|
+
setActiveTab(label);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let className = "tab-list-item";
|
|
12
|
+
if (activeTab === label) {
|
|
13
|
+
className += " tab-list-active";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Box
|
|
18
|
+
className={className}
|
|
19
|
+
onClick={onClick}
|
|
20
|
+
margin="0 0 -1px 0"
|
|
21
|
+
padding="0.5rem 0.75rem"
|
|
22
|
+
background={activeTab === label ? WHITE : GRECIAN_GREY}
|
|
23
|
+
extraStyles={`cursor: pointer; flex-grow: 1; text-align: center; ${
|
|
24
|
+
activeTab === label ? `list-style: none;` : ``
|
|
25
|
+
}`}
|
|
26
|
+
>
|
|
27
|
+
<Text>{label}</Text>
|
|
28
|
+
</Box>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default Tab;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import Tab from "./Tab";
|
|
4
|
+
import page from "../../../../.storybook/page";
|
|
5
|
+
|
|
6
|
+
export const tab = () => (
|
|
7
|
+
<Tab label={"Test"} onClick={() => console.log("test")} />
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const story = page({
|
|
11
|
+
title: "Components|Atoms/Tab",
|
|
12
|
+
Component: Tab
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default story;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fontFamily = {
|
|
2
|
+
p: "Public Sans",
|
|
3
|
+
pL: "Public Sans",
|
|
4
|
+
pS: "Public Sans",
|
|
5
|
+
pXS: "Public Sans",
|
|
6
|
+
pXXS: "Public Sans",
|
|
7
|
+
pXL: "Public Sans"
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// Text uses the same variants as paragraph
|
|
11
|
+
// Use a Paragraph if you want a block level element
|
|
12
|
+
// Use a Text if you want an inline element
|
|
13
|
+
|
|
14
|
+
const fontSize = {
|
|
15
|
+
p: "1rem",
|
|
16
|
+
pL: "1.125rem",
|
|
17
|
+
pS: "0.875rem",
|
|
18
|
+
pXS: "0.75rem",
|
|
19
|
+
pXXS: "0.65rem",
|
|
20
|
+
pXL: "1.5rem"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const fallbackValues = {
|
|
24
|
+
fontFamily,
|
|
25
|
+
fontSize
|
|
26
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { Stack, Box, Cluster } from "../../atoms/layouts";
|
|
3
|
+
import { themeComponent } from "../../../util/themeUtils";
|
|
4
|
+
import { fallbackValues } from "./Tabs.theme";
|
|
5
|
+
import Tab from "../../atoms/tab";
|
|
6
|
+
|
|
7
|
+
const HORIZONTAL = "horizontal";
|
|
8
|
+
|
|
9
|
+
const Tabs = ({
|
|
10
|
+
tabsConfig,
|
|
11
|
+
tabsDisplayMode // can be either HORIZONTAL or VERTICAL
|
|
12
|
+
}) => {
|
|
13
|
+
const [activeTab, toggleActiveTab] = useState(tabsConfig.tabs[0].label);
|
|
14
|
+
|
|
15
|
+
const createTabs = (tabConfig, activeTab) => {
|
|
16
|
+
return tabConfig.tabs.map(tab => {
|
|
17
|
+
return (
|
|
18
|
+
<Tab
|
|
19
|
+
activeTab={activeTab}
|
|
20
|
+
key={tab.label}
|
|
21
|
+
label={tab.label}
|
|
22
|
+
setActiveTab={() => toggleActiveTab(tab.label)}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const showHorozontal = (tabsConfig, activeTab) => {
|
|
29
|
+
return (
|
|
30
|
+
<Cluster justify={"space-around"}>
|
|
31
|
+
{createTabs(tabsConfig, activeTab)}
|
|
32
|
+
</Cluster>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const showVertical = (tabsConfig, activeTab) => {
|
|
37
|
+
return <Stack>{createTabs(tabsConfig, activeTab)}</Stack>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Box className="tabs">
|
|
42
|
+
<Box className="tab-list">
|
|
43
|
+
{tabsDisplayMode == HORIZONTAL
|
|
44
|
+
? showHorozontal(tabsConfig, activeTab)
|
|
45
|
+
: showVertical(tabsConfig, activeTab)}
|
|
46
|
+
</Box>
|
|
47
|
+
<Box className="tab-content">
|
|
48
|
+
<Box>
|
|
49
|
+
{tabsConfig.tabs.map(tab => {
|
|
50
|
+
if (tab.label !== activeTab) return undefined;
|
|
51
|
+
return tab.content;
|
|
52
|
+
})}
|
|
53
|
+
</Box>
|
|
54
|
+
</Box>
|
|
55
|
+
</Box>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default themeComponent(Tabs, "NavigationTab", fallbackValues);
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createStore } from "redux";
|
|
3
|
+
import Tabs from "./Tabs";
|
|
4
|
+
|
|
5
|
+
import page from "../../../../.storybook/page";
|
|
6
|
+
import Text from "../../atoms/text";
|
|
7
|
+
|
|
8
|
+
import { createFormState, onlyIntegers, required } from "redux-freeform";
|
|
9
|
+
import DisplayBox from "../../atoms/display-box";
|
|
10
|
+
import { Box } from "../../atoms/layouts";
|
|
11
|
+
|
|
12
|
+
// Including commented out configs as a preliminary work for
|
|
13
|
+
// https://citybase.atlassian.net/browse/KCORE-2973
|
|
14
|
+
// https://citybase.atlassian.net/browse/KCORE-2974
|
|
15
|
+
// https://citybase.atlassian.net/browse/KCORE-2975
|
|
16
|
+
|
|
17
|
+
const ButtonTest = () => (
|
|
18
|
+
<DisplayBox>
|
|
19
|
+
<Text>Test Button Clicks</Text>
|
|
20
|
+
<Box>
|
|
21
|
+
<button onClick={() => console.log("BUTTON TEST;")}>Click me</button>
|
|
22
|
+
</Box>
|
|
23
|
+
</DisplayBox>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
//const creditCardFormConfig = {
|
|
27
|
+
// amount: {
|
|
28
|
+
// defaultValue: "100.00",
|
|
29
|
+
// validators: [required()]
|
|
30
|
+
// }
|
|
31
|
+
//};
|
|
32
|
+
|
|
33
|
+
const checkFormConfig = {
|
|
34
|
+
amount: {
|
|
35
|
+
defaultValue: "100.00",
|
|
36
|
+
validators: [required()]
|
|
37
|
+
},
|
|
38
|
+
name: {
|
|
39
|
+
validators: [required()]
|
|
40
|
+
},
|
|
41
|
+
accountNumber: {
|
|
42
|
+
validators: [onlyIntegers()]
|
|
43
|
+
},
|
|
44
|
+
routingNumber: {
|
|
45
|
+
validators: [onlyIntegers()]
|
|
46
|
+
},
|
|
47
|
+
checkType: {
|
|
48
|
+
defaultValue: "Personal"
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//const cashFormConfig = {
|
|
53
|
+
// amount: {
|
|
54
|
+
// defaultValue: "100.00",
|
|
55
|
+
// validators: [required()]
|
|
56
|
+
// }
|
|
57
|
+
//};
|
|
58
|
+
//
|
|
59
|
+
//const MyCreditCardForm = ({ actions, fields }) => {
|
|
60
|
+
// return (
|
|
61
|
+
// <div>
|
|
62
|
+
// {fields.amount.hasErrors && fields.amount.errors.includes(required.error)
|
|
63
|
+
// ? "Amount"
|
|
64
|
+
// : "Amount"}
|
|
65
|
+
// <input
|
|
66
|
+
// value={fields.amount.rawValue}
|
|
67
|
+
// onChange={evt => actions.fields.amount.set(evt.target.value)}
|
|
68
|
+
// type="text"
|
|
69
|
+
// />
|
|
70
|
+
// </div>
|
|
71
|
+
// );
|
|
72
|
+
//};
|
|
73
|
+
|
|
74
|
+
const MyCheckForm = ({ actions, fields }) => (
|
|
75
|
+
<div>
|
|
76
|
+
{fields.amount.hasErrors && fields.amount.errors.includes(required.error)
|
|
77
|
+
? "AmountError"
|
|
78
|
+
: "Amount"}
|
|
79
|
+
<input
|
|
80
|
+
value={fields.amount.rawValue}
|
|
81
|
+
onChange={evt => actions.fields.amount.set(evt.target.value)}
|
|
82
|
+
type="text"
|
|
83
|
+
/>
|
|
84
|
+
{fields.name.hasErrors && fields.name.errors.includes(required.error)
|
|
85
|
+
? "Name Error"
|
|
86
|
+
: "Name"}
|
|
87
|
+
<input
|
|
88
|
+
value={fields.name.rawValue}
|
|
89
|
+
onChange={evt => actions.fields.name.set(evt.target.value)}
|
|
90
|
+
type="text"
|
|
91
|
+
/>
|
|
92
|
+
{fields.accountNumber.hasErrors &&
|
|
93
|
+
fields.accountNumber.errors.includes(required.error)
|
|
94
|
+
? "Account Number Error"
|
|
95
|
+
: "Account Number"}
|
|
96
|
+
<input
|
|
97
|
+
value={fields.accountNumber.rawValue}
|
|
98
|
+
onChange={evt => actions.fields.accountNumber.set(evt.target.value)}
|
|
99
|
+
type="text"
|
|
100
|
+
/>
|
|
101
|
+
{fields.routingNumber.hasErrors &&
|
|
102
|
+
fields.routingNumber.errors.includes(required.error)
|
|
103
|
+
? "Routing Number Error"
|
|
104
|
+
: "Routing Number"}
|
|
105
|
+
<input
|
|
106
|
+
value={fields.routingNumber.rawValue}
|
|
107
|
+
onChange={evt => actions.fields.routingNumber.set(evt.target.value)}
|
|
108
|
+
type="text"
|
|
109
|
+
/>
|
|
110
|
+
{fields.checkType.hasErrors &&
|
|
111
|
+
fields.checkType.errors.includes(required.error)
|
|
112
|
+
? "Check Type Error"
|
|
113
|
+
: "Check Type"}
|
|
114
|
+
<input
|
|
115
|
+
value={fields.checkType.rawValue}
|
|
116
|
+
onChange={evt => actions.fields.checkType.set(evt.target.value)}
|
|
117
|
+
type="text"
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
//const MyCashForm = ({ actions, fields }) => (
|
|
123
|
+
// <div>
|
|
124
|
+
// {fields.amount.hasErrors && fields.amount.errors.includes(required.error)
|
|
125
|
+
// ? "Amount Error"
|
|
126
|
+
// : "Amount"}
|
|
127
|
+
// <input
|
|
128
|
+
// value={fields.amount.rawValue}
|
|
129
|
+
// onChange={evt => actions.fields.amount.set(evt.target.value)}
|
|
130
|
+
// type="text"
|
|
131
|
+
// />
|
|
132
|
+
// </div>
|
|
133
|
+
//);
|
|
134
|
+
|
|
135
|
+
//const {
|
|
136
|
+
// reducer: cardReducer,
|
|
137
|
+
// mapStateToProps: cardMapStateToProps,
|
|
138
|
+
// mapDispatchToProps: cardMapDispatchToProps
|
|
139
|
+
//} = createFormState(creditCardFormConfig);
|
|
140
|
+
|
|
141
|
+
const {
|
|
142
|
+
reducer: checkReducer,
|
|
143
|
+
mapStateToProps: checkMapStateToProps,
|
|
144
|
+
mapDispatchToProps: checkMapDispatchToProps
|
|
145
|
+
} = createFormState(checkFormConfig);
|
|
146
|
+
|
|
147
|
+
//const {
|
|
148
|
+
// reducer: cashReducer,
|
|
149
|
+
// mapStateToProps: cashMapStateToProps,
|
|
150
|
+
// mapDispatchToProps: cashMapDispatchToProps
|
|
151
|
+
//} = createFormState(cashFormConfig);
|
|
152
|
+
|
|
153
|
+
//const cardStore = createStore(
|
|
154
|
+
// cardReducer,
|
|
155
|
+
// window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
156
|
+
//);
|
|
157
|
+
|
|
158
|
+
const checkStore = createStore(
|
|
159
|
+
checkReducer,
|
|
160
|
+
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
//const cashStore = createStore(
|
|
164
|
+
// cashReducer,
|
|
165
|
+
// window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
166
|
+
//);
|
|
167
|
+
|
|
168
|
+
//const tabsConfig = {
|
|
169
|
+
// tabs: [
|
|
170
|
+
// {
|
|
171
|
+
// label: 'Credit Card',
|
|
172
|
+
// active: true,
|
|
173
|
+
// content: MyCreditCardForm(
|
|
174
|
+
// {...cardMapStateToProps(cardStore.getState())},
|
|
175
|
+
// {...cardMapDispatchToProps(cardStore.dispatch)}
|
|
176
|
+
// )
|
|
177
|
+
// },
|
|
178
|
+
// {
|
|
179
|
+
// label: 'Check',
|
|
180
|
+
// active: true,
|
|
181
|
+
// content: MyCheckForm(
|
|
182
|
+
// {...checkMapStateToProps(checkStore.getState())},
|
|
183
|
+
// {...checkMapDispatchToProps(checkStore.dispatch)}
|
|
184
|
+
// )
|
|
185
|
+
// },
|
|
186
|
+
// {
|
|
187
|
+
// true: 'Cash',
|
|
188
|
+
// active: true,
|
|
189
|
+
// content: MyCashForm(
|
|
190
|
+
// {...cashMapStateToProps(cashStore.getState())},
|
|
191
|
+
// {...cashMapDispatchToProps(cashStore.dispatch)}
|
|
192
|
+
// )
|
|
193
|
+
// }
|
|
194
|
+
// ]
|
|
195
|
+
//};
|
|
196
|
+
|
|
197
|
+
const LOREM = `
|
|
198
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
|
199
|
+
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
200
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
|
201
|
+
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
|
202
|
+
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
|
203
|
+
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
|
|
204
|
+
deserunt mollit anim id est laborum.
|
|
205
|
+
`;
|
|
206
|
+
|
|
207
|
+
const tabsConfig = {
|
|
208
|
+
tabs: [
|
|
209
|
+
{
|
|
210
|
+
label: "Credit Card",
|
|
211
|
+
active: true,
|
|
212
|
+
content: <Text>{LOREM}</Text>
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
label: "Check",
|
|
216
|
+
active: true,
|
|
217
|
+
content: MyCheckForm(
|
|
218
|
+
{ ...checkMapStateToProps(checkStore.getState()) },
|
|
219
|
+
{ ...checkMapDispatchToProps(checkStore.dispatch) }
|
|
220
|
+
)
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
label: "Cash",
|
|
224
|
+
active: true,
|
|
225
|
+
content: <ButtonTest></ButtonTest>
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const HORIZONTAL = "horizontal";
|
|
231
|
+
|
|
232
|
+
export const tabs = () => (
|
|
233
|
+
<Tabs tabsConfig={tabsConfig} tabsDisplayMode={HORIZONTAL} />
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
const story = page({
|
|
237
|
+
title: "Components|Molecules/Tabs",
|
|
238
|
+
Component: Tabs
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
export default story;
|