@pareto-engineering/design-system 2.0.0-alpha.44 → 2.0.0-alpha.45

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.
Files changed (27) hide show
  1. package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +36 -51
  2. package/dist/cjs/f/fields/QueryCombobox/common/Combobox/Combobox.js +47 -14
  3. package/dist/cjs/f/fields/QueryCombobox/common/Menu/Menu.js +1 -1
  4. package/dist/cjs/f/fields/QueryCombobox/common/index.js +1 -9
  5. package/dist/cjs/f/fields/QueryCombobox/styles.scss +45 -39
  6. package/dist/cjs/f/fields/index.js +9 -1
  7. package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +40 -53
  8. package/dist/es/f/fields/QueryCombobox/common/Combobox/Combobox.js +48 -16
  9. package/dist/es/f/fields/QueryCombobox/common/Menu/Menu.js +1 -1
  10. package/dist/es/f/fields/QueryCombobox/common/index.js +1 -2
  11. package/dist/es/f/fields/QueryCombobox/styles.scss +45 -39
  12. package/dist/es/f/fields/index.js +2 -1
  13. package/package.json +3 -2
  14. package/src/__snapshots__/Storyshots.test.js.snap +158 -0
  15. package/src/stories/f/QueryCombobox.stories.jsx +220 -0
  16. package/src/stories/f/__generated__/QueryComboboxAllTeamsQuery.graphql.js +139 -0
  17. package/src/stories/utils/generateNodeId.js +12 -0
  18. package/src/stories/utils/testData.js +63 -0
  19. package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +200 -0
  20. package/src/ui/f/fields/QueryCombobox/common/Combobox/Combobox.jsx +198 -0
  21. package/src/ui/f/fields/QueryCombobox/common/Combobox/index.js +2 -0
  22. package/src/ui/f/fields/QueryCombobox/common/Menu/Menu.jsx +103 -0
  23. package/src/ui/f/fields/QueryCombobox/common/Menu/index.js +2 -0
  24. package/src/ui/f/fields/QueryCombobox/common/index.js +2 -0
  25. package/src/ui/f/fields/QueryCombobox/index.js +2 -0
  26. package/src/ui/f/fields/QueryCombobox/styles.scss +71 -0
  27. package/src/ui/f/fields/index.js +1 -0
@@ -2,11 +2,12 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
2
2
 
3
3
  /* @pareto-engineering/generator-front 1.0.12 */
4
4
  import * as React from 'react';
5
- import { useEffect } from 'react';
5
+ import { useEffect, useRef } from 'react';
6
6
  import PropTypes from 'prop-types';
7
7
  import { useCombobox } from 'downshift';
8
8
  import styleNames from '@pareto-engineering/bem';
9
- import { FormLabel, FormDescription } from "../../../.."; // Local Definitions
9
+ import { FormLabel, FormDescription } from "../../../..";
10
+ import { Popover } from "../../../../../a"; // Local Definitions
10
11
 
11
12
  import { Menu } from "../Menu";
12
13
  const baseClassName = styleNames.base;
@@ -22,14 +23,17 @@ const Combobox = ({
22
23
  label,
23
24
  name,
24
25
  options: items,
25
- fetchOptions,
26
+ getOptions,
26
27
  setValue,
27
28
  error,
28
- description // ...otherProps
29
+ description,
30
+ value,
31
+ color // ...otherProps
29
32
 
30
33
  }) => {
31
34
  const {
32
35
  isOpen,
36
+ selectItem,
33
37
  selectedItem,
34
38
  getLabelProps,
35
39
  getMenuProps,
@@ -39,33 +43,48 @@ const Combobox = ({
39
43
  getItemProps
40
44
  } = useCombobox({
41
45
  items,
46
+ initialSelectedItem: value,
42
47
  itemToString: item => item ? item.label : '',
43
48
  onInputValueChange: ({
44
49
  inputValue
45
50
  }) => {
46
- fetchOptions(inputValue);
51
+ getOptions(inputValue);
47
52
  }
48
- });
53
+ }); // If the user has selected an item, we'll set the value of the field
54
+ // or if the combobox state has a selected item, we'll set the value to the formik state
55
+
49
56
  useEffect(() => {
50
57
  if (selectedItem) {
51
- setValue(selectedItem.value);
58
+ setValue(selectedItem);
59
+ }
60
+ }, [selectedItem]); // If the formik state has a value, we'll set the selected item to the combobox state
61
+
62
+ useEffect(() => {
63
+ if ((value === null || value === void 0 ? void 0 : value.value) !== (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value)) {
64
+ selectItem(value);
52
65
  }
53
- }, [selectedItem]);
66
+ }, [value]);
67
+ const parentRef = useRef(null);
54
68
  return /*#__PURE__*/React.createElement("div", {
55
69
  id: id,
56
- className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
57
- style: style
70
+ className: [baseClassName, componentClassName, userClassName, `y-${color}`].filter(e => e).join(' '),
71
+ style: style,
72
+ ref: parentRef
58
73
  }, /*#__PURE__*/React.createElement(FormLabel, _extends({}, getLabelProps(), {
59
- className: "input-label",
60
74
  name: name
61
- }), label), /*#__PURE__*/React.createElement("div", getComboboxProps(), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
75
+ }), label), /*#__PURE__*/React.createElement("div", _extends({}, getComboboxProps(), {
76
+ className: "input-wrapper"
77
+ }), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
62
78
  className: "input"
63
- }))), /*#__PURE__*/React.createElement(Menu, _extends({
79
+ }))), /*#__PURE__*/React.createElement(Popover, {
80
+ isOpen: isOpen,
81
+ parentRef: parentRef
82
+ }, /*#__PURE__*/React.createElement(Menu, _extends({
64
83
  isOpen: isOpen,
65
84
  getItemProps: getItemProps,
66
85
  highlightedIndex: highlightedIndex,
67
86
  items: items
68
- }, getMenuProps())), (description || error) && /*#__PURE__*/React.createElement(FormDescription, {
87
+ }, getMenuProps()))), (description || error) && /*#__PURE__*/React.createElement(FormDescription, {
69
88
  isError: !!error
70
89
  }, error || description));
71
90
  };
@@ -107,7 +126,7 @@ Combobox.propTypes = {
107
126
  /**
108
127
  * The function to fetch the options from the backend
109
128
  */
110
- fetchOptions: PropTypes.func,
129
+ getOptions: PropTypes.func,
111
130
 
112
131
  /**
113
132
  * The function to set the value of the custom select input
@@ -122,7 +141,20 @@ Combobox.propTypes = {
122
141
  /**
123
142
  * The error object
124
143
  */
125
- error: PropTypes.objectOf(PropTypes.string)
144
+ error: PropTypes.objectOf(PropTypes.string),
145
+
146
+ /**
147
+ * The value of the custom select input
148
+ */
149
+ value: PropTypes.shape({
150
+ value: PropTypes.string,
151
+ label: PropTypes.string
152
+ }),
153
+
154
+ /**
155
+ * The base color of the combobox custom select input
156
+ */
157
+ color: PropTypes.string
126
158
  };
127
159
  Combobox.defaultProps = {// someProp:false
128
160
  };
@@ -31,7 +31,7 @@ const Menu = /*#__PURE__*/React.forwardRef(({
31
31
  item,
32
32
  index
33
33
  }), {
34
- className: `item ${highlightedIndex === index ? styleNames.modifierActive : ''}`
34
+ className: ['item', highlightedIndex === index && styleNames.modifierActive].filter(Boolean).join(' ')
35
35
  }), /*#__PURE__*/React.createElement("p", null, item.label)))));
36
36
  Menu.propTypes = {
37
37
  /**
@@ -1,3 +1,2 @@
1
1
  export { Menu } from "./Menu";
2
- export { Combobox } from "./Combobox";
3
- export { MultipleCombobox } from "./MultipleCombobox";
2
+ export { Combobox } from "./Combobox";
@@ -6,60 +6,66 @@ $default-input-padding: .75em .75em .55em;
6
6
  $default-padding: 1em;
7
7
  $default-margin: 1em;
8
8
 
9
- .#{bem.$base}.query-combobox {
10
- .input {
11
- background: var(--light-y);
12
- border: var(--theme-border-style) var(--dark-y);
13
- color: var(--on-y);
14
- padding: $default-input-padding;
9
+ .#{bem.$base}.combobox,
10
+ .#{bem.$base}.multiple-combobox {
11
+ position: relative;
12
+
13
+ .#{bem.$base}.popover {
15
14
  width: 100%;
16
15
 
17
- &::placeholder {
18
- color: var(--metadata);
19
- }
16
+ >.menu {
17
+ list-style: none;
18
+ margin: 0;
19
+ outline: 0;
20
+ padding: 0;
20
21
 
21
- &:not(:disabled):hover {
22
- border: var(--theme-border-style) var(--light-background4);
23
- }
24
-
25
- &:disabled {
26
- background-color: var(--dark-y);
27
- }
22
+ >.item {
23
+ padding: $default-padding / 2;
28
24
 
29
- &:focus {
30
- background: var(--light-background4);
25
+ &.#{bem.$modifier-active} {
26
+ background-color: var(--background2);
27
+ }
28
+ }
31
29
  }
32
30
  }
33
31
 
34
- .menu {
35
- list-style: none;
36
- margin: 0;
37
- outline: 0;
38
- padding: 0;
32
+ >.input-wrapper {
33
+ >.input {
34
+ background: var(--light-y);
35
+ border: var(--theme-border-style) var(--dark-y);
36
+ color: var(--on-y);
37
+ padding: $default-input-padding;
38
+ width: 100%;
39
39
 
40
- /* stylelint-disable selector-max-universal -- Allow */
41
- >* {
42
- padding-block: $default-padding / 2;
43
- }
40
+ &::placeholder {
41
+ color: var(--metadata);
42
+ }
44
43
 
45
- /* stylelint-enable selector-max-universal */
46
- >.item {
47
- &.#{bem.$modifier-active} {
48
- background-color: var(--background2);
44
+ &:not(:disabled):hover {
45
+ border: var(--theme-border-style) var(--light-background4);
46
+ }
47
+
48
+ &:disabled {
49
+ background-color: var(--dark-y);
50
+ }
51
+
52
+ &:focus {
53
+ background: var(--light-background4);
49
54
  }
50
55
  }
51
56
  }
57
+ }
52
58
 
53
- .multiple-combobox {
54
- .selected-items {
55
- display: flex;
56
59
 
57
- /* stylelint-disable selector-max-universal -- Allow */
58
- >*:not(:first-child) {
59
- margin-left: $default-margin;
60
- }
60
+ .#{bem.$base}.multiple-combobox {
61
+ >.selected-items {
62
+ display: flex;
61
63
 
62
- /* stylelint-enable selector-max-universal */
64
+ /* stylelint-disable selector-max-universal -- Allow */
65
+ >*:not(:first-child) {
66
+ margin-left: $default-margin;
63
67
  }
68
+
69
+ /* stylelint-enable selector-max-universal */
64
70
  }
65
71
  }
@@ -2,4 +2,5 @@ export { TextInput } from "./TextInput";
2
2
  export { SelectInput } from "./SelectInput";
3
3
  export { ChoicesInput } from "./ChoicesInput";
4
4
  export { TextareaInput } from "./TextareaInput";
5
- export { RatingsInput } from "./RatingsInput";
5
+ export { RatingsInput } from "./RatingsInput";
6
+ export { QueryCombobox } from "./QueryCombobox";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pareto-engineering/design-system",
3
- "version": "2.0.0-alpha.44",
3
+ "version": "2.0.0-alpha.45",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.js",
@@ -88,10 +88,11 @@
88
88
  "stylelint-config-palantir": "^5.1.0"
89
89
  },
90
90
  "dependencies": {
91
- "@pareto-engineering/assets": "^2.0.0-alpha.18",
91
+ "@pareto-engineering/assets": "^2.0.0-alpha.21",
92
92
  "@pareto-engineering/bem": "^0.1.5",
93
93
  "@pareto-engineering/styles": "^2.0.0-alpha.8",
94
94
  "date-fns": "^2.22.1",
95
+ "downshift": "^6.1.7",
95
96
  "formik": "^2.2.9",
96
97
  "hamburgers": "^1.1.3",
97
98
  "lodash": "^4.17.21",
@@ -11198,6 +11198,164 @@ exports[`Storyshots f/fields/ChoicesInput Multiple With Grid 1`] = `
11198
11198
  </form>
11199
11199
  `;
11200
11200
 
11201
+ exports[`Storyshots f/fields/QueryCombobox Single Select 1`] = `
11202
+ <form
11203
+ action="#"
11204
+ onReset={[Function]}
11205
+ onSubmit={[Function]}
11206
+ >
11207
+ <div
11208
+ className="base combobox y-background2"
11209
+ >
11210
+ <label
11211
+ className="base label x-main2"
11212
+ htmlFor="team"
11213
+ id="downshift-0-label"
11214
+ >
11215
+ Search for a team
11216
+ </label>
11217
+ <div
11218
+ aria-expanded={false}
11219
+ aria-haspopup="listbox"
11220
+ aria-owns="downshift-0-menu"
11221
+ className="input-wrapper"
11222
+ role="combobox"
11223
+ >
11224
+ <input
11225
+ aria-autocomplete="list"
11226
+ aria-controls="downshift-0-menu"
11227
+ aria-labelledby="downshift-0-label"
11228
+ autoComplete="off"
11229
+ className="input"
11230
+ id="downshift-0-input"
11231
+ onBlur={[Function]}
11232
+ onChange={[Function]}
11233
+ onKeyDown={[Function]}
11234
+ value=""
11235
+ />
11236
+ </div>
11237
+ <div
11238
+ className="base popover x-background1 bottom left"
11239
+ >
11240
+ <ul
11241
+ aria-labelledby="downshift-0-label"
11242
+ className="base menu"
11243
+ id="downshift-0-menu"
11244
+ onMouseLeave={[Function]}
11245
+ role="listbox"
11246
+ />
11247
+ </div>
11248
+ </div>
11249
+ <div
11250
+ style={
11251
+ Object {
11252
+ "alignItems": "flex-end",
11253
+ "display": "flex",
11254
+ "flexDirection": "column",
11255
+ }
11256
+ }
11257
+ >
11258
+ <div
11259
+ className="debugger"
11260
+ >
11261
+ <button
11262
+ className="base button x-main2"
11263
+ onClick={[Function]}
11264
+ type="button"
11265
+ >
11266
+ Open FormDebugger
11267
+ </button>
11268
+ </div>
11269
+ <button
11270
+ className="base button x-main1"
11271
+ onClick={[Function]}
11272
+ type="button"
11273
+ >
11274
+ Replace initial value
11275
+ </button>
11276
+ </div>
11277
+ </form>
11278
+ `;
11279
+
11280
+ exports[`Storyshots f/fields/QueryCombobox Single Select With Default Formik State 1`] = `
11281
+ <form
11282
+ action="#"
11283
+ onReset={[Function]}
11284
+ onSubmit={[Function]}
11285
+ >
11286
+ <div
11287
+ className="base combobox y-background2"
11288
+ >
11289
+ <label
11290
+ className="base label x-main2"
11291
+ htmlFor="team"
11292
+ id="downshift-1-label"
11293
+ >
11294
+ Search for a team
11295
+ </label>
11296
+ <div
11297
+ aria-expanded={false}
11298
+ aria-haspopup="listbox"
11299
+ aria-owns="downshift-1-menu"
11300
+ className="input-wrapper"
11301
+ role="combobox"
11302
+ >
11303
+ <input
11304
+ aria-autocomplete="list"
11305
+ aria-controls="downshift-1-menu"
11306
+ aria-labelledby="downshift-1-label"
11307
+ autoComplete="off"
11308
+ className="input"
11309
+ id="downshift-1-input"
11310
+ onBlur={[Function]}
11311
+ onChange={[Function]}
11312
+ onKeyDown={[Function]}
11313
+ value="Apple"
11314
+ />
11315
+ </div>
11316
+ <div
11317
+ className="base popover x-background1 bottom left"
11318
+ >
11319
+ <ul
11320
+ aria-labelledby="downshift-1-label"
11321
+ className="base menu"
11322
+ id="downshift-1-menu"
11323
+ onMouseLeave={[Function]}
11324
+ role="listbox"
11325
+ />
11326
+ </div>
11327
+ </div>
11328
+ <div
11329
+ style={
11330
+ Object {
11331
+ "alignItems": "flex-end",
11332
+ "display": "flex",
11333
+ "flexDirection": "column",
11334
+ }
11335
+ }
11336
+ >
11337
+ <div
11338
+ className="debugger"
11339
+ >
11340
+ <button
11341
+ className="base button x-main2"
11342
+ onClick={[Function]}
11343
+ type="button"
11344
+ >
11345
+ Open FormDebugger
11346
+ </button>
11347
+ </div>
11348
+ <button
11349
+ className="base button x-main1"
11350
+ onClick={[Function]}
11351
+ type="button"
11352
+ >
11353
+ Replace initial value
11354
+ </button>
11355
+ </div>
11356
+ </form>
11357
+ `;
11358
+
11201
11359
  exports[`Storyshots f/fields/RatingsInput Base 1`] = `
11202
11360
  <form
11203
11361
  action="#"
@@ -0,0 +1,220 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ import * as React from 'react'
3
+
4
+ import { Formik, Form, useField } from 'formik'
5
+
6
+ import { Button, FormDebugger, QueryCombobox } from 'ui'
7
+
8
+ import { fruits } from '../utils/testData'
9
+
10
+ import generateNodeId from '../utils/generateNodeId'
11
+
12
+ import {
13
+ RelayEnvironmentProvider,
14
+ mockRelayOperation,
15
+ // environment,
16
+ } from '../utils/relay'
17
+
18
+ export default {
19
+ title :'f/fields/QueryCombobox',
20
+ component :QueryCombobox,
21
+ subcomponents:{
22
+ // Item:QueryCombobox.Item
23
+ },
24
+ decorators:[
25
+ (storyfn) => (
26
+ <RelayEnvironmentProvider>
27
+ { storyfn() }
28
+ </RelayEnvironmentProvider>
29
+ ),
30
+ ],
31
+ argTypes:{
32
+ backgroundColor:{ control: 'color' },
33
+ },
34
+ }
35
+
36
+ const allTeamsMockData = {
37
+ PageInfo() {
38
+ return {
39
+ hasNextPage :true,
40
+ hasPreviousPage:true,
41
+ }
42
+ },
43
+ TeamNodeConnection:(args) => {
44
+ const edges = fruits.map((fruit) => ({
45
+ node:{
46
+ id :generateNodeId('TeamNode'),
47
+ name:fruit,
48
+ },
49
+ }))
50
+
51
+ // eslint-disable-next-line camelcase
52
+ const { name_Icontains } = args?.args || {}
53
+
54
+ return ({
55
+ pageInfo:{
56
+ hasNextPage :true,
57
+ hasPreviousPage:true,
58
+ },
59
+ // eslint-disable-next-line camelcase
60
+ edges:name_Icontains?.trim()
61
+ ? edges.filter(({ node }) => node.name
62
+ .toLowerCase()
63
+ .includes(name_Icontains.toLowerCase()))
64
+ : [],
65
+ })
66
+ },
67
+ }
68
+
69
+ const FETCH_TEAMS_QUERY = graphql`
70
+ query QueryComboboxAllTeamsQuery($name_Icontains: String) {
71
+ allTeams(name_Icontains: $name_Icontains) {
72
+ edges {
73
+ node {
74
+ id
75
+ name
76
+ }
77
+ }
78
+ }
79
+ }
80
+ `
81
+
82
+ // eslint-disable-next-line react/prop-types
83
+ const ResolvedTemplate = ({ multiple, defaultFormikState = {} }) => {
84
+ mockRelayOperation(allTeamsMockData)
85
+ mockRelayOperation(allTeamsMockData)
86
+ mockRelayOperation(allTeamsMockData)
87
+
88
+ const Content = () => {
89
+ const name = multiple ? 'teams' : 'team'
90
+
91
+ const [, , helpers] = useField(name)
92
+
93
+ const { setValue } = helpers
94
+
95
+ const updateFormikState = () => {
96
+ setValue({
97
+ value:'VGVhbU5vZGU6MDAxZTIyOGEtYzA5My00MGI0LWE1MTUtYTNkMTM1NTE1MDNk',
98
+ label:'Kafagoho',
99
+ })
100
+ }
101
+
102
+ return (
103
+ <>
104
+ <QueryCombobox
105
+ query={FETCH_TEAMS_QUERY}
106
+ label="Search for a team"
107
+ optionsKeyMap={{
108
+ value:'id',
109
+ label:'name',
110
+ }}
111
+ name={name}
112
+ multiple={multiple}
113
+ graphQlNode="allTeams"
114
+ searchVariable="name_Icontains"
115
+ />
116
+ <div
117
+ style={{
118
+ display :'flex',
119
+ alignItems :'flex-end',
120
+ flexDirection:'column',
121
+ }}
122
+ >
123
+ <FormDebugger />
124
+ <Button
125
+ onClick={updateFormikState}
126
+ >
127
+ {multiple ? 'Add more initial values' : 'Replace initial value'}
128
+ </Button>
129
+ </div>
130
+ </>
131
+ )
132
+ }
133
+
134
+ return (
135
+ <Formik
136
+ initialValues={defaultFormikState}
137
+ >
138
+ <Form>
139
+ <Content />
140
+ </Form>
141
+ </Formik>
142
+ )
143
+ }
144
+
145
+ export const SingleSelect = ResolvedTemplate.bind({})
146
+ SingleSelect.args = {
147
+ multiple:false,
148
+ }
149
+
150
+ export const SingleSelectWithDefaultFormikState = ResolvedTemplate.bind({})
151
+ SingleSelectWithDefaultFormikState.args = {
152
+ multiple :false,
153
+ defaultFormikState:{
154
+ team:{
155
+ value:'VGVhbU5vZGU6MDAxZTIyOGEtYzA5My00MGI0LWE1MTUtYTNkMTM1NTE1MDNl',
156
+ label:'Apple',
157
+ },
158
+ },
159
+ }
160
+
161
+ // eslint-disable-next-line react/prop-types
162
+ // const RejectedTemplate = ({ multiple }) => {
163
+ // const Content = () => {
164
+ // environment.mock.queuePendingOperation(
165
+ // FETCH_TEAMS_QUERY,
166
+ // { name_Icontains: 'a' },
167
+ // )
168
+
169
+ // environment.mock.rejectMostRecentOperation('An error has occured while fetching the teams')
170
+
171
+ // const name = multiple ? 'teams' : 'team'
172
+
173
+ // const [, meta, helpers] = useField(name)
174
+
175
+ // const { setValue, setError } = helpers
176
+
177
+ // const { error } = meta
178
+
179
+ // return (
180
+ // <>
181
+ // <QueryCombobox
182
+ // query={FETCH_TEAMS_QUERY}
183
+ // label="Search for a team"
184
+ // optionsKeyMap={{
185
+ // value:'id',
186
+ // label:'name',
187
+ // }}
188
+ // error={error}
189
+ // setValue={setValue}
190
+ // setError={setError}
191
+ // name={name}
192
+ // multiple={multiple}
193
+ // graphQlNode="allTeams"
194
+ // searchVariable="name_Icontains"
195
+ // />
196
+ // <FormDebugger />
197
+ // </>
198
+ // )
199
+ // }
200
+
201
+ // return (
202
+ // <Formik
203
+ // initialValues={{ team: '' }}
204
+ // >
205
+ // <Form>
206
+ // <Content />
207
+ // </Form>
208
+ // </Formik>
209
+ // )
210
+ // }
211
+
212
+ // export const SingleSelectWithError = RejectedTemplate.bind({})
213
+ // SingleSelectWithError.args = {
214
+ // multiple:false,
215
+ // }
216
+
217
+ // export const MultipleSelectWithError = RejectedTemplate.bind({})
218
+ // MultipleSelectWithError.args = {
219
+ // multiple:true,
220
+ // }