@salesforcedevs/dx-components 1.3.258 → 1.3.259

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/lwc.config.json CHANGED
@@ -5,6 +5,7 @@
5
5
  { "npm": "@salesforcedevs/docs-components" }
6
6
  ],
7
7
  "expose": [
8
+ "dx/agenda",
8
9
  "dx/alert",
9
10
  "dx/audio",
10
11
  "dx/banner",
@@ -14,11 +15,13 @@
14
15
  "dx/buttonToggle",
15
16
  "dx/cardBlogPost",
16
17
  "dx/cardCallout",
18
+ "dx/cardClickthrough",
17
19
  "dx/cardContent",
18
20
  "dx/cardDemo",
19
21
  "dx/cardDocs",
20
22
  "dx/cardEvent",
21
23
  "dx/cardExpanded",
24
+ "dx/cardGrid",
22
25
  "dx/cardGridDocs",
23
26
  "dx/cardMinimal",
24
27
  "dx/cardNews",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "1.3.258",
3
+ "version": "1.3.259",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -45,5 +45,5 @@
45
45
  "volta": {
46
46
  "node": "16.19.1"
47
47
  },
48
- "gitHead": "1a1c249fe121c056d038fa06f99be150f3b799fd"
48
+ "gitHead": "5096835f5d0a2d8cd5bf67ab844b919a89c40758"
49
49
  }
@@ -0,0 +1,97 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+
4
+ ul {
5
+ list-style: none;
6
+ }
7
+
8
+ .container {
9
+ max-width: 840px;
10
+ margin: 0 auto;
11
+ }
12
+
13
+ .detail-list-title {
14
+ text-align: center;
15
+ margin-bottom: 60px;
16
+ }
17
+
18
+ .detail-list-content-container {
19
+ position: relative;
20
+ }
21
+
22
+ .detail-list-content {
23
+ background-color: white;
24
+ border-color: var(--dx-g-gray-90);
25
+ border-style: solid;
26
+ border-width: 1px;
27
+ border-radius: 16px;
28
+ padding: var(--dx-g-spacing-sm) var(--dx-g-spacing-2xl);
29
+ }
30
+
31
+ .detail-list-item {
32
+ align-items: center;
33
+ display: flex;
34
+ gap: var(--dx-g-spacing-xl);
35
+ padding: var(--dx-g-spacing-xl) 0;
36
+ }
37
+
38
+ .detail-list-item:not(:last-child) {
39
+ border-bottom: 1px solid var(--dx-g-gray-95);
40
+ }
41
+
42
+ .detail-list-item-title {
43
+ flex: 1;
44
+ }
45
+
46
+ .detail-list-item .detail-list-item-detail {
47
+ color: var(--dx-g-blue-vibrant-20);
48
+ display: inline-block;
49
+ font-weight: 700;
50
+ width: 25%;
51
+ }
52
+
53
+ .detail-list-item-detail-right {
54
+ text-align: right;
55
+ }
56
+
57
+ .flourish-container {
58
+ position: absolute;
59
+ bottom: 10px;
60
+ right: 0;
61
+ width: var(--dx-c-flourish-width, unset);
62
+ }
63
+
64
+ @media (max-width: 915px) {
65
+ .flourish-container {
66
+ display: none;
67
+ }
68
+ }
69
+
70
+ @media (max-width: 600px) {
71
+ .detail-list-content {
72
+ padding: var(--dx-g-spacing-sm) var(--dx-g-spacing-mlg);
73
+ }
74
+
75
+ .detail-list-item {
76
+ gap: var(--dx-g-spacing-md);
77
+ }
78
+
79
+ .detail-list-item-detail {
80
+ width: 30%;
81
+ }
82
+
83
+ .detail-list-item-title {
84
+ font-size: var(--dx-g-text-base);
85
+ line-height: 20px;
86
+ }
87
+ }
88
+
89
+ @media (max-width: 430px) {
90
+ .detail-list-item-detail {
91
+ font-size: var(--dx-g-text-xs);
92
+ }
93
+
94
+ .detail-list-item-title {
95
+ font-size: var(--dx-g-text-sm);
96
+ }
97
+ }
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div class="container">
3
+ <h2 class="detail-list-title dx-text-display-4">{title}</h2>
4
+ <div class="detail-list-content-container">
5
+ <ul class="detail-list-content" part="content">
6
+ <template for:each={items} for:item="item">
7
+ <li class="detail-list-item" key={item.title}>
8
+ <span
9
+ lwc:if={item.leftDetail}
10
+ class="detail-list-item-detail detail-list-item-detail-left dx-text-body-3"
11
+ >
12
+ {item.leftDetail}
13
+ </span>
14
+ <span class="detail-list-item-title dx-text-display-7">
15
+ {item.title}
16
+ </span>
17
+ <span
18
+ lwc:if={item.rightDetail}
19
+ class="detail-list-item-detail detail-list-item-detail-right dx-text-body-3"
20
+ >
21
+ {item.rightDetail}
22
+ </span>
23
+ </li>
24
+ </template>
25
+ </ul>
26
+ <div lwc:if={flourish} class="flourish-container">
27
+ <img src={flourish} alt={flourishAlt} />
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </template>
@@ -0,0 +1,26 @@
1
+ import { toJson } from "dxUtils/normalizers";
2
+ import { api, LightningElement } from "lwc";
3
+
4
+ export interface AgendaItem {
5
+ body?: string;
6
+ isInitiallyOpen?: boolean;
7
+ leftDetail?: string;
8
+ rightDetail?: string;
9
+ title: string;
10
+ }
11
+
12
+ export default class Agenda extends LightningElement {
13
+ @api title: string = "Agenda";
14
+ @api flourish?: string;
15
+ @api flourishAlt?: string;
16
+
17
+ @api
18
+ get items() {
19
+ return this._items;
20
+ }
21
+ set items(value: any) {
22
+ this._items = toJson(value);
23
+ }
24
+
25
+ private _items: AgendaItem[] = [];
26
+ }
@@ -0,0 +1,69 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+ @import "dxHelpers/card";
4
+
5
+ :host {
6
+ --dx-c-heading-max-lines: 4;
7
+ --dx-c-card-grid-max-width: 60px;
8
+ }
9
+
10
+ .card {
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .not-clickable {
16
+ cursor: default;
17
+ }
18
+
19
+ .image {
20
+ width: 100%;
21
+ height: 160px;
22
+ }
23
+
24
+ .control {
25
+ border-radius: 50%;
26
+ background-color: var(--dx-g-cloud-blue-vibrant-95);
27
+ color: var(--dx-g-blue-vibrant-40);
28
+ width: 48px;
29
+ height: 48px;
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ position: absolute;
34
+ bottom: 32px;
35
+ right: 20px;
36
+ }
37
+
38
+ /* text section */
39
+
40
+ .card_section-text {
41
+ grid-area: text;
42
+ flex-grow: 1;
43
+ position: relative;
44
+ }
45
+
46
+ .dx-text-display-8 dx-button {
47
+ margin-left: var(--dx-g-spacing-xs);
48
+ }
49
+
50
+ .dx-text-display-6 {
51
+ position: relative;
52
+ -webkit-line-clamp: var(--dx-c-heading-max-lines);
53
+ -webkit-box-orient: vertical;
54
+ display: box;
55
+ overflow: hidden;
56
+ }
57
+
58
+ .dx-text-display-6 dx-icon {
59
+ display: inline-block;
60
+ transform: translateY(-3px);
61
+ }
62
+
63
+ /* mobile responsiveness */
64
+
65
+ @media screen and (max-width: 1024px) {
66
+ .has-image:not(.show-mobile-image) .image {
67
+ display: none;
68
+ }
69
+ }
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <a href={href} class={className} target={target} onclick={handleCardClick}>
3
+ <img
4
+ if:true={imgSrc}
5
+ alt={imgAlt}
6
+ src={imgSrc}
7
+ class="image dx-card-base_image"
8
+ />
9
+ <div
10
+ class="dx-card-base_section-vertical dx-card-base_column card_section-text"
11
+ >
12
+ <span class="dx-text-label-3" part="label">{label}</span>
13
+ <dx-card-title title={title} target={target} onclick={handleLinkClick}></dx-card-title>
14
+ <span lwc:if={body} class="dx-text-body-2" onclick={handleTextClick}>{body}</span>
15
+ <span lwc:if={href} class="control"><dx-icon size="medium" symbol="forward"></dx-icon></span>
16
+ </div>
17
+ </a>
18
+ </template>
@@ -0,0 +1,60 @@
1
+ import { LightningElement, api } from "lwc";
2
+ import cx from "classnames";
3
+ import { track } from "dxUtils/analytics";
4
+
5
+ export default class CardClickthrough extends LightningElement {
6
+ @api body!: string;
7
+ @api href?: string;
8
+ @api imgAlt?: string = "";
9
+ @api imgSrc?: string | null = null;
10
+ @api label!: string;
11
+ @api title!: string;
12
+ @api target?: string | null = null;
13
+ @api showMobileImg?: boolean = false;
14
+
15
+ private get className(): string {
16
+ return cx(
17
+ "card",
18
+ "dx-card-base",
19
+ this.imgSrc && "has-image",
20
+ this.showMobileImg && "show-mobile-image",
21
+ !this.href && "not-clickable" // for "coming soon" cards
22
+ );
23
+ }
24
+
25
+ handleCardClick(evt: Event) {
26
+ if (!this.href) {
27
+ evt.preventDefault();
28
+ }
29
+ }
30
+
31
+ private handleLinkClick(event: PointerEvent) {
32
+ if (!this.href) {
33
+ return;
34
+ }
35
+ const payloadCardInfo = {
36
+ click_text: this.title,
37
+ element_title: this.title,
38
+ click_url: this.href,
39
+ element_type: "link",
40
+ content_category: "cta"
41
+ };
42
+ track(event.currentTarget!, "custEv_cardClick", payloadCardInfo);
43
+ track(event.currentTarget!, "custEv_linkClick", payloadCardInfo);
44
+ }
45
+
46
+ private handleTextClick(event: PointerEvent) {
47
+ if (!this.href) {
48
+ return;
49
+ }
50
+ const payloadCardTextInfo = {
51
+ click_text: this.body,
52
+ element_title: this.title,
53
+ click_url: `${window.location.origin}${this.href}`,
54
+ element_type: "tile",
55
+ content_category: "cta"
56
+ };
57
+ track(event.currentTarget!, "custEv_ctaTile", payloadCardTextInfo);
58
+ track(event.currentTarget!, "custEv_linkClick", payloadCardTextInfo);
59
+ }
60
+ }
@@ -9,13 +9,13 @@
9
9
  <div
10
10
  class="dx-card-base_section-vertical dx-card-base_column card_section-text"
11
11
  >
12
- <span class="dx-text-label-3">{label}</span>
12
+ <span class="dx-text-label-3" part="label">{label}</span>
13
13
  <dx-card-title
14
14
  title={title}
15
15
  target={target}
16
16
  onclick={handleLinkClick}
17
17
  ></dx-card-title>
18
- <span class="dx-text-body-2" onclick={handleTextClick}>{body}</span>
18
+ <span lwc:if={body} class="dx-text-body-2" onclick={handleTextClick}>{body}</span>
19
19
  </div>
20
20
  <div class="dx-card-base_section-vertical dx-card-base_ctas">
21
21
  <slot onslotchange={onSlotChange}></slot>
@@ -0,0 +1,5 @@
1
+ @media screen and (max-width: 1024px) {
2
+ dx-card-docs {
3
+ --dx-c-body-max-lines: 3;
4
+ }
5
+ }
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <dx-grid columns={numColumns}>
3
+ <template for:each={cards} for:item="card">
4
+ <dx-card-clickthrough
5
+ key={card.title}
6
+ body={card.body}
7
+ href={card.href}
8
+ img-alt={card.imgAlt}
9
+ img-src={card.imgSrc}
10
+ label={card.label}
11
+ title={card.title}
12
+ target={card.target}
13
+ show-mobile-img={card.showMobileImg}
14
+ >
15
+ </dx-card-clickthrough>
16
+ </template>
17
+ </dx-grid>
18
+ </template>
@@ -0,0 +1,19 @@
1
+ import { api, LightningElement } from "lwc";
2
+ import Grid from "dx/grid";
3
+ import { DocsCard } from "typings/custom";
4
+ import { toJson } from "dxUtils/normalizers";
5
+
6
+ export default class CardGrid extends LightningElement {
7
+ // DocsCard[] with _optional_ href
8
+ private _cards: ({ href?: string } & Omit<DocsCard, "href">)[] = [];
9
+
10
+ @api
11
+ get cards() {
12
+ return this._cards;
13
+ }
14
+ set cards(value: any) {
15
+ this._cards = toJson(value);
16
+ }
17
+
18
+ @api numColumns: Grid["columns"] = "three";
19
+ }
@@ -13,7 +13,7 @@ a {
13
13
  }
14
14
 
15
15
  footer {
16
- padding-top: var(--dx-g-spacing-5xl);
16
+ padding-top: var(--dx-c-footer-padding-top, var(--dx-g-spacing-5xl));
17
17
  }
18
18
 
19
19
  footer.signup-variant-large-signup {
@@ -74,6 +74,10 @@ footer.signup-variant-no-signup {
74
74
  height: 504px;
75
75
  }
76
76
 
77
+ .content-container_top_large_no_signup {
78
+ height: 33vw;
79
+ }
80
+
77
81
  .subscription {
78
82
  position: relative;
79
83
  z-index: 1;
@@ -278,7 +282,7 @@ footer.signup-variant-no-signup {
278
282
  }
279
283
 
280
284
  @media screen and (min-width: 1400px) {
281
- .content-container_top_large {
285
+ .content-container_top_large:not(.content-container_top_large_no_signup) {
282
286
  /* takes into account the background assets' h:w ratio */
283
287
  height: 38vw;
284
288
  }
@@ -301,11 +305,20 @@ footer.signup-variant-no-signup {
301
305
  background-size: 122.92%;
302
306
  }
303
307
 
308
+ .content-container_top_large_no_signup .graphic-large {
309
+ background-size: 101%;
310
+ }
311
+
304
312
  .content-container_top_large {
305
313
  height: 464px;
306
314
  padding-top: var(--dx-g-spacing-2xl);
307
315
  }
308
316
 
317
+ .content-container_top_large_no_signup {
318
+ height: 38vw;
319
+ padding-top: 0;
320
+ }
321
+
309
322
  .subscription h3 {
310
323
  font-size: 24px;
311
324
  line-height: 28px;
@@ -380,6 +393,10 @@ footer.signup-variant-no-signup {
380
393
  padding-bottom: 140px;
381
394
  }
382
395
 
396
+ .content-container_top_large_no_signup {
397
+ height: 44vw;
398
+ }
399
+
383
400
  .graphic-mountains {
384
401
  display: none;
385
402
  }
@@ -34,6 +34,13 @@
34
34
  </dx-button>
35
35
  </div>
36
36
  </div>
37
+ <div
38
+ if:true={showLargeNoSignup}
39
+ class={largeNoSignupClassName}
40
+ >
41
+ <div class="graphic graphic-large" alt=""></div>
42
+ <slot name="custom-content" onslotchange={onSlotChange}></slot>
43
+ </div>
37
44
  <div
38
45
  if:true={showContainerMiddle}
39
46
  class="content-container content-container_middle"
@@ -1,6 +1,10 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { FooterVariant, OptionWithLink } from "typings/custom";
3
+ import {
4
+ FooterVariant,
5
+ LightningSlotElement,
6
+ OptionWithLink
7
+ } from "typings/custom";
4
8
  import { toJson } from "dxUtils/normalizers";
5
9
  import {
6
10
  defaultGeneralLinks,
@@ -9,6 +13,7 @@ import {
9
13
  intellectualHref
10
14
  } from "./links";
11
15
  import { track } from "dxUtils/analytics";
16
+ import { isSlotEmpty } from "dxUtils/slot";
12
17
 
13
18
  export default class Footer extends LightningElement {
14
19
  @api locale: string | null = null;
@@ -34,6 +39,7 @@ export default class Footer extends LightningElement {
34
39
  private _locales: OptionWithLink[] | null = null;
35
40
  private _variant: FooterVariant = "small-signup";
36
41
  private intellectualHref = intellectualHref;
42
+ private isSlotEmpty = true;
37
43
  private socialLinks = socialLinks;
38
44
  private termsLinks = termsLinks;
39
45
  private signupUrl = "https://www.salesforce.com/form/other/role-based-newsletter/?Developer=true";
@@ -64,6 +70,10 @@ export default class Footer extends LightningElement {
64
70
  return this.variant === "small-signup";
65
71
  }
66
72
 
73
+ get showLargeNoSignup() {
74
+ return this.variant === "large-no-signup";
75
+ }
76
+
67
77
  get hasLocales() {
68
78
  return this.locale && this.locales;
69
79
  }
@@ -94,17 +104,31 @@ export default class Footer extends LightningElement {
94
104
  return cx(`signup-variant-${this.variant}`);
95
105
  }
96
106
 
107
+ get largeNoSignupClassName() {
108
+ return cx(
109
+ "content-container",
110
+ "content-container_top_large",
111
+ "content-container_top_large_no_signup",
112
+ !this.isSlotEmpty && "custom-content"
113
+ );
114
+ }
115
+
97
116
  private onLocaleChange(e: CustomEvent) {
98
117
  this.dispatchEvent(
99
118
  new CustomEvent("localechange", { detail: e.detail })
100
119
  );
101
120
  }
102
121
 
122
+ private onSlotChange(e: LightningSlotElement): void {
123
+ this.isSlotEmpty = isSlotEmpty(e);
124
+ }
125
+
103
126
  private isFooterVariant(value: string): value is FooterVariant {
104
127
  return [
105
128
  "no-signup",
106
129
  "small-signup",
107
130
  "large-signup",
131
+ "large-no-signup",
108
132
  "terms-only"
109
133
  ].includes(value);
110
134
  }
@@ -1,6 +1,7 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import { LightningSlotElement } from "typings/custom";
3
3
  import debounce from "debounce";
4
+ import { isSlotEmpty } from "dxUtils/slot";
4
5
  const MOBILE_SIZE = 640;
5
6
  const getInputSize = () =>
6
7
  (window.innerWidth ||
@@ -30,8 +31,7 @@ export default class SectionSignup extends LightningElement {
30
31
  }
31
32
 
32
33
  private onSlotChange(e: LightningSlotElement) {
33
- // @ts-ignore
34
- this.isSlotEmpty = e.target.assignedElements().length === 0;
34
+ this.isSlotEmpty = isSlotEmpty(e);
35
35
  }
36
36
 
37
37
  private _updateSize = () => {