@salesforcedevs/dx-components 0.56.2 → 0.57.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "0.56.2",
3
+ "version": "0.57.0",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -25,5 +25,5 @@
25
25
  "@types/lodash.get": "^4.4.6",
26
26
  "@types/vimeo__player": "^2.16.2"
27
27
  },
28
- "gitHead": "47b838f7aa4fb0c55349f98074753103b693851f"
28
+ "gitHead": "ec519d645639c13fab52eb62663930901f66b2fe"
29
29
  }
@@ -19,18 +19,21 @@
19
19
  role={role}
20
20
  slot="content"
21
21
  >
22
- <template for:each={options} for:item="option">
22
+ <template for:each={options} for:item="option" for:index="index">
23
23
  <dx-dropdown-option
24
24
  suppress-gtm-nav-headings={suppressGtmNavHeadings}
25
25
  analytics-event={analyticsEvent}
26
+ analytics-base-payload={analyticsBasePayload}
26
27
  active={option.active}
27
28
  key-value={option.keyValue}
28
29
  if:false={option.options}
29
30
  key={option.id}
31
+ index-position={index}
30
32
  onfocus={onOptionFocus}
31
33
  onselect={onOptionClick}
32
34
  option={option}
33
35
  nav-item-label={navItemLabel}
36
+ variant={variant}
34
37
  ></dx-dropdown-option>
35
38
  <div
36
39
  key={option.id}
@@ -43,6 +46,7 @@
43
46
  <dx-dropdown-option
44
47
  suppress-gtm-nav-headings={suppressGTMNavHeadings}
45
48
  analytics-event={analyticsEvent}
49
+ analytics-base-payload={analyticsBasePayload}
46
50
  active={suboption.active}
47
51
  key={suboption.id}
48
52
  key-value={suboption.keyValue}
@@ -1,4 +1,9 @@
1
- import { OptionWithNested, PopperPlacement } from "typings/custom";
1
+ import {
2
+ AnalyticsPayload,
3
+ OptionWithNested,
4
+ PopperPlacement,
5
+ DropdownVariant
6
+ } from "typings/custom";
2
7
  import { LightningElement, api, track } from "lwc";
3
8
  import cx from "classnames";
4
9
  import get from "lodash.get";
@@ -18,8 +23,6 @@ export default class Dropdown extends LightningElement {
18
23
  @api value: string | null = null; // "active option" id
19
24
  @api valuePath: string = "id"; // path to match for the active value (useful for url matching)
20
25
  @api stayOpenAfterChange?: boolean = false;
21
- @api suppressGtmNavHeadings?: boolean = false;
22
-
23
26
  // props forwarded to popover:
24
27
  @api ariaLabel: string | null = null;
25
28
  @api tempId: string | null = null;
@@ -32,9 +35,16 @@ export default class Dropdown extends LightningElement {
32
35
  @api width?: string | null = null;
33
36
  @api fullWidth?: boolean | null;
34
37
  @api navItemLabel: string | null = null;
38
+ @api variant: DropdownVariant = "base";
35
39
 
36
40
  // props forwarded to dropdown option
37
41
  @api analyticsEvent: string | null = null;
42
+ @api analyticsBasePayload: AnalyticsPayload = {
43
+ elementType: "dropdown",
44
+ destinationType: "internal",
45
+ ctaClick: true
46
+ };
47
+ @api suppressGtmNavHeadings?: boolean = false;
38
48
 
39
49
  @api
40
50
  get options() {
@@ -1,5 +1,26 @@
1
1
  @import "dxHelpers/reset";
2
2
 
3
+ .indented-shape {
4
+ --background: rgb(170, 203, 255);
5
+ --wide: 2px;
6
+
7
+ background-color: var(--background);
8
+ height: var(--wide);
9
+ margin-bottom: var(--dx-g-spacing-xs);
10
+ margin-right: var(--dx-g-spacing-sm);
11
+ position: relative;
12
+ width: var(--shape-width);
13
+ }
14
+
15
+ .indented-shape::after {
16
+ background-color: var(--background);
17
+ bottom: 0;
18
+ content: "";
19
+ height: 15px;
20
+ position: absolute;
21
+ width: var(--wide);
22
+ }
23
+
3
24
  .option {
4
25
  display: flex;
5
26
  font-family: var(--dx-g-font-sans);
@@ -37,14 +58,27 @@
37
58
  text-align: left;
38
59
  }
39
60
 
61
+ .option-indented .option_details {
62
+ align-items: center;
63
+ flex-direction: row;
64
+ }
65
+
40
66
  .option_label {
41
- color: var(--dx-g-blue-vibrant-50);
67
+ color: var(--dx-c-dropdown-option-label-color, var(--dx-g-blue-vibrant-50));
42
68
  display: flex;
43
69
  align-items: center;
44
70
  font-weight: var(--dx-g-font-bold);
45
71
  font-size: var(--dx-c-dropdown-option-font-size, var(--dx-g-text-base));
46
72
  }
47
73
 
74
+ .option-indented .option_label {
75
+ display: -webkit-box;
76
+ max-width: 300px;
77
+ overflow: hidden;
78
+ -webkit-line-clamp: 1;
79
+ -webkit-box-orient: vertical;
80
+ }
81
+
48
82
  .option_label > *:last-child {
49
83
  margin-left: var(--dx-g-spacing-sm);
50
84
  }
@@ -59,3 +93,87 @@
59
93
  margin-right: var(--dx-g-spacing-md);
60
94
  flex-shrink: 0;
61
95
  }
96
+
97
+ .option-indented {
98
+ padding-top: var(--dx-g-spacing-xs);
99
+ padding-bottom: var(--dx-g-spacing-xs);
100
+ }
101
+
102
+ .option-indented:not([data-index="0"]) {
103
+ --base-indentation: calc(var(--dx-g-spacing-md) + var(--shape-width));
104
+ --shape-width: 8px;
105
+
106
+ padding-left: calc(var(--indentation, 0px) + var(--dx-g-spacing-md));
107
+ }
108
+
109
+ [data-index="2"] {
110
+ --indentation: var(--base-indentation);
111
+ }
112
+
113
+ [data-index="3"] {
114
+ --indentation: calc(2 * var(--base-indentation));
115
+ }
116
+
117
+ [data-index="4"] {
118
+ --indentation: calc(3 * var(--base-indentation));
119
+ }
120
+
121
+ [data-index="5"] {
122
+ --indentation: calc(4 * var(--base-indentation));
123
+ }
124
+
125
+ [data-index="6"] {
126
+ --indentation: calc(5 * var(--base-indentation));
127
+ }
128
+
129
+ [data-index="7"] {
130
+ --indentation: calc(6 * var(--base-indentation));
131
+ }
132
+
133
+ [data-index="8"] {
134
+ --indentation: calc(7 * var(--base-indentation));
135
+ }
136
+
137
+ [data-index="9"] {
138
+ --indentation: calc(8 * var(--base-indentation));
139
+ }
140
+
141
+ [data-index="10"] {
142
+ --indentation: calc(9 * var(--base-indentation));
143
+ }
144
+
145
+ [data-index="11"] {
146
+ --indentation: calc(10 * var(--base-indentation));
147
+ }
148
+
149
+ [data-index="12"] {
150
+ --indentation: calc(11 * var(--base-indentation));
151
+ }
152
+
153
+ [data-index="13"] {
154
+ --indentation: calc(12 * var(--base-indentation));
155
+ }
156
+
157
+ [data-index="14"] {
158
+ --indentation: calc(13 * var(--base-indentation));
159
+ }
160
+
161
+ [data-index="15"] {
162
+ --indentation: calc(14 * var(--base-indentation));
163
+ }
164
+
165
+ [data-index="16"] {
166
+ --indentation: calc(15 * var(--base-indentation));
167
+ }
168
+
169
+ [data-index="17"] {
170
+ --indentation: calc(16 * var(--base-indentation));
171
+ }
172
+
173
+ [data-index="18"] {
174
+ --indentation: calc(17 * var(--base-indentation));
175
+ }
176
+
177
+ [data-index="19"] {
178
+ --indentation: calc(18 * var(--base-indentation));
179
+ }
@@ -7,6 +7,7 @@
7
7
  key={option.id}
8
8
  role="menuitem"
9
9
  tabindex="-1"
10
+ data-index={indexPosition}
10
11
  onclick={onClick}
11
12
  >
12
13
  <dx-icon
@@ -17,6 +18,7 @@
17
18
  size="large"
18
19
  ></dx-icon>
19
20
  <div class="option_details">
21
+ <div if:true={renderIndentedShape} class="indented-shape"></div>
20
22
  <div class="option_label">
21
23
  {option.label}
22
24
  <dx-icon
@@ -34,6 +36,7 @@
34
36
  class={className}
35
37
  role="menuitem"
36
38
  tabindex="-1"
39
+ data-index={indexPosition}
37
40
  onclick={onClick}
38
41
  >
39
42
  <dx-icon
@@ -44,6 +47,7 @@
44
47
  size="large"
45
48
  ></dx-icon>
46
49
  <div class="option_details">
50
+ <div if:true={renderIndentedShape} class="indented-shape"></div>
47
51
  <div class="option_label">{option.label}</div>
48
52
  <div if:true={option.description} class="option_description">
49
53
  {option.description}
@@ -1,6 +1,10 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { OptionWithNested } from "typings/custom";
3
+ import {
4
+ OptionWithNested,
5
+ AnalyticsPayload,
6
+ DropdownVariant
7
+ } from "typings/custom";
4
8
  import { track } from "dxUtils/analytics";
5
9
 
6
10
  export default class DropdownOption extends LightningElement {
@@ -10,6 +14,9 @@ export default class DropdownOption extends LightningElement {
10
14
  @api active: boolean = false;
11
15
  @api navItemLabel: String | null = null;
12
16
  @api analyticsEvent: string | null = null;
17
+ @api analyticsBasePayload!: AnalyticsPayload;
18
+ @api indexPosition: number = 0;
19
+ @api variant: DropdownVariant = "base";
13
20
 
14
21
  @api focus() {
15
22
  const option = this.template.querySelector(".option");
@@ -20,7 +27,15 @@ export default class DropdownOption extends LightningElement {
20
27
  }
21
28
 
22
29
  private get className(): string {
23
- return cx("option", this.active && "option-active");
30
+ return cx(
31
+ "option",
32
+ this.active && "option-active",
33
+ this.variant && `option-${this.variant}`
34
+ );
35
+ }
36
+
37
+ private get renderIndentedShape() {
38
+ return this.variant === "indented" && this.indexPosition >= 1;
24
39
  }
25
40
 
26
41
  private onClick(e: PointerEvent) {
@@ -29,13 +44,11 @@ export default class DropdownOption extends LightningElement {
29
44
  );
30
45
 
31
46
  const payload: any = {
47
+ ...this.analyticsBasePayload,
32
48
  clickText: this.keyValue || undefined,
33
- pageLocation: window.location.pathname || undefined,
34
- elementType: "dropdown",
35
- destinationType: "internal",
36
- ctaClick: true,
37
49
  itemTitle: this.option.label || undefined,
38
- clickUrl: e.target?.href || undefined
50
+ pageLocation: window.location.pathname,
51
+ clickUrl: this.option.link?.href || undefined
39
52
  };
40
53
 
41
54
  const navHeading = this.navItemLabel || this.option.label || undefined;
@@ -1,17 +1,20 @@
1
- export class QueryCoordinator {
2
- static getUrlParamValue(key: string) {
3
- return JSON.parse(
4
- new URL(window.location.href).searchParams.get(key) || "null"
5
- );
6
- }
1
+ import qs from "query-string";
2
+
3
+ export function getUrlParamValue(key: string) {
4
+ const urlParams = qs.parse(window.location.search);
7
5
 
8
- static setUrlParamValue(key: string, value: any) {
9
- const newUrl = new URL(window.location.href);
10
- if (value) {
11
- newUrl.searchParams.set(key, JSON.stringify(value));
12
- } else {
13
- newUrl.searchParams.delete(key);
14
- }
15
- window.history.replaceState(null, "", newUrl.href);
6
+ return urlParams[key] ? urlParams[key]?.split(",") : [];
7
+ }
8
+
9
+ export function setUrlParamValue(key: string, value: any) {
10
+ const newUrl = new URL(window.location.href);
11
+ if (value) {
12
+ newUrl.search = qs.stringify(
13
+ { [key]: value },
14
+ { arrayFormat: "comma" }
15
+ );
16
+ } else {
17
+ newUrl.searchParams.delete(key);
16
18
  }
19
+ window.history.replaceState(null, "", newUrl.href);
17
20
  }