@salesforcedevs/dx-components 1.5.0-alpha2 → 1.8.0-node-20-alpha
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 +1 -0
- package/package.json +3 -3
- package/src/modules/dx/cardDocs/cardDocs.html +13 -3
- package/src/modules/dx/cardDocs/cardDocs.ts +1 -0
- package/src/modules/dx/cardTitle/cardTitle.html +1 -1
- package/src/modules/dx/darkModeManager/darkModeManager.ts +21 -27
- package/src/modules/dx/eyebrow/eyebrow.css +44 -0
- package/src/modules/dx/eyebrow/eyebrow.html +16 -0
- package/src/modules/dx/eyebrow/eyebrow.ts +32 -0
- package/src/modules/dx/feature/feature.css +11 -1
- package/src/modules/dx/feature/feature.html +3 -2
- package/src/modules/dx/featureFlag/featureFlag.ts +20 -25
- package/src/modules/dx/featuredContentHeader/featuredContentHeader.html +2 -2
- package/src/modules/dx/featuredContentHeader/featuredContentHeader.ts +5 -2
- package/src/modules/dx/footer/footer.css +1 -1
- package/package-lock.json +0 -7980
package/lwc.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/dx-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0-node-20-alpha",
|
|
4
4
|
"description": "DX Lightning web components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": "
|
|
7
|
+
"node": "20.x"
|
|
8
8
|
},
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
@@ -44,6 +44,6 @@
|
|
|
44
44
|
"luxon": "3.4.4"
|
|
45
45
|
},
|
|
46
46
|
"volta": {
|
|
47
|
-
"node": "
|
|
47
|
+
"node": "20.19.0"
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<a href={href} class={className} target={target}>
|
|
2
|
+
<a href={href} class={className} target={target} part="base">
|
|
3
3
|
<img
|
|
4
4
|
if:true={imgSrc}
|
|
5
5
|
alt={imgAlt}
|
|
@@ -8,22 +8,32 @@
|
|
|
8
8
|
/>
|
|
9
9
|
<div
|
|
10
10
|
class="dx-card-base_section-vertical dx-card-base_column card_section-text"
|
|
11
|
+
part="content"
|
|
11
12
|
>
|
|
12
|
-
<span class="dx-text-label-3" part="label">
|
|
13
|
+
<span class="dx-text-label-3" lwc:if={label} part="label">
|
|
14
|
+
{label}
|
|
15
|
+
</span>
|
|
13
16
|
<dx-card-title
|
|
17
|
+
lwc:if={header}
|
|
14
18
|
header={header}
|
|
15
19
|
target={target}
|
|
16
20
|
onclick={handleLinkClick}
|
|
21
|
+
exportparts="title"
|
|
17
22
|
></dx-card-title>
|
|
18
23
|
<span
|
|
19
24
|
lwc:if={body}
|
|
20
25
|
class="dx-text-body-2"
|
|
21
26
|
onclick={handleTextClick}
|
|
27
|
+
part="body"
|
|
22
28
|
>
|
|
23
29
|
{body}
|
|
24
30
|
</span>
|
|
31
|
+
<span lwc:if={subText} class="dx-text-body-3">{subText}</span>
|
|
25
32
|
</div>
|
|
26
|
-
<div
|
|
33
|
+
<div
|
|
34
|
+
class="dx-card-base_section-vertical dx-card-base_ctas"
|
|
35
|
+
part="action"
|
|
36
|
+
>
|
|
27
37
|
<slot onslotchange={onSlotChange}></slot>
|
|
28
38
|
</div>
|
|
29
39
|
</a>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @lwc/lwc/no-document-query */
|
|
2
|
-
import { OPTIMIZELY_INSTANCE, USER_ID } from "dx/featureFlag";
|
|
3
2
|
import { LightningElement } from "lwc";
|
|
4
3
|
|
|
5
4
|
export const LOCAL_STORAGE_KEY = "dx-dark-mode-theme";
|
|
@@ -30,7 +29,10 @@ declare module globalThis {
|
|
|
30
29
|
|
|
31
30
|
export const DARK_MODE_THEMES = ["dark", "light"];
|
|
32
31
|
export const DARKMODE_TOGGLE_EVENT_NAME = "UPDATE_DARK_MODE";
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
export const isDarkModeEnabled = () => {
|
|
34
|
+
return process.env.DARK_MODE;
|
|
35
|
+
};
|
|
34
36
|
|
|
35
37
|
export const dispatchDarkModeToggleEvent = () => {
|
|
36
38
|
window.dispatchEvent(new Event(DARKMODE_TOGGLE_EVENT_NAME));
|
|
@@ -53,40 +55,32 @@ export const setLocalStorageDarkModeSetting = (theme: string) => {
|
|
|
53
55
|
|
|
54
56
|
export default class DarkModeManager extends LightningElement {
|
|
55
57
|
renderedCallback(): void {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
if (!globalThis.singletonDarkModeManagerRendered) {
|
|
65
|
-
const theme = getLocalStorageDarkModeSetting();
|
|
66
|
-
if (theme) {
|
|
67
|
-
if (DARK_MODE_THEMES.includes(theme)) {
|
|
68
|
-
setTheme(theme);
|
|
69
|
-
}
|
|
70
|
-
} else if (isBrowserDarkModeEnabled()) {
|
|
71
|
-
setTheme("dark");
|
|
72
|
-
}
|
|
73
|
-
window.addEventListener(
|
|
74
|
-
DARKMODE_TOGGLE_EVENT_NAME,
|
|
75
|
-
onDarkModeToggle
|
|
76
|
-
);
|
|
77
|
-
globalThis.singletonDarkModeManagerRendered = true;
|
|
58
|
+
if (
|
|
59
|
+
isDarkModeEnabled() &&
|
|
60
|
+
!globalThis.singletonDarkModeManagerRendered
|
|
61
|
+
) {
|
|
62
|
+
const theme = getLocalStorageDarkModeSetting();
|
|
63
|
+
if (theme) {
|
|
64
|
+
if (DARK_MODE_THEMES.includes(theme)) {
|
|
65
|
+
setTheme(theme);
|
|
78
66
|
}
|
|
67
|
+
} else if (isBrowserDarkModeEnabled()) {
|
|
68
|
+
setTheme("dark");
|
|
79
69
|
}
|
|
80
|
-
|
|
70
|
+
window.addEventListener(
|
|
71
|
+
DARKMODE_TOGGLE_EVENT_NAME,
|
|
72
|
+
onDarkModeToggle
|
|
73
|
+
);
|
|
74
|
+
globalThis.singletonDarkModeManagerRendered = true;
|
|
75
|
+
}
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
disconnectedCallback(): void {
|
|
84
|
-
if (
|
|
79
|
+
if (isDarkModeEnabled()) {
|
|
85
80
|
window.removeEventListener(
|
|
86
81
|
DARKMODE_TOGGLE_EVENT_NAME,
|
|
87
82
|
onDarkModeToggle
|
|
88
83
|
);
|
|
89
|
-
globalThis.singletonDarkModeManagerRendered = false;
|
|
90
84
|
}
|
|
91
85
|
}
|
|
92
86
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@import "dxHelpers/text";
|
|
2
|
+
|
|
3
|
+
.eyebrow {
|
|
4
|
+
display: flex;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
align-items: center;
|
|
7
|
+
background: var(--dx-g-blue-vibrant-10);
|
|
8
|
+
color: white;
|
|
9
|
+
padding: 6px 40px;
|
|
10
|
+
gap: 4px;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.eyebrow.fixed {
|
|
15
|
+
position: fixed;
|
|
16
|
+
top: var(--dx-g-global-header-height, 0);
|
|
17
|
+
width: 100%;
|
|
18
|
+
z-index: var(--dx-g-z-index-max, 999);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.eyebrow > dx-icon {
|
|
22
|
+
padding-right: 5px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.eyebrow > span {
|
|
26
|
+
text-align: center;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.eyebrow > span > a {
|
|
30
|
+
color: white;
|
|
31
|
+
text-decoration: underline;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (min-width: 768px) and (max-width: 1279px) {
|
|
35
|
+
.eyebrow {
|
|
36
|
+
padding: 6px 32px;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@media (max-width: 767px) {
|
|
41
|
+
.eyebrow {
|
|
42
|
+
padding: 6px 24px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class={className}>
|
|
3
|
+
<dx-icon
|
|
4
|
+
sprite={iconSprite}
|
|
5
|
+
symbol={iconSymbol}
|
|
6
|
+
size={iconSize}
|
|
7
|
+
></dx-icon>
|
|
8
|
+
<span>
|
|
9
|
+
{body}
|
|
10
|
+
<template lwc:if={hasCta}>
|
|
11
|
+
|
|
12
|
+
<a target={ctaTarget} href={ctaHref}>{ctaLabel}</a>
|
|
13
|
+
</template>
|
|
14
|
+
</span>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import cx from "classnames";
|
|
2
|
+
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
3
|
+
import { api, LightningElement } from "lwc";
|
|
4
|
+
import { IconSize, IconSprite, IconSymbol } from "typings/custom";
|
|
5
|
+
|
|
6
|
+
export default class Eyebrow extends LightningElement {
|
|
7
|
+
@api body = "";
|
|
8
|
+
@api ctaHref = "";
|
|
9
|
+
@api ctaLabel = "";
|
|
10
|
+
@api ctaTarget = "_blank";
|
|
11
|
+
@api iconSize: IconSize = "large";
|
|
12
|
+
@api iconSprite: IconSprite = "action";
|
|
13
|
+
@api iconSymbol: IconSymbol = "info";
|
|
14
|
+
|
|
15
|
+
@api
|
|
16
|
+
get fixed() {
|
|
17
|
+
return this._fixed;
|
|
18
|
+
}
|
|
19
|
+
set fixed(value: string | boolean) {
|
|
20
|
+
this._fixed = normalizeBoolean(value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private _fixed: boolean = false;
|
|
24
|
+
|
|
25
|
+
get hasCta() {
|
|
26
|
+
return Boolean(this.ctaHref && this.ctaLabel);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get className() {
|
|
30
|
+
return cx("eyebrow", "dx-text-body-3", this.fixed && "fixed");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
--dx-c-feature-img-container-padding: 4rem;
|
|
10
10
|
--dx-c-feature-image-max-width: 100%;
|
|
11
11
|
--dx-c-feature-description-font-size: var(--dx-g-text-base);
|
|
12
|
+
--dx-c-feature-description-img-width: 45%;
|
|
13
|
+
--dx-c-feature-description-gap: 0;
|
|
14
|
+
--dx-c-feature-description-img-gap: 0;
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
.label {
|
|
@@ -31,11 +34,18 @@ h3 {
|
|
|
31
34
|
section {
|
|
32
35
|
display: flex;
|
|
33
36
|
align-items: center;
|
|
37
|
+
gap: var(--dx-c-feature-description-img-gap);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.description {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: var(--dx-c-feature-description-gap);
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
.description,
|
|
37
47
|
.image {
|
|
38
|
-
width:
|
|
48
|
+
width: var(--dx-c-feature-description-img-width);
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
.image {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<section class={sectionClass}>
|
|
3
3
|
<div class="description">
|
|
4
4
|
<h2 if:true={hasLabel} class="dx-text-display-8 label">{label}</h2>
|
|
5
|
-
<h3 class="dx-text-display-4">{header}</h3>
|
|
6
|
-
<div class="body dx-text-body-2">
|
|
5
|
+
<h3 class="dx-text-display-4" part="header">{header}</h3>
|
|
6
|
+
<div class="body dx-text-body-2" part="body">
|
|
7
7
|
<slot></slot>
|
|
8
8
|
</div>
|
|
9
9
|
<dx-button
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
icon-symbol={iconSymbol}
|
|
14
14
|
href={buttonHref}
|
|
15
15
|
onclick={handleClick}
|
|
16
|
+
if:true={buttonHref}
|
|
16
17
|
>
|
|
17
18
|
{buttonLabel}
|
|
18
19
|
</dx-button>
|
|
@@ -3,42 +3,37 @@ import optimizelySdk from "@optimizely/optimizely-sdk";
|
|
|
3
3
|
|
|
4
4
|
// This is needed to specify user context (such as logged in, admin, ...etc).
|
|
5
5
|
// leave this as hard-coded for now until we create audiences in Optimizely.
|
|
6
|
-
|
|
7
|
-
const LOCAL_ENVIRONMENT_SDK_KEY = "DzwQxncbVQsbMnXfjpasL";
|
|
8
|
-
const SDK_KEY = process.env.OPTIMIZELY_SDK_KEY;
|
|
9
|
-
const DATAFILE_ACCESS_TOKEN = process.env.OPTIMIZELY_DATAFILE_ACCESS_TOKEN;
|
|
10
|
-
const DATAFILE_OPTIONS =
|
|
11
|
-
SDK_KEY && DATAFILE_ACCESS_TOKEN
|
|
12
|
-
? {
|
|
13
|
-
urlTemplate: `https://config.optimizely.com/datafiles/auth/${SDK_KEY}.json`,
|
|
14
|
-
datafileAccessToken: DATAFILE_ACCESS_TOKEN
|
|
15
|
-
}
|
|
16
|
-
: undefined;
|
|
17
|
-
export const OPTIMIZELY_INSTANCE = optimizelySdk.createInstance({
|
|
18
|
-
sdkKey: SDK_KEY || LOCAL_ENVIRONMENT_SDK_KEY,
|
|
19
|
-
datafileOptions: DATAFILE_OPTIONS
|
|
20
|
-
});
|
|
6
|
+
const userId = "user123";
|
|
21
7
|
|
|
22
8
|
export default class FeatureFlag extends LightningElement {
|
|
23
9
|
@api flag!: string;
|
|
24
10
|
|
|
11
|
+
private optimizelyInstance: any;
|
|
12
|
+
|
|
25
13
|
private showElements(slot: any) {
|
|
26
14
|
slot.classList.remove("hidden");
|
|
27
15
|
}
|
|
28
16
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
connectedCallback(): void {
|
|
18
|
+
this.optimizelyInstance = optimizelySdk.createInstance({
|
|
19
|
+
sdkKey: process.env.OPTIMIZELY_SDK_KEY
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
34
23
|
renderedCallback(): void {
|
|
35
24
|
const slotEl = this.template.querySelector("slot") as any;
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
this.optimizelyInstance?.onReady().then(({ success, reason }: any) => {
|
|
27
|
+
if (!success) {
|
|
28
|
+
console.log(
|
|
29
|
+
`Optimizely client initialization unsuccessful, reason: ${reason}`
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const user = this.optimizelyInstance?.createUserContext(userId);
|
|
34
|
+
const decision = user?.decide(this.flag);
|
|
35
|
+
|
|
36
|
+
if (decision?.enabled) {
|
|
42
37
|
this.showElements(slotEl);
|
|
43
38
|
}
|
|
44
39
|
});
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
<div>
|
|
22
22
|
<slot name="language-selector"></slot>
|
|
23
23
|
</div>
|
|
24
|
-
<
|
|
24
|
+
<template lwc:if={isDarkModeEnabled}>
|
|
25
25
|
<div
|
|
26
26
|
class="dark-mode-button"
|
|
27
27
|
onclick={onDarkModeButtonClick}
|
|
28
28
|
>
|
|
29
29
|
<div class="dark-mode-icon"></div>
|
|
30
30
|
</div>
|
|
31
|
-
</
|
|
31
|
+
</template>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
<div class="container-layout">
|
|
@@ -5,7 +5,10 @@ import { toJson } from "dxUtils/normalizers";
|
|
|
5
5
|
import { track } from "dxUtils/analytics";
|
|
6
6
|
import svgs from "./svgs";
|
|
7
7
|
import ImageAndLabel from "dx/imageAndLabel";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
dispatchDarkModeToggleEvent,
|
|
10
|
+
isDarkModeEnabled
|
|
11
|
+
} from "dx/darkModeManager";
|
|
9
12
|
|
|
10
13
|
export default class FeaturedContentHeader extends LightningElement {
|
|
11
14
|
@api label?: string | null = null;
|
|
@@ -92,7 +95,7 @@ export default class FeaturedContentHeader extends LightningElement {
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
private get isDarkModeEnabled() {
|
|
95
|
-
return this.enableDarkModeToggle;
|
|
98
|
+
return this.enableDarkModeToggle && isDarkModeEnabled();
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
private get hasPlainImage() {
|