@salesforcedevs/dx-components 0.54.5 → 0.55.2

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.54.5",
3
+ "version": "0.55.2",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -16,7 +16,6 @@
16
16
  "@vimeo/player": "^2.16.4",
17
17
  "classnames": "^2.2.6",
18
18
  "debounce": "^1.2.0",
19
- "lightning-base-components": "1.12.3-alpha",
20
19
  "lodash.get": "^4.4.2",
21
20
  "microtip": "0.2.2"
22
21
  },
@@ -1,6 +1,6 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { Breadcrumb, Option } from "typings/custom";
3
+ import { Breadcrumb, OptionWithNested } from "typings/custom";
4
4
  import { toJson } from "dxUtils/normalizers";
5
5
 
6
6
  type LabelMap = { [href: string]: string };
@@ -19,7 +19,7 @@ const toLabel = (val: string) => {
19
19
  export default class Breadcrumbs extends LightningElement {
20
20
  @api ariaLabel: string = "Navigation Breadcrumbs";
21
21
  @api baseHref: string = "/";
22
- @api navItems: Option[] = [];
22
+ @api navItems: OptionWithNested[] = [];
23
23
  @api pathname: string = window.location.pathname;
24
24
  @api title: string = "Salesforce";
25
25
  @api logo: boolean = false;
@@ -42,19 +42,22 @@ export default class Breadcrumbs extends LightningElement {
42
42
  private _breadcrumbs!: Breadcrumb[];
43
43
 
44
44
  private get labelMap(): LabelMap {
45
- const deepReducer = (options: Option[]) =>
46
- options.reduce((acc: LabelMap, item: Option): LabelMap => {
47
- if (item.options) {
48
- return { ...acc, ...deepReducer(item.options) };
49
- }
50
- if (!item.link) {
51
- return acc;
52
- }
53
- return {
54
- ...acc,
55
- [item.link.href]: item.label
56
- };
57
- }, {});
45
+ const deepReducer = (options: OptionWithNested[]) =>
46
+ options.reduce(
47
+ (acc: LabelMap, item: OptionWithNested): LabelMap => {
48
+ if (item.options) {
49
+ return { ...acc, ...deepReducer(item.options) };
50
+ }
51
+ if (!item.link) {
52
+ return acc;
53
+ }
54
+ return {
55
+ ...acc,
56
+ [item.link.href]: item.label
57
+ };
58
+ },
59
+ {}
60
+ );
58
61
  return this.navItems ? deepReducer(this.navItems) : {};
59
62
  }
60
63
 
@@ -108,6 +108,15 @@
108
108
  width: var(--dx-c-slot-empty-width, var(--dx-g-spacing-xl));
109
109
  }
110
110
 
111
+ .button.size-hero {
112
+ font-size: var(--dx-g-text-lg);
113
+ height: 52px;
114
+ }
115
+
116
+ .button.size-hero.style-icon.slot-empty {
117
+ width: var(--dx-c-slot-empty-width, 52px);
118
+ }
119
+
111
120
  /* primary */
112
121
 
113
122
  .button.variant_primary {
@@ -17,7 +17,7 @@ export default class Button extends LightningElement {
17
17
  @api iconSymbol?: IconSymbol;
18
18
  @api iconPosition?: "right" | "left" = "right";
19
19
  @api loading: boolean = false;
20
- @api size: "large" | "small" = "small";
20
+ @api size: "large" | "hero" | "small" = "small";
21
21
  @api variant: ButtonVariant = "primary";
22
22
  @api inlineTextColor: ButtonTextColor = "dark";
23
23
  @api font: "display" | "sans" = "display";
@@ -1,11 +1,11 @@
1
- import { Option, PopperPlacement } from "typings/custom";
1
+ import { OptionWithNested, PopperPlacement } from "typings/custom";
2
2
  import { LightningElement, api, track } from "lwc";
3
3
  import cx from "classnames";
4
4
  import get from "lodash.get";
5
5
  import { deepmapOptions } from "dxUtils/options";
6
6
  import { toJson } from "dxUtils/normalizers";
7
7
 
8
- interface DropdownOption extends Option {
8
+ interface DropdownOption extends OptionWithNested {
9
9
  // link that gets shown as a highlighted link at end of option group
10
10
  calloutLink?: {
11
11
  href: string;
@@ -1,10 +1,10 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { Option } from "typings/custom";
3
+ import { OptionWithNested } from "typings/custom";
4
4
  import { track } from "dxUtils/analytics";
5
5
 
6
6
  export default class DropdownOption extends LightningElement {
7
- @api option!: Option;
7
+ @api option!: OptionWithNested;
8
8
  @api suppressGtmNavHeadings: boolean = false;
9
9
  @api keyValue!: string;
10
10
  @api active: boolean = false;
@@ -1,7 +1,7 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
+ import { FooterVariant, OptionWithLink } from "typings/custom";
3
4
  import { toJson } from "dxUtils/normalizers";
4
- import { FooterVariant, Option } from "typings/custom";
5
5
  import {
6
6
  generalLinks,
7
7
  termsLinks,
@@ -31,7 +31,7 @@ export default class Footer extends LightningElement {
31
31
  this._locales = toJson(value);
32
32
  }
33
33
 
34
- private _locales?: Option[] | null = null;
34
+ private _locales?: OptionWithLink[] | null = null;
35
35
  private termsLinks = termsLinks;
36
36
  private generalLinks = generalLinks;
37
37
  private socialLinks = socialLinks;
@@ -1,10 +1,10 @@
1
1
  import { api } from "lwc";
2
+ import type { OptionWithNested } from "typings/custom";
2
3
  import { HeaderBase } from "dxBaseElements/headerBase";
3
4
  import { toJson } from "dxUtils/normalizers";
4
- import type { Option } from "typings/custom";
5
5
 
6
6
  export default class Header extends HeaderBase {
7
- private _breadcrumbs!: Option[];
7
+ private _breadcrumbs!: OptionWithNested[];
8
8
 
9
9
  @api
10
10
  get breadcrumbs() {
@@ -1,6 +1,6 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { Option } from "typings/custom";
3
+ import { OptionWithNested } from "typings/custom";
4
4
  import { deepmapOptions } from "dxUtils/options";
5
5
 
6
6
  export default class HeaderMobileNavMenu extends LightningElement {
@@ -9,7 +9,7 @@ export default class HeaderMobileNavMenu extends LightningElement {
9
9
  @api pathname: string | null = null;
10
10
 
11
11
  @api
12
- set navItems(_navItems: Option[]) {
12
+ set navItems(_navItems: OptionWithNested[]) {
13
13
  this._navItems = _navItems;
14
14
  }
15
15
  get navItems() {
@@ -24,7 +24,7 @@ export default class HeaderMobileNavMenu extends LightningElement {
24
24
  // then we use deepmapper to affect the actual root options (actual links)
25
25
  return deepmapOptions(
26
26
  navItems,
27
- (app: Option, index: number, level: number) => {
27
+ (app: OptionWithNested, index: number, level: number) => {
28
28
  const active = app.link
29
29
  ? app.link.href === this.pathname
30
30
  : false;
@@ -47,7 +47,7 @@ export default class HeaderMobileNavMenu extends LightningElement {
47
47
  );
48
48
  }
49
49
 
50
- private _navItems: Option[] = [];
50
+ private _navItems: OptionWithNested[] = [];
51
51
  private navElement: HTMLElement | null = null;
52
52
  private wasOpen: boolean = false;
53
53
  private showScrollShadow: boolean = false;
@@ -1,18 +1,18 @@
1
1
  import { LightningElement, api } from "lwc";
2
- import { TabVariant, Option } from "typings/custom";
2
+ import { TabVariant, OptionWithNested } from "typings/custom";
3
3
  export default class HeaderNav extends LightningElement {
4
4
  @api pathname: string | null = null;
5
5
  @api variant: TabVariant = "default";
6
6
  @api ariaLabel: string = "Primary Navigation";
7
7
 
8
8
  @api
9
- set navItems(_navItems: Option[]) {
9
+ set navItems(_navItems: OptionWithNested[]) {
10
10
  this._navItems = _navItems;
11
11
  }
12
12
 
13
13
  get navItems() {
14
14
  const activeItem = this._navItems
15
- .filter((navItem: Option) => {
15
+ .filter((navItem: OptionWithNested) => {
16
16
  if (!navItem.link || navItem.link.href === "/") {
17
17
  return false;
18
18
  }
@@ -31,7 +31,7 @@ export default class HeaderNav extends LightningElement {
31
31
  (b.link?.href.length || 0) - (a.link?.href.length || 0)
32
32
  )[0];
33
33
 
34
- const items = this._navItems.map((navItem: Option) =>
34
+ const items = this._navItems.map((navItem: OptionWithNested) =>
35
35
  navItem.link
36
36
  ? {
37
37
  ...navItem,
@@ -45,7 +45,7 @@ export default class HeaderNav extends LightningElement {
45
45
  return items;
46
46
  }
47
47
 
48
- private _navItems: Option[] = [];
48
+ private _navItems: OptionWithNested[] = [];
49
49
 
50
50
  private requestOpenNavMenu(e: PointerEvent) {
51
51
  const detail = (<HTMLButtonElement>e.currentTarget).getAttribute(
@@ -1,6 +1,6 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { PopoverRequestCloseType, Option } from "typings/custom";
3
+ import { PopoverRequestCloseType, OptionWithLink } from "typings/custom";
4
4
  import { buildSearchEngine } from "dxUtils/coveo";
5
5
  import {
6
6
  StandaloneSearchBox as StandaloneSearchBoxType,
@@ -28,7 +28,7 @@ export default class HeaderSearch extends LightningElement {
28
28
  return this.mobile ? null : "desktop_search-container";
29
29
  }
30
30
 
31
- private get suggestions(): Option[] {
31
+ private get suggestions(): OptionWithLink[] {
32
32
  if (this.searchState) {
33
33
  return this.searchState.suggestions.map(
34
34
  ({ highlightedValue }: { highlightedValue: string }) => ({
@@ -1,5 +1,3 @@
1
- @import "dxHelpers/slds";
2
-
3
1
  :host {
4
2
  display: block;
5
3
  }
@@ -8,7 +6,7 @@
8
6
  outline: none;
9
7
  }
10
8
 
11
- .slds-select_container::before {
9
+ .select_container::before {
12
10
  --icon-size: 0.5em;
13
11
 
14
12
  border-style: solid;
@@ -24,21 +22,196 @@
24
22
  width: var(--icon-size);
25
23
  }
26
24
 
27
- .placeholder {
25
+ .select-element_placeholder {
28
26
  color: var(--sds-g-gray-9);
29
27
  }
30
28
 
31
- select.slds-select:focus:not([disabled]),
32
- select.slds-select:active:not([disabled]) {
29
+ select.select-element:focus:not([disabled]),
30
+ select.select-element:active:not([disabled]) {
33
31
  border-width: 2px;
34
32
  border-color: var(--dx-g-blue-vibrant-50);
35
33
  box-shadow: none;
36
34
  -webkit-box-shadow: none;
37
35
  }
38
36
 
39
- :host(.slds-has-error) select.slds-select:focus,
40
- :host(.slds-has-error) select.slds-select:active {
37
+ .has-error select.select-element:focus,
38
+ .has-error select.select-element:active {
41
39
  border-color: #ea001e;
42
40
  box-shadow: 0 0 3px var(--dx-g-blue-vibrant-50);
43
41
  -webkit-box-shadow: 0 0 3px var(--dx-g-blue-vibrant-50);
44
42
  }
43
+
44
+ @media (min-width: 48em) {
45
+ .form-element_horizontal .form-element_control {
46
+ padding-left: 33%;
47
+ clear: none;
48
+ }
49
+ }
50
+
51
+ abbr[title] {
52
+ border-bottom: 1px dotted;
53
+ text-decoration: none;
54
+ cursor: help;
55
+ }
56
+
57
+ abbr[title]::after {
58
+ content: " (" attr(title) ")";
59
+ }
60
+
61
+ abbr[title],
62
+ fieldset,
63
+ hr {
64
+ border: 0;
65
+ }
66
+
67
+ button,
68
+ select {
69
+ text-transform: none;
70
+ }
71
+
72
+ .form-element_control {
73
+ clear: left;
74
+ position: relative;
75
+ }
76
+
77
+ .form-element_label {
78
+ overflow-wrap: break-word;
79
+ word-wrap: break-word;
80
+ -webkit-hyphens: auto;
81
+ -ms-hyphens: auto;
82
+ hyphens: auto;
83
+ display: inline-block;
84
+ color: #3e3e3c;
85
+ font-size: 0.75rem;
86
+ padding-right: 0.5rem;
87
+ padding-top: 0.25rem;
88
+ margin-bottom: 0.125rem;
89
+ }
90
+
91
+ .form-element_label:empty {
92
+ margin: 0;
93
+ }
94
+
95
+ .form-element_stacked .form-element_label,
96
+ .form-element_stacked .form-element_control {
97
+ border-bottom: 0;
98
+ padding-left: 0;
99
+ }
100
+
101
+ .form-element_stacked .form-element_control {
102
+ width: 100%;
103
+ -ms-flex-preferred-size: 100%;
104
+ flex-basis: 100%;
105
+ clear: left;
106
+ }
107
+
108
+ .assistive-text {
109
+ position: absolute !important;
110
+ margin: -1px !important;
111
+ border: 0 !important;
112
+ padding: 0 !important;
113
+ width: 1px !important;
114
+ height: 1px !important;
115
+ overflow: hidden !important;
116
+ clip: rect(0 0 0 0) !important;
117
+ text-transform: none !important;
118
+ white-space: nowrap !important;
119
+ }
120
+
121
+ .required-element {
122
+ color: #ea001e;
123
+ margin: 0 0.125rem;
124
+ }
125
+
126
+ .select-element {
127
+ height: calc(1.875rem + (1px * 2));
128
+ width: 100%;
129
+ border: 1px solid #dddbda;
130
+ border-radius: 0.25rem;
131
+ background-color: white;
132
+ -webkit-transition: border 0.1s linear, background-color 0.1s linear;
133
+ transition: border 0.1s linear, background-color 0.1s linear;
134
+ }
135
+
136
+ .select-element:focus,
137
+ .select-element:active {
138
+ outline: 0;
139
+ border-color: #1b96ff;
140
+ background-color:white;
141
+ -webkit-box-shadow: 0 0 3px #0176d3;
142
+ box-shadow: 0 0 3px #0176d3;
143
+ }
144
+
145
+ .select-element[disabled],
146
+ .select-element.slds-is-disabled {
147
+ background-color: #ecebea;
148
+ border-color: #c9c7c5;
149
+ color: #3e3e3c;
150
+ cursor: not-allowed;
151
+ -webkit-user-select: none;
152
+ -moz-user-select: none;
153
+ -ms-user-select: none;
154
+ user-select: none;
155
+ opacity: 1;
156
+ }
157
+
158
+ .select-element[disabled]:focus,
159
+ .select-element[disabled]:active,
160
+ .select-element.slds-is-disabled:focus,
161
+ .select-element.slds-is-disabled:active {
162
+ -webkit-box-shadow: none;
163
+ box-shadow: none;
164
+ }
165
+
166
+ .select-element[size] {
167
+ min-height: calc(1.875rem + (1px * 2));
168
+ height: inherit;
169
+ }
170
+
171
+ .select-element[size] option {
172
+ padding: 0.5rem;
173
+ }
174
+
175
+ .has-error .select-element {
176
+ border-color: #ea001e;
177
+ -webkit-box-shadow: #ea001e 0 0 0 1px inset;
178
+ box-shadow: #ea001e 0 0 0 1px inset;
179
+ background-clip: padding-box;
180
+ }
181
+
182
+ .select_container {
183
+ position: relative;
184
+ }
185
+
186
+ .select_container .select-element {
187
+ -moz-appearance: none;
188
+ -webkit-appearance: none;
189
+ padding-left: 0.5rem;
190
+ padding-right: 1.5rem;
191
+ }
192
+
193
+ .select_container .select-element::-ms-expand {
194
+ display: none;
195
+ }
196
+
197
+ .has-error .select-element:focus,
198
+ .has-error .select-element:active {
199
+ -webkit-box-shadow: #ea001e 0 0 0 1px inset, 0 0 3px #0176d3;
200
+ box-shadow: #ea001e 0 0 0 1px inset, 0 0 3px #0176d3;
201
+ }
202
+
203
+ .form-element:not(.has-error) .select-element:required {
204
+ -webkit-box-shadow: none;
205
+ box-shadow: none;
206
+ }
207
+
208
+ .form-element_help,
209
+ .form-element_helper {
210
+ font-size: 0.75rem;
211
+ margin-top: 0.125rem;
212
+ display: block;
213
+ }
214
+
215
+ .has-error .form-element_help {
216
+ color: #ea001e;
217
+ }
@@ -1,60 +1,57 @@
1
1
  <template>
2
- <label class={computedLabelClass} for="select">
3
- {label}
4
- <template if:true={required}>
5
- <abbr>*</abbr>
6
- </template>
7
- </label>
8
-
9
- <div class="slds-form-element__control">
10
- <div class="slds-select_container">
11
- <select
12
- autocomplete={autocomplete}
13
- class={selectClass}
14
- disabled={disabled}
15
- id="select"
16
- multiple={multiple}
17
- name={name}
18
- onblur={handleBlur}
19
- onchange={handleChange}
20
- onfocus={handleFocus}
21
- required={required}
22
- accesskey={accessKey}
23
- size={size}
24
- >
25
- <template if:true={placeholder}>
26
- <option if:false={value} value="" disabled>
27
- {placeholder}
28
- </option>
29
- </template>
30
- <template for:each={options} for:item="option">
31
- <template if:true={option.disabled}>
32
- <option
33
- disabled
34
- key={option.value}
35
- value={option.value}
36
- >
37
- {option.label}
38
- </option>
2
+ <div class={containerClass}>
3
+ <label class="form-element_label" for="select">
4
+ {label}
5
+ <template if:true={required}>
6
+ <abbr>*</abbr>
7
+ </template>
8
+ </label>
9
+ <div class="form-element_control">
10
+ <div class="select_container">
11
+ <select
12
+ autocomplete={autocomplete}
13
+ class={selectClass}
14
+ disabled={disabled}
15
+ id="select"
16
+ name={name}
17
+ onblur={handleBlur}
18
+ onchange={handleChange}
19
+ onfocus={handleFocus}
20
+ required={required}
21
+ accesskey={accessKey}
22
+ size={size}
23
+ >
24
+ <template if:true={placeholder}>
25
+ <option value="" disabled>{placeholder}</option>
39
26
  </template>
40
- <template if:false={option.disabled}>
41
- <option key={option.value} value={option.value}>
42
- {option.label}
43
- </option>
27
+ <template for:each={options} for:item="option">
28
+ <template if:true={option.disabled}>
29
+ <option
30
+ disabled
31
+ key={option.value}
32
+ value={option.value}
33
+ >
34
+ {option.label}
35
+ </option>
36
+ </template>
37
+ <template if:false={option.disabled}>
38
+ <option key={option.value} value={option.value}>
39
+ {option.label}
40
+ </option>
41
+ </template>
44
42
  </template>
45
- </template>
46
- </select>
43
+ </select>
44
+ </div>
47
45
  </div>
46
+ <template if:true={helpMessage}>
47
+ <div
48
+ aria-live="assertive"
49
+ class="form-element_help"
50
+ data-help-message
51
+ id="help-message"
52
+ >
53
+ {helpMessage}
54
+ </div>
55
+ </template>
48
56
  </div>
49
-
50
- <template if:true={_helpMessage}>
51
- <div
52
- aria-live="assertive"
53
- class="slds-form-element__help"
54
- data-help-message
55
- id="help-message"
56
- >
57
- {_helpMessage}
58
- </div>
59
- </template>
60
57
  </template>
@@ -1,23 +1,141 @@
1
1
  import cx from "classnames";
2
- import { api } from "lwc";
3
- import LightningSelect from "lightning/select";
4
- import { toJson } from "dxUtils/normalizers";
2
+ import { LightningElement, api } from "lwc";
3
+ import { SelectOption } from "typings/custom";
4
+ import { toJson, normalizeBoolean } from "dxUtils/normalizers";
5
5
 
6
- export default class Select extends LightningSelect {
6
+ export const DEFAULT_MISSING_MESSAGE = "This field is required";
7
+
8
+ export default class Select extends LightningElement {
9
+ @api accessKey!: string;
10
+ @api autocomplete?: string;
11
+ @api label?: string;
12
+ @api messageWhenValueMissing: string = DEFAULT_MISSING_MESSAGE;
13
+ @api name?: string;
7
14
  @api placeholder?: string;
15
+ @api size?: string;
16
+
17
+ @api
18
+ get disabled() {
19
+ return this._disabled;
20
+ }
21
+
22
+ set disabled(value) {
23
+ this._disabled = normalizeBoolean(value);
24
+ }
25
+
26
+ @api
27
+ get options() {
28
+ return this._options;
29
+ }
30
+
31
+ set options(value) {
32
+ this._options = toJson(value);
33
+ }
8
34
 
9
35
  @api
10
- get jsonOptions() {
11
- return this.options;
36
+ get required() {
37
+ return this._required;
12
38
  }
13
39
 
14
- set jsonOptions(value) {
15
- this.options = toJson(value);
40
+ set required(value) {
41
+ this._required = normalizeBoolean(value);
42
+ }
43
+
44
+ @api
45
+ get value() {
46
+ return this._value;
47
+ }
48
+
49
+ set value(value) {
50
+ this._value = value;
51
+ this.updateSelectValue();
52
+ }
53
+
54
+ _disabled = false;
55
+ _size = "";
56
+ _required = false;
57
+ _options: Array<SelectOption> = [];
58
+ _value: string = "";
59
+ _selectElement: HTMLSelectElement | null = null;
60
+ helpMessage?: string = "";
61
+
62
+ renderedCallback(): void {
63
+ this.updateSelectValue();
64
+ }
65
+
66
+ get containerClass() {
67
+ return cx("form-element", this.hasError && "has-error");
68
+ }
69
+
70
+ get hasError(): boolean {
71
+ return !!this.helpMessage;
16
72
  }
17
73
 
18
74
  get selectClass() {
19
- return cx("slds-select", {
20
- placeholder: !this.value
75
+ return cx("select-element", {
76
+ "select-element_placeholder": this.placeholder && !this.value
21
77
  });
22
78
  }
79
+
80
+ get selectElement() {
81
+ if (!this._selectElement) {
82
+ this._selectElement =
83
+ this.template.querySelector<HTMLSelectElement>("select");
84
+ }
85
+ return this._selectElement;
86
+ }
87
+
88
+ @api
89
+ blur(): void {
90
+ if (this.selectElement) {
91
+ this.selectElement.blur();
92
+ }
93
+ }
94
+
95
+ @api
96
+ focus(): void {
97
+ if (this.selectElement) {
98
+ this.selectElement.focus();
99
+ }
100
+ }
101
+
102
+ @api
103
+ reportValidity(): boolean {
104
+ const isInvalid = this._required && !this._value;
105
+ this.helpMessage = isInvalid
106
+ ? this.messageWhenValueMissing || DEFAULT_MISSING_MESSAGE
107
+ : "";
108
+ return !isInvalid;
109
+ }
110
+
111
+ handleBlur(): void {
112
+ this.reportValidity();
113
+ this.dispatchEvent(new CustomEvent("blur"));
114
+ }
115
+
116
+ handleChange(event: Event & { target: HTMLSelectElement }): void {
117
+ const { value } = event.target;
118
+ this._value = value;
119
+ this.dispatchEvent(
120
+ new CustomEvent("change", {
121
+ detail: { value }
122
+ })
123
+ );
124
+ }
125
+
126
+ handleFocus(): void {
127
+ this.helpMessage = "";
128
+ this.dispatchEvent(new CustomEvent("focus"));
129
+ }
130
+
131
+ // We have to do it programmatically because value binding doesn't work apparently.
132
+ updateSelectValue(): void {
133
+ if (!this._value && !this.placeholder) {
134
+ return;
135
+ }
136
+
137
+ if (this.selectElement) {
138
+ this.selectElement.value = this._value;
139
+ }
140
+ }
23
141
  }
@@ -292,7 +292,7 @@ export default class SidebarSearch extends LightningElement {
292
292
  }: Result): SidebarSearchResult => {
293
293
  // discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
294
294
 
295
- let pathname;
295
+ let pathname, queryParam;
296
296
  if (sfhtml_url__c) {
297
297
  pathname = `/docs/${sfhtml_url__c}`;
298
298
  } else {
@@ -303,9 +303,15 @@ export default class SidebarSearch extends LightningElement {
303
303
  ? ".html"
304
304
  : "";
305
305
  pathname = `${url.pathname}${extension}`;
306
+ queryParam = url.search;
306
307
  }
307
308
 
308
- const href = `${pathname}?q=${this.value}`;
309
+ let href;
310
+ if (queryParam) {
311
+ href = `${pathname}${queryParam}&q=${this.value}`;
312
+ } else {
313
+ href = `${pathname}?q=${this.value}`;
314
+ }
309
315
 
310
316
  return {
311
317
  title,
@@ -1,6 +1,6 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { Brand, Option } from "typings/custom";
3
+ import { Brand, OptionWithLink, OptionWithNested } from "typings/custom";
4
4
  import { toJson } from "dxUtils/normalizers";
5
5
  import { track } from "dxUtils/analytics";
6
6
 
@@ -61,8 +61,8 @@ export abstract class HeaderBase extends LightningElement {
61
61
  this._versions = toJson(value);
62
62
  }
63
63
 
64
- private _navItems!: Option[];
65
- private _versions!: Option[];
64
+ private _navItems!: OptionWithNested[];
65
+ private _versions!: OptionWithLink[];
66
66
  private matchMedia!: MediaQueryList;
67
67
  protected mobile: boolean = false;
68
68
  private mobileNavMenuValue: string | null = null;
@@ -1,12 +1,12 @@
1
- import { Option } from "typings/custom";
1
+ import { OptionWithNested } from "typings/custom";
2
2
 
3
3
  const deepmapper = (
4
- _options: Option[],
5
- _callback: (option: Option, lavel: number) => Option,
4
+ _options: OptionWithNested[],
5
+ _callback: (option: OptionWithNested, lavel: number) => OptionWithNested,
6
6
  level: number = 0
7
- ): Option[] => {
7
+ ): OptionWithNested[] => {
8
8
  const _level = level + 1;
9
- return _options?.map((option: Option) =>
9
+ return _options?.map((option: OptionWithNested) =>
10
10
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
11
  option.options
12
12
  ? {
@@ -18,9 +18,13 @@ const deepmapper = (
18
18
  };
19
19
 
20
20
  export const deepmapOptions = (
21
- options: Option[],
22
- callback: (option: Option, index: number, level: number) => Option
23
- ): Option[] => {
21
+ options: OptionWithNested[],
22
+ callback: (
23
+ option: OptionWithNested,
24
+ index: number,
25
+ level: number
26
+ ) => OptionWithNested
27
+ ): OptionWithNested[] => {
24
28
  let index = 0;
25
29
  return deepmapper(options, (option, level) => {
26
30
  const newOption = callback(option, index, level);
@@ -29,7 +33,7 @@ export const deepmapOptions = (
29
33
  });
30
34
  };
31
35
 
32
- export const getOptionsCount = (options: Option[]) => {
36
+ export const getOptionsCount = (options: OptionWithNested[]) => {
33
37
  let count = 0;
34
38
  deepmapper(options, (option) => {
35
39
  count += 1;
@@ -1,191 +0,0 @@
1
- :host(.slds-form-element_stacked) .slds-form-element__label,
2
- :host(.slds-form-element_stacked) .slds-form-element__control {
3
- border-bottom: 0;
4
- padding-left: 0;
5
- }
6
-
7
- :host(.slds-form-element_stacked) .slds-form-element__control {
8
- width: 100%;
9
- -ms-flex-preferred-size: 100%;
10
- flex-basis: 100%;
11
- clear: left;
12
- }
13
-
14
- @media (min-width: 48em) {
15
- :host(.slds-form-element_horizontal) .slds-form-element__control {
16
- padding-left: 33%;
17
- clear: none;
18
- }
19
- }
20
-
21
- :host(.slds-has-error) .slds-select {
22
- border-color: #ea001e;
23
- -webkit-box-shadow: #ea001e 0 0 0 1px inset;
24
- box-shadow: #ea001e 0 0 0 1px inset;
25
- background-clip: padding-box;
26
- }
27
-
28
- :host(.slds-has-error) .slds-select:focus,
29
- :host(.slds-has-error) .slds-select:active {
30
- -webkit-box-shadow: #ea001e 0 0 0 1px inset, 0 0 3px #0176d3;
31
- box-shadow: #ea001e 0 0 0 1px inset, 0 0 3px #0176d3;
32
- }
33
-
34
- :host(.slds-has-error) .slds-form-element__help {
35
- color: #ea001e;
36
- }
37
-
38
- abbr[title] {
39
- border-bottom: 1px dotted;
40
- }
41
-
42
- abbr[title] {
43
- text-decoration: none;
44
- }
45
-
46
- abbr[title],
47
- fieldset,
48
- hr {
49
- border: 0;
50
- }
51
-
52
- abbr[title] {
53
- cursor: help;
54
- }
55
-
56
- abbr[title]:after {
57
- content: " (" attr(title) ")";
58
- }
59
-
60
- button,
61
- select {
62
- text-transform: none;
63
- }
64
-
65
- .slds-form-element__label {
66
- overflow-wrap: break-word;
67
- word-wrap: break-word;
68
- -webkit-hyphens: auto;
69
- -ms-hyphens: auto;
70
- hyphens: auto;
71
- display: inline-block;
72
- color: #3e3e3c;
73
- font-size: 0.75rem;
74
- padding-right: 0.5rem;
75
- padding-top: 0.25rem;
76
- margin-bottom: 0.125rem;
77
- }
78
-
79
- .slds-form-element__label:empty {
80
- margin: 0;
81
- }
82
-
83
- .slds-assistive-text {
84
- position: absolute !important;
85
- margin: -1px !important;
86
- border: 0 !important;
87
- padding: 0 !important;
88
- width: 1px !important;
89
- height: 1px !important;
90
- overflow: hidden !important;
91
- clip: rect(0 0 0 0) !important;
92
- text-transform: none !important;
93
- white-space: nowrap !important;
94
- }
95
-
96
- .slds-required {
97
- color: #ea001e;
98
- margin: 0 0.125rem;
99
- }
100
-
101
- .slds-form-element__control {
102
- clear: left;
103
- position: relative;
104
- }
105
-
106
- .slds-select {
107
- height: calc(1.875rem + (1px * 2));
108
- width: 100%;
109
- border: 1px solid var(--sds-c-select-color-border, #dddbda);
110
- border-radius: var(--sds-c-select-radius-border, 0.25rem);
111
- background-color: var(--sds-c-select-color-background, white);
112
- color: var(--sds-c-select-text-color);
113
- -webkit-box-shadow: var(--sds-c-select-shadow);
114
- box-shadow: var(--sds-c-select-shadow);
115
- -webkit-transition: border 0.1s linear, background-color 0.1s linear;
116
- transition: border 0.1s linear, background-color 0.1s linear;
117
- }
118
-
119
- .slds-select:required {
120
- -webkit-box-shadow: none;
121
- box-shadow: none;
122
- }
123
-
124
- .slds-select:focus,
125
- .slds-select:active {
126
- outline: 0;
127
- border-color: var(--sds-c-select-color-border-focus, #1b96ff);
128
- background-color: var(--sds-c-select-color-background-focus, white);
129
- color: var(--sds-c-select-text-color-focus);
130
- -webkit-box-shadow: var(--sds-c-select-shadow-focus, 0 0 3px #0176d3);
131
- box-shadow: var(--sds-c-select-shadow-focus, 0 0 3px #0176d3);
132
- }
133
-
134
- .slds-select[disabled],
135
- .slds-select.slds-is-disabled {
136
- background-color: #ecebea;
137
- border-color: #c9c7c5;
138
- color: #3e3e3c;
139
- cursor: not-allowed;
140
- -webkit-user-select: none;
141
- -moz-user-select: none;
142
- -ms-user-select: none;
143
- user-select: none;
144
- opacity: 1;
145
- }
146
-
147
- .slds-select[disabled]:focus,
148
- .slds-select[disabled]:active,
149
- .slds-select.slds-is-disabled:focus,
150
- .slds-select.slds-is-disabled:active {
151
- -webkit-box-shadow: none;
152
- box-shadow: none;
153
- }
154
-
155
- .slds-select[size],
156
- .slds-select[multiple] {
157
- min-height: calc(1.875rem + (1px * 2));
158
- height: inherit;
159
- }
160
-
161
- .slds-select[size] option,
162
- .slds-select[multiple] option {
163
- padding: 0.5rem;
164
- }
165
-
166
- .slds-select_container {
167
- position: relative;
168
- color: var(--sds-c-select-text-color);
169
- }
170
-
171
- .slds-select_container .slds-select {
172
- -moz-appearance: none;
173
- -webkit-appearance: none;
174
- padding-left: 0.5rem;
175
- padding-right: 1.5rem;
176
- }
177
- .slds-select_container .slds-select::-ms-expand {
178
- display: none;
179
- }
180
-
181
- .slds-select[size] option,
182
- .slds-select[multiple] option {
183
- padding: 0.5rem;
184
- }
185
-
186
- .slds-form-element__help,
187
- .slds-form-element__helper {
188
- font-size: 0.75rem;
189
- margin-top: 0.125rem;
190
- display: block;
191
- }