@pega/custom-dx-components 0.24.8 → 0.24.10

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 (24) hide show
  1. package/package.json +1 -1
  2. package/src/constants.js +4 -0
  3. package/src/tasks/create/index.js +3 -0
  4. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/PConnProps.d.ts.mustache +46 -0
  5. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/config.json.mustache +64 -0
  6. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/demo.stories.tsx.mustache +99 -0
  7. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/index.tsx.mustache +184 -0
  8. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/mock.ts.mustache +5 -0
  9. package/src/tasks/create/templates/Constellation/Field/Icon-Button-URL/styles.ts.mustache +8 -0
  10. package/src/tasks/create-all/index.js +3 -0
  11. package/src/tasks/init/template/package.json.mustache +1 -1
  12. package/src/tasks/validator/index.js +7 -1
  13. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/PConnProps.d.ts +46 -0
  14. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/config.json +64 -0
  15. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +99 -0
  16. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/index.tsx +181 -0
  17. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/mock.ts +5 -0
  18. package/tests/assets/components/createAll/Constellation/Pega_DXIL_MyIconButtonURL/styles.ts +8 -0
  19. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/PConnProps.d.ts +46 -0
  20. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/config.json +64 -0
  21. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/demo.stories.tsx +99 -0
  22. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/index.tsx +181 -0
  23. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/mock.ts +5 -0
  24. package/tests/assets/components/createAll/Launchpad/Pega_DXIL_MyIconButtonURL/styles.ts +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/custom-dx-components",
3
- "version": "0.24.8",
3
+ "version": "0.24.10",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "scripts": {
package/src/constants.js CHANGED
@@ -139,6 +139,10 @@ export const COMPONENT_SCHEMA = {
139
139
  name: 'URL',
140
140
  value: 'Text-URL'
141
141
  },
142
+ {
143
+ name: 'Icon Button URL',
144
+ value: 'Icon-Button-URL'
145
+ },
142
146
  {
143
147
  name: 'Integer',
144
148
  value: 'Integer'
@@ -73,6 +73,9 @@ const compileMustacheTemplates = async (
73
73
  case 'Picklist-RadioButtons':
74
74
  mustacheSubType = 'Picklist';
75
75
  break;
76
+ case 'Icon-Button-URL':
77
+ mustacheSubType = 'Text-URL';
78
+ break;
76
79
  }
77
80
  }
78
81
 
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "{{COMPONENT_KEY}}",
3
+ "label": "{{COMPONENT_LABEL}}",
4
+ "description": "{{DESCRIPTION}}",
5
+ "organization": "{{ORGANIZATION}}",
6
+ "version": "{{VERSION}}",
7
+ "library": "{{LIBRARY}}",
8
+ "allowedApplications": {{{ALLOWEDAPPS}}},
9
+ "componentKey": "{{COMPONENT_KEY}}",
10
+ "type": "{{TYPE}}",
11
+ "subtype": {{{SUB_TYPE}}},
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import {{COMPONENT_CLASS_NAME}} from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof {{COMPONENT_CLASS_NAME}}> = {
10
+ title: '{{COMPONENT_CLASS_NAME}}',
11
+ component: {{COMPONENT_CLASS_NAME}},
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof {{COMPONENT_CLASS_NAME}}>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const Base{{COMPONENT_CLASS_NAME}}: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <{{COMPONENT_CLASS_NAME}} {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ Base{{COMPONENT_CLASS_NAME}}.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,184 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label,
9
+ Link
10
+ } from '@pega/cosmos-react-core';
11
+ import type { PConnFieldProps } from './PConnProps';
12
+
13
+ // IMPORTANT
14
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
15
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
16
+ // Icons need to be registered (camel case), and then used (kabab case)
17
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
18
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
19
+ import * as globe from '@pega/cosmos-react-core/lib/components/Icon/icons/globe.icon';
20
+
21
+ import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
22
+
23
+ // interface for props
24
+ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
25
+ // If any, enter additional props that only exist on TextInput here
26
+ countryCode: string;
27
+ }
28
+
29
+ // *************
30
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
31
+ // used "as is"
32
+ //
33
+ // In this example, Icon is shown on its own and inside a Button
34
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
35
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
36
+ //
37
+ // In this example, the click will get a list of states for a given country and display in a
38
+ // table below. The table dispaly will toggle with the click of the button icon.
39
+ //
40
+ // Globe icon is an icon placed in a LINK element set to use an icon (NOTE: In general
41
+ // the LINK element shows the open icon to the left of the link text, but here we are using
42
+ // another icon, so with "icon" specified in the link, the open icon doesn't show)
43
+ //
44
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
45
+ // inside the config.json and let the user pick it, if it is not already part of your
46
+ // import and registration (can't be done on the fly)
47
+ // **************
48
+
49
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
50
+ // any default values in config.pros should be set in defaultProps at bottom of this file
51
+ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
52
+ const { value, countryCode = 'USA', getPConnect, testId } = props;
53
+ const [statelist, setStatelist] = useState([]);
54
+ const [showTable, setShowTable] = useState(false);
55
+ const [validUrl, setValidUrl] = useState('');
56
+ const PConnect = getPConnect();
57
+
58
+ // IMPORTANT: need to register icons used in camel case
59
+ registerIcon(listNumber, arrowRight, globe);
60
+
61
+
62
+ // setting up columns for the work list table
63
+ const columns = [
64
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
65
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
66
+ ];
67
+
68
+ // toggle showing table and getting table data
69
+ function showHideTable() {
70
+ setShowTable(prevShowTable => !prevShowTable);
71
+ }
72
+
73
+ // check if url is valid
74
+ function validateUrl(href: string) {
75
+ return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
76
+ href
77
+ );
78
+ }
79
+
80
+ // Testing to see if value entered is valid url, if not can't use it.
81
+ // Reason for this code is that you can NOT pass to Link component
82
+ // a bad url, or it will error out.
83
+ // For example: Since the value is the property field,
84
+ // it could be entered from another component and thus as it is
85
+ // entered (typed in), it won't be valid until it is all entered.
86
+ useEffect(() => {
87
+ if (validateUrl(value)) {
88
+ setValidUrl(value);
89
+ } else {
90
+ setValidUrl('');
91
+ }
92
+ }, [value]);
93
+
94
+ // going to get data for worklist to put into a table
95
+ // data comes from calling a PCore function to get
96
+ // get data from a data page and a PConnect function
97
+ // to get getContextName
98
+ useEffect(() => {
99
+ const dataViewName = 'D_pyStateList';
100
+ const context = PConnect.getContextName();
101
+ const params = { pyCountry: countryCode };
102
+
103
+ // only retrieve table data if table is shown
104
+ if (showTable) {
105
+ PCore.getDataPageUtils()
106
+ .getDataAsync(dataViewName, context, params, null, null)
107
+ // @ts-ignore
108
+ .then((response: any) => {
109
+ // table requires an index or will get setExtraStackFrame error
110
+ setStatelist(
111
+ response.data.map((entry: any, index: number) => {
112
+ // mapping the data into the column names
113
+ // MUST have an id/index or will get a setExtraStackFrame error
114
+ // put a key in the table
115
+ return {
116
+ stateName: entry.pyLabel,
117
+ stateCode: entry.pyStateCode,
118
+ id: index
119
+ };
120
+ })
121
+ );
122
+ })
123
+ .catch((error: any) => {
124
+ console.log(error);
125
+ });
126
+ }
127
+ }, [PConnect, countryCode, showTable]);
128
+
129
+ return (
130
+ <Styled{{COMPONENT_CLASS_NAME}}Wrapper>
131
+ {{! pick new delimiters for mustache }}
132
+ {{=<% %>=}}
133
+ <div style={{ display: 'flex' }} data-testid={testId}>
134
+ <Icon
135
+ style={{ height: '1.5rem', width: '1.5rem' }}
136
+ // icon name is kabab case
137
+ name='arrow-right'
138
+ role='img'
139
+ aria-label='arrow right'
140
+ />
141
+ <Label style={{ margin: '0.1rem' }}>
142
+ {' '}
143
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
144
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
145
+ </Label>
146
+ <Button
147
+ icon
148
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
149
+ variant='link'
150
+ compact={false}
151
+ onClick={showHideTable}
152
+ >
153
+ <Icon
154
+ style={{ height: '1.5rem', width: '1.5rem' }}
155
+ // icon name is kabab case
156
+ name='list-number'
157
+ role='img'
158
+ aria-label='numbered list'
159
+ />
160
+ </Button>
161
+ <Link href={validUrl} variant='link' label={validUrl} icon>
162
+ <Icon
163
+ style={{ height: '1.5rem', width: '1.5rem' }}
164
+ // icon name is kabab case
165
+ name='globe'
166
+ role='img'
167
+ aria-label='open link'
168
+ />
169
+ </Link>
170
+ </div>
171
+ {showTable && (
172
+ <Table
173
+ title={PConnect.getLocalizedValue('State list', '', '')}
174
+ columns={columns}
175
+ data={statelist}
176
+ />
177
+ )}
178
+ <%={{ }}=%> {{! revert delimiters for mustache }}
179
+ </Styled{{COMPONENT_CLASS_NAME}}Wrapper>
180
+ );
181
+ }
182
+
183
+
184
+ export default withConfiguration({{COMPONENT_CLASS_NAME}});
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });
@@ -82,6 +82,9 @@ export const compileMustacheTemplates = async (
82
82
  case 'Picklist-RadioButtons':
83
83
  mustacheSubType = 'Picklist';
84
84
  break;
85
+ case 'Icon-Button-URL':
86
+ mustacheSubType = 'Text-URL';
87
+ break;
85
88
  }
86
89
  }
87
90
 
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "devDependencies": {
71
71
  "@pega/configs": "^0.6.0",
72
- "@pega/custom-dx-components": "0.24.8",
72
+ "@pega/custom-dx-components": "0.24.10",
73
73
  "@pega/pcore-pconnect-typedefs": "~3.0.0",
74
74
  "@storybook/addon-actions": "^7.6.7",
75
75
  "@storybook/addon-essentials": "^7.6.7",
@@ -350,7 +350,13 @@ export default async (option) => {
350
350
  }
351
351
 
352
352
  //const data = JSON.parse(fs.readFileSync(path.resolve(configFile), 'utf8'));
353
- const data = JSON.parse(configData);
353
+ let data;
354
+ try {
355
+ data = JSON.parse(configData);
356
+ }
357
+ catch (er) {
358
+ throw new Error(`Invalid schema json in config.json: ${er}`);
359
+ }
354
360
 
355
361
  const valid = validateSchema(data);
356
362
 
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "Pega_DXIL_MyIconButtonURL",
3
+ "label": "My Icon Button URL",
4
+ "description": "My Icon Button URL",
5
+ "organization": "Pega",
6
+ "version": "0.0.1",
7
+ "library": "DXIL",
8
+ "allowedApplications": [],
9
+ "componentKey": "Pega_DXIL_MyIconButtonURL",
10
+ "type": "Field",
11
+ "subtype": "Text-URL",
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import PegaDxilMyIconButtonUrl from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof PegaDxilMyIconButtonUrl> = {
10
+ title: 'PegaDxilMyIconButtonUrl',
11
+ component: PegaDxilMyIconButtonUrl,
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof PegaDxilMyIconButtonUrl>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const BasePegaDxilMyIconButtonUrl: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <PegaDxilMyIconButtonUrl {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ BasePegaDxilMyIconButtonUrl.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,181 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label,
9
+ Link
10
+ } from '@pega/cosmos-react-core';
11
+ import type { PConnFieldProps } from './PConnProps';
12
+
13
+ // IMPORTANT
14
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
15
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
16
+ // Icons need to be registered (camel case), and then used (kabab case)
17
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
18
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
19
+ import * as globe from '@pega/cosmos-react-core/lib/components/Icon/icons/globe.icon';
20
+
21
+ import StyledPegaDxilMyIconButtonUrlWrapper from './styles';
22
+
23
+ // interface for props
24
+ interface PegaDxilMyIconButtonUrlProps extends PConnFieldProps {
25
+ // If any, enter additional props that only exist on TextInput here
26
+ countryCode: string;
27
+ }
28
+
29
+ // *************
30
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
31
+ // used "as is"
32
+ //
33
+ // In this example, Icon is shown on its own and inside a Button
34
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
35
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
36
+ //
37
+ // In this example, the click will get a list of states for a given country and display in a
38
+ // table below. The table dispaly will toggle with the click of the button icon.
39
+ //
40
+ // Globe icon is an icon placed in a LINK element set to use an icon (NOTE: In general
41
+ // the LINK element shows the open icon to the left of the link text, but here we are using
42
+ // another icon, so with "icon" specified in the link, the open icon doesn't show)
43
+ //
44
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
45
+ // inside the config.json and let the user pick it, if it is not already part of your
46
+ // import and registration (can't be done on the fly)
47
+ // **************
48
+
49
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
50
+ // any default values in config.pros should be set in defaultProps at bottom of this file
51
+ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
52
+ const { value, countryCode = 'USA', getPConnect, testId } = props;
53
+ const [statelist, setStatelist] = useState([]);
54
+ const [showTable, setShowTable] = useState(false);
55
+ const [validUrl, setValidUrl] = useState('');
56
+ const PConnect = getPConnect();
57
+
58
+ // IMPORTANT: need to register icons used in camel case
59
+ registerIcon(listNumber, arrowRight, globe);
60
+
61
+
62
+ // setting up columns for the work list table
63
+ const columns = [
64
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
65
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
66
+ ];
67
+
68
+ // toggle showing table and getting table data
69
+ function showHideTable() {
70
+ setShowTable(prevShowTable => !prevShowTable);
71
+ }
72
+
73
+ // check if url is valid
74
+ function validateUrl(href: string) {
75
+ return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
76
+ href
77
+ );
78
+ }
79
+
80
+ // Testing to see if value entered is valid url, if not can't use it.
81
+ // Reason for this code is that you can NOT pass to Link component
82
+ // a bad url, or it will error out.
83
+ // For example: Since the value is the property field,
84
+ // it could be entered from another component and thus as it is
85
+ // entered (typed in), it won't be valid until it is all entered.
86
+ useEffect(() => {
87
+ if (validateUrl(value)) {
88
+ setValidUrl(value);
89
+ } else {
90
+ setValidUrl('');
91
+ }
92
+ }, [value]);
93
+
94
+ // going to get data for worklist to put into a table
95
+ // data comes from calling a PCore function to get
96
+ // get data from a data page and a PConnect function
97
+ // to get getContextName
98
+ useEffect(() => {
99
+ const dataViewName = 'D_pyStateList';
100
+ const context = PConnect.getContextName();
101
+ const params = { pyCountry: countryCode };
102
+
103
+ // only retrieve table data if table is shown
104
+ if (showTable) {
105
+ PCore.getDataPageUtils()
106
+ .getDataAsync(dataViewName, context, params, null, null)
107
+ // @ts-ignore
108
+ .then((response: any) => {
109
+ // table requires an index or will get setExtraStackFrame error
110
+ setStatelist(
111
+ response.data.map((entry: any, index: number) => {
112
+ // mapping the data into the column names
113
+ // MUST have an id/index or will get a setExtraStackFrame error
114
+ // put a key in the table
115
+ return {
116
+ stateName: entry.pyLabel,
117
+ stateCode: entry.pyStateCode,
118
+ id: index
119
+ };
120
+ })
121
+ );
122
+ })
123
+ .catch((error: any) => {
124
+ console.log(error);
125
+ });
126
+ }
127
+ }, [PConnect, countryCode, showTable]);
128
+
129
+ return (
130
+ <StyledPegaDxilMyIconButtonUrlWrapper>
131
+ <div style={{ display: 'flex' }} data-testid={testId}>
132
+ <Icon
133
+ style={{ height: '1.5rem', width: '1.5rem' }}
134
+ // icon name is kabab case
135
+ name='arrow-right'
136
+ role='img'
137
+ aria-label='arrow right'
138
+ />
139
+ <Label style={{ margin: '0.1rem' }}>
140
+ {' '}
141
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
142
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
143
+ </Label>
144
+ <Button
145
+ icon
146
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
147
+ variant='link'
148
+ compact={false}
149
+ onClick={showHideTable}
150
+ >
151
+ <Icon
152
+ style={{ height: '1.5rem', width: '1.5rem' }}
153
+ // icon name is kabab case
154
+ name='list-number'
155
+ role='img'
156
+ aria-label='numbered list'
157
+ />
158
+ </Button>
159
+ <Link href={validUrl} variant='link' label={validUrl} icon>
160
+ <Icon
161
+ style={{ height: '1.5rem', width: '1.5rem' }}
162
+ // icon name is kabab case
163
+ name='globe'
164
+ role='img'
165
+ aria-label='open link'
166
+ />
167
+ </Link>
168
+ </div>
169
+ {showTable && (
170
+ <Table
171
+ title={PConnect.getLocalizedValue('State list', '', '')}
172
+ columns={columns}
173
+ data={statelist}
174
+ />
175
+ )}
176
+ </StyledPegaDxilMyIconButtonUrlWrapper>
177
+ );
178
+ }
179
+
180
+
181
+ export default withConfiguration(PegaDxilMyIconButtonUrl);
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });
@@ -0,0 +1,46 @@
1
+ import {PConnect } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ // PConnProps.d.ts
4
+ // This gives us a place to have each component (which is most DX Components) that is
5
+ // expected to have a getPConnect extend its props (from BaseProps)
6
+ // such that every component will be expected to have a getPConnect() function
7
+ // that returns a PConnect object. (new/better way of doing .propTypes).
8
+ // This PConnProps can be extended to include other props that we know are in every component
9
+ export interface PConnProps {
10
+ // getPConnect should exist for every C11n component. (add @ts-ignore in special cases where it isn't)
11
+ getPConnect: () => typeof PConnect;
12
+
13
+ // Allow any/all other key/value pairs in the BaseProps for now
14
+ // TODO: refine which other props are always expected for various component
15
+ // types and consider further interface "subclassing". For example, we may
16
+ // want to create a "BasePropsForm" that gives guidance on required, readonly, etc.
17
+ // and any other props that every Form component expects.
18
+ // For example, see the PConnFieldProps below.
19
+ // NOTE: if you uncomment the line below, the PConnProps type will allow
20
+ // otherwise undefined types to appear. This can be helpful for debugging
21
+ // or when adding new components whose types aren't yet known.
22
+ // [key: string]: any;
23
+ }
24
+
25
+
26
+ // PConnFieldProps extends PConnProps to bring in the common properties that are
27
+ // associated with most field components (ex: Dropdown, TextInput, etc.) in the
28
+ // components/field directory
29
+ export interface PConnFieldProps extends PConnProps {
30
+ label: string,
31
+ required: boolean,
32
+ disabled: boolean,
33
+ value: any,
34
+ validatemessage: string,
35
+ status?: string,
36
+ onChange?: any,
37
+ onBlur?: any,
38
+ readOnly: boolean,
39
+ testId: string,
40
+ helperText: string,
41
+ displayMode?: string,
42
+ hideLabel: boolean,
43
+ placeholder?: string,
44
+ fieldMetadata?: any,
45
+ additionalProps?: any
46
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "Pega_DXIL_MyIconButtonURL",
3
+ "label": "My Icon Button URL",
4
+ "description": "My Icon Button URL",
5
+ "organization": "Pega",
6
+ "version": "0.0.1",
7
+ "library": "DXIL",
8
+ "allowedApplications": [],
9
+ "componentKey": "Pega_DXIL_MyIconButtonURL",
10
+ "type": "Field",
11
+ "subtype": "Text-URL",
12
+ "icon": "images/pz-url-active.svg",
13
+ "properties": [
14
+ {
15
+ "format": "SELECT",
16
+ "name": "countryCode",
17
+ "label": "Country code",
18
+ "defaultValue": "USA",
19
+ "source": [
20
+ {
21
+ "key": "USA",
22
+ "value": "United States"
23
+ },
24
+ {
25
+ "key": "CAN",
26
+ "value": "Canada"
27
+ },
28
+ {
29
+ "key": "AUS",
30
+ "value": "Australia"
31
+ },
32
+ {
33
+ "key": "JPN",
34
+ "value": "Japan"
35
+ },
36
+ {
37
+ "key": "IND",
38
+ "value": "India"
39
+ },
40
+ {
41
+ "key": "TUR",
42
+ "value": "Turkey"
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "label": "Advanced",
48
+ "format": "GROUP",
49
+ "collapsible": true,
50
+ "properties": [
51
+ {
52
+ "name": "testId",
53
+ "label": "Test ID",
54
+ "format": "TEXT",
55
+ "ignorePattern": "[^-_\\p{N}\\p{L}]",
56
+ "includeAnnotations": false
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "defaultConfig": {
62
+ "label": "@L $this.label"
63
+ }
64
+ }
@@ -0,0 +1,99 @@
1
+
2
+ /* eslint-disable react/jsx-no-useless-fragment */
3
+ // @ts-nocheck
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import PegaDxilMyIconButtonUrl from './index';
7
+ import { stateProps, configProps } from './mock';
8
+
9
+ const meta: Meta<typeof PegaDxilMyIconButtonUrl> = {
10
+ title: 'PegaDxilMyIconButtonUrl',
11
+ component: PegaDxilMyIconButtonUrl,
12
+ excludeStories: /.*Data$/
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof PegaDxilMyIconButtonUrl>;
17
+
18
+ if (!window.PCore) {
19
+ window.PCore = {};
20
+ }
21
+
22
+ const statelistData = {
23
+ data: [
24
+ {
25
+ pyLabel: 'Massachusetts',
26
+ pyStateCode: 'MA'
27
+ },
28
+ {
29
+ pyLabel: 'Rhode Island',
30
+ pyStateCode: 'RI'
31
+ },
32
+ {
33
+ pyLabel: 'Connecticut',
34
+ pyStateCode: 'CT'
35
+ }
36
+ ]
37
+ };
38
+
39
+ window.PCore.getDataPageUtils = () => {
40
+ return {
41
+ getDataAsync: () => {
42
+ return new Promise(resolve => {
43
+ resolve(statelistData);
44
+ });
45
+ }
46
+ };
47
+ };
48
+
49
+ export const BasePegaDxilMyIconButtonUrl: Story = args => {
50
+
51
+ const props = {
52
+ countryCode: configProps.countryCode,
53
+ getPConnect: () => {
54
+ return {
55
+ getValue: value => {
56
+ return value;
57
+ },
58
+ getContextName: () => {
59
+ return 'app/primary_1';
60
+ },
61
+ getLocalizedValue: value => {
62
+ return value;
63
+ },
64
+ getActionsApi: () => {
65
+ return {
66
+ updateFieldValue: () => {
67
+ /* nothing */
68
+ },
69
+ triggerFieldChange: () => {
70
+ /* nothing */
71
+ }
72
+ };
73
+ },
74
+ ignoreSuggestion: () => {
75
+ /* nothing */
76
+ },
77
+ acceptSuggestion: () => {
78
+ /* nothing */
79
+ },
80
+ setInheritedProps: () => {
81
+ /* nothing */
82
+ },
83
+ resolveConfigProps: () => {
84
+ /* nothing */
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ return (
91
+ <>
92
+ <PegaDxilMyIconButtonUrl {...props} {...args} />
93
+ </>
94
+ );
95
+ };
96
+
97
+ BasePegaDxilMyIconButtonUrl.args = {
98
+ countryCode: configProps.countryCode
99
+ };
@@ -0,0 +1,181 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Icon,
4
+ Button,
5
+ withConfiguration,
6
+ registerIcon,
7
+ Table,
8
+ Label,
9
+ Link
10
+ } from '@pega/cosmos-react-core';
11
+ import type { PConnFieldProps } from './PConnProps';
12
+
13
+ // IMPORTANT
14
+ // To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
15
+ // Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
16
+ // Icons need to be registered (camel case), and then used (kabab case)
17
+ import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
18
+ import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
19
+ import * as globe from '@pega/cosmos-react-core/lib/components/Icon/icons/globe.icon';
20
+
21
+ import StyledPegaDxilMyIconButtonUrlWrapper from './styles';
22
+
23
+ // interface for props
24
+ interface PegaDxilMyIconButtonUrlProps extends PConnFieldProps {
25
+ // If any, enter additional props that only exist on TextInput here
26
+ countryCode: string;
27
+ }
28
+
29
+ // *************
30
+ // This component is meant to be an example of usage (Icon, Button, etc.) and NOT meant to be
31
+ // used "as is"
32
+ //
33
+ // In this example, Icon is shown on its own and inside a Button
34
+ // Though an Icon can have an "onClick" event is it recommended if you want to click on it,
35
+ // to put it in a Button (shown below), so you can have a tooltip and hover style
36
+ //
37
+ // In this example, the click will get a list of states for a given country and display in a
38
+ // table below. The table dispaly will toggle with the click of the button icon.
39
+ //
40
+ // Globe icon is an icon placed in a LINK element set to use an icon (NOTE: In general
41
+ // the LINK element shows the open icon to the left of the link text, but here we are using
42
+ // another icon, so with "icon" specified in the link, the open icon doesn't show)
43
+ //
44
+ // NOTE: because icons have to be imported and registered, you can NOT put the icon name
45
+ // inside the config.json and let the user pick it, if it is not already part of your
46
+ // import and registration (can't be done on the fly)
47
+ // **************
48
+
49
+ // props passed in combination of props from property panel (config.json) and run time props from Constellation
50
+ // any default values in config.pros should be set in defaultProps at bottom of this file
51
+ function PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
52
+ const { value, countryCode = 'USA', getPConnect, testId } = props;
53
+ const [statelist, setStatelist] = useState([]);
54
+ const [showTable, setShowTable] = useState(false);
55
+ const [validUrl, setValidUrl] = useState('');
56
+ const PConnect = getPConnect();
57
+
58
+ // IMPORTANT: need to register icons used in camel case
59
+ registerIcon(listNumber, arrowRight, globe);
60
+
61
+
62
+ // setting up columns for the work list table
63
+ const columns = [
64
+ { renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
65
+ { renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
66
+ ];
67
+
68
+ // toggle showing table and getting table data
69
+ function showHideTable() {
70
+ setShowTable(prevShowTable => !prevShowTable);
71
+ }
72
+
73
+ // check if url is valid
74
+ function validateUrl(href: string) {
75
+ return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
76
+ href
77
+ );
78
+ }
79
+
80
+ // Testing to see if value entered is valid url, if not can't use it.
81
+ // Reason for this code is that you can NOT pass to Link component
82
+ // a bad url, or it will error out.
83
+ // For example: Since the value is the property field,
84
+ // it could be entered from another component and thus as it is
85
+ // entered (typed in), it won't be valid until it is all entered.
86
+ useEffect(() => {
87
+ if (validateUrl(value)) {
88
+ setValidUrl(value);
89
+ } else {
90
+ setValidUrl('');
91
+ }
92
+ }, [value]);
93
+
94
+ // going to get data for worklist to put into a table
95
+ // data comes from calling a PCore function to get
96
+ // get data from a data page and a PConnect function
97
+ // to get getContextName
98
+ useEffect(() => {
99
+ const dataViewName = 'D_pyStateList';
100
+ const context = PConnect.getContextName();
101
+ const params = { pyCountry: countryCode };
102
+
103
+ // only retrieve table data if table is shown
104
+ if (showTable) {
105
+ PCore.getDataPageUtils()
106
+ .getDataAsync(dataViewName, context, params, null, null)
107
+ // @ts-ignore
108
+ .then((response: any) => {
109
+ // table requires an index or will get setExtraStackFrame error
110
+ setStatelist(
111
+ response.data.map((entry: any, index: number) => {
112
+ // mapping the data into the column names
113
+ // MUST have an id/index or will get a setExtraStackFrame error
114
+ // put a key in the table
115
+ return {
116
+ stateName: entry.pyLabel,
117
+ stateCode: entry.pyStateCode,
118
+ id: index
119
+ };
120
+ })
121
+ );
122
+ })
123
+ .catch((error: any) => {
124
+ console.log(error);
125
+ });
126
+ }
127
+ }, [PConnect, countryCode, showTable]);
128
+
129
+ return (
130
+ <StyledPegaDxilMyIconButtonUrlWrapper>
131
+ <div style={{ display: 'flex' }} data-testid={testId}>
132
+ <Icon
133
+ style={{ height: '1.5rem', width: '1.5rem' }}
134
+ // icon name is kabab case
135
+ name='arrow-right'
136
+ role='img'
137
+ aria-label='arrow right'
138
+ />
139
+ <Label style={{ margin: '0.1rem' }}>
140
+ {' '}
141
+ {PConnect.getLocalizedValue('State list for', '', '')}{' '}
142
+ {PConnect.getLocalizedValue(`${countryCode}`, '', '')}{' '}
143
+ </Label>
144
+ <Button
145
+ icon
146
+ label={PConnect.getLocalizedValue('Click to show/hide state list', '', '')}
147
+ variant='link'
148
+ compact={false}
149
+ onClick={showHideTable}
150
+ >
151
+ <Icon
152
+ style={{ height: '1.5rem', width: '1.5rem' }}
153
+ // icon name is kabab case
154
+ name='list-number'
155
+ role='img'
156
+ aria-label='numbered list'
157
+ />
158
+ </Button>
159
+ <Link href={validUrl} variant='link' label={validUrl} icon>
160
+ <Icon
161
+ style={{ height: '1.5rem', width: '1.5rem' }}
162
+ // icon name is kabab case
163
+ name='globe'
164
+ role='img'
165
+ aria-label='open link'
166
+ />
167
+ </Link>
168
+ </div>
169
+ {showTable && (
170
+ <Table
171
+ title={PConnect.getLocalizedValue('State list', '', '')}
172
+ columns={columns}
173
+ data={statelist}
174
+ />
175
+ )}
176
+ </StyledPegaDxilMyIconButtonUrlWrapper>
177
+ );
178
+ }
179
+
180
+
181
+ export default withConfiguration(PegaDxilMyIconButtonUrl);
@@ -0,0 +1,5 @@
1
+
2
+ // @ts-nocheck
3
+ export const configProps = {
4
+ countryCode: 'USA'
5
+ };
@@ -0,0 +1,8 @@
1
+ // individual style, comment out above, and uncomment here and add styles
2
+ import styled, { css } from 'styled-components';
3
+
4
+ export default styled.div(() => {
5
+ return css`
6
+ margin: 0px 0;
7
+ `;
8
+ });