New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@salesforcedevs/docs-components

Package Overview
Dependencies
Maintainers
28
Versions
679
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@salesforcedevs/docs-components - npm Package Compare versions

Comparing version

to
0.5.0-alpha1

4

package.json
{
"name": "@salesforcedevs/docs-components",
"version": "0.4.48",
"version": "0.5.0-alpha1",
"description": "Docs Lightning web components for DSC",

@@ -17,3 +17,3 @@ "license": "MIT",

},
"gitHead": "bece6881f38e566196a3c0720eb3b7c1573b8913"
"gitHead": "4629fdd9ca18a13480044ad43515b91945d16aad"
}

@@ -13,5 +13,7 @@ import Button from "dx/button";

import Dropdown from "dx/dropdown";
import { Option } from "typings/custom";
const EXPECTED_QUERY_TABLET = "(max-width: 980px)";
const EXPECTED_QUERY_MOBILE = "(max-width: 880px)";
const SMALL_MOBILE_MATCH = "(max-width: 740px)";

@@ -21,5 +23,64 @@ const TAG = "doc-header";

const assertMediaMatchCalls = () => {
expect(window.matchMedia).toBeCalledTimes(3);
expect(window.matchMedia).toHaveBeenNthCalledWith(1, EXPECTED_QUERY_MOBILE);
expect(window.matchMedia).toHaveBeenNthCalledWith(2, EXPECTED_QUERY_TABLET);
expect(window.matchMedia).toHaveBeenLastCalledWith(SMALL_MOBILE_MATCH);
};
const assertDropdownRender = (
element: Header,
dropdown: Dropdown,
languages: Array<Option>
) => {
expect(dropdown).not.toBeNull();
expect(dropdown.classList).toHaveLength(1);
expect(dropdown.classList).toContain("header_lang-dropdown");
expect(dropdown.options).toHaveLength(languages.length);
dropdown.options.forEach((option, index) => {
const mockLang = languages[index];
expect(option).toHaveProperty("id", mockLang.id);
expect(option).toHaveProperty("label", mockLang.label);
});
expect(dropdown.valuePath).toBe(element.langValuePath);
expect(dropdown.value).toBe(element.language);
expect(dropdown.querySelector("dx-button")).not.toBeNull();
};
const testLangEvent = () => {
const { languages } = mockPropsDevelopers;
const [firstLang, secondLang] = languages;
const element = render({
...mockPropsDevelopers,
language: firstLang.id
});
expect(element.language).toBe(firstLang.id);
const dropdown: HTMLElement = element.shadowRoot.querySelector(
".header_lang-dropdown"
);
const mockLangChange = jest.fn();
element.addEventListener("langchange", mockLangChange);
dropdown.dispatchEvent(
new CustomEvent("change", { detail: secondLang.id })
);
expect(element.language).toBe(secondLang.id);
expect(mockLangChange).toBeCalledTimes(1);
expect(mockLangChange.mock.calls[0][0]).toHaveProperty(
"detail",
secondLang.id
);
return expect(element).toBeAccessible();
};
describe(TAG, () => {
afterEach(() => {
jest.clearAllMocks();
afterAll(() => {
jest.resetAllMocks();
});

@@ -29,9 +90,55 @@

it("renders", () => {
const element = render();
const headerEl: HTMLElement = element.shadowRoot.querySelector(
"header"
);
expect(headerEl).not.toBeNull();
expect(headerEl.classList).toHaveLength(0);
expect(headerEl.querySelector("dx-feedback-banner")).not.toBeNull();
const logo = element.shadowRoot.querySelector("dx-logo");
expect(logo).not.toBeNull();
expect(logo.label).toBe("Salesforce");
expect(
element.shadowRoot.querySelector("dx-header-nav")
).toBeNull();
expect(
element.shadowRoot.querySelector("dx-header-search")
).toBeNull();
expect(
element.shadowRoot.querySelector("dx-header-mobile-nav-menu")
).toBeNull();
const homeLink: HTMLAnchorElement = element.shadowRoot.querySelector(
".home-link"
);
expect(homeLink).not.toBeNull();
expect(homeLink.href).toMatch(/\/$/);
expect(homeLink.querySelector("dx-icon")).toBeNull();
expect(element.shadowRoot.querySelector("dx-dropdown")).toBeNull();
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-nav"
)
).toBeNull();
});
it("renders with some properties", () => {
const subtitle = "testsubtitle";
const element = render({ ...mockPropsDevelopers, subtitle });
const subtitleEl = element.shadowRoot.querySelector(".subtitle");
const buttons: Array<HTMLElement> = element.shadowRoot.querySelectorAll(
"dx-button"
expect(subtitleEl.textContent).toEqual(subtitle);
const signUp: HTMLElement = element.shadowRoot.querySelector(
".header-login-signup dx-button"
);
const dropdown = element.shadowRoot.querySelector("dx-dropdown");
expect(signUp).not.toBeNull();
const headerNavs: Array<HeaderNav> = element.shadowRoot.querySelectorAll(

@@ -44,6 +151,18 @@ "dx-header-nav"

expect(subtitleEl.textContent).toEqual(subtitle);
expect(buttons).toHaveLength(1);
expect(dropdown).toBeNull();
const dropdown: Dropdown = element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-right-ctas dx-dropdown"
);
assertDropdownRender(
element,
dropdown,
mockPropsDevelopers.languages
);
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-title dx-dropdown"
)
).toBeNull();
const brandIcon = element.shadowRoot.querySelector(".brand-icon");

@@ -102,41 +221,5 @@ expect(brandIcon).toBeNull();

it("receives versions", () => {
const version = { id: "123", label: "Test" };
const element = render({
...mockPropsDevelopers,
versions: JSON.stringify([version])
});
const dropdown: Dropdown = element.shadowRoot.querySelector(
"dx-dropdown"
);
expect(dropdown).not.toBeNull();
expect(dropdown.options).toHaveLength(1);
// eslint-disable-next-line jest/expect-expect
it("triggers event on language change", testLangEvent);
const [option] = dropdown.options;
expect(option).toHaveProperty("id", version.id);
expect(option).toHaveProperty("label", version.label);
return expect(element).toBeAccessible();
});
it("triggers event on version change", () => {
const versionsListParameter = [{ id: "123", label: "Test" }];
const element = render({
...mockPropsDevelopers,
versions: JSON.stringify(versionsListParameter)
});
const dropdown: HTMLElement = element.shadowRoot.querySelector(
".header_version-dropdown"
);
const mockVersionChange = jest.fn();
element.addEventListener("versionchange", mockVersionChange);
dropdown.dispatchEvent(
new CustomEvent("change", { detail: "123" })
);
expect(mockVersionChange).toBeCalledTimes(1);
expect(mockVersionChange.mock.calls[0][0].detail).toEqual("123");
return expect(element).toBeAccessible();
});
it("triggers event onrequestopennav", () => {

@@ -208,12 +291,6 @@ const element = render({

describe("tablet", () => {
const oldMatchMedia = window.matchMedia;
beforeAll(() => {
window.matchMedia = createMediaMock(false, [false, true]);
beforeEach(() => {
window.matchMedia = createMediaMock(false, [false, true, false]);
});
afterAll(() => {
window.matchMedia = oldMatchMedia;
});
it("renders tablet specific elements", () => {

@@ -237,10 +314,14 @@ const element = render(mockPropsDevelopers);

expect(signupDiv).not.toBeNull();
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-right-ctas dx-dropdown"
)
).not.toBeNull();
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-title dx-dropdown"
)
).toBeNull();
expect(window.matchMedia).toBeCalledTimes(2);
expect(window.matchMedia).toHaveBeenCalledWith(
EXPECTED_QUERY_MOBILE
);
expect(window.matchMedia).toHaveBeenLastCalledWith(
EXPECTED_QUERY_TABLET
);
assertMediaMatchCalls();
});

@@ -250,12 +331,6 @@ });

describe("mobile", () => {
const oldMatchMedia = window.matchMedia;
beforeAll(() => {
window.matchMedia = createMediaMock(true);
beforeEach(() => {
window.matchMedia = createMediaMock(false, [true, true, false]);
});
afterAll(() => {
window.matchMedia = oldMatchMedia;
});
it("renders mobile specific elements", () => {

@@ -272,18 +347,21 @@ const element = render(mockPropsDevelopers);

);
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-right-ctas dx-dropdown"
)
).not.toBeNull();
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-title dx-dropdown"
)
).toBeNull();
expect(headerSearch).not.toBeNull();
expect(headerSearch.mobile).toBe(true);
expect(window.matchMedia).toBeCalledTimes(2);
expect(window.matchMedia).toHaveBeenCalledWith(
EXPECTED_QUERY_MOBILE
);
expect(window.matchMedia).toHaveBeenLastCalledWith(
EXPECTED_QUERY_TABLET
);
assertMediaMatchCalls();
});
it("tests toggle button", () => {
const element = render({
...mockPropsDevelopers
});
const element = render(mockPropsDevelopers);
const button: HTMLElement = element.shadowRoot.querySelector(

@@ -307,2 +385,33 @@ ".nav_menu-ctas .nav_menu-button"

});
describe("small mobile", () => {
beforeEach(() => {
window.matchMedia = createMediaMock(true);
});
it("renders small mobile specific elements", () => {
const element = render(mockPropsDevelopers);
const dropdown = element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-title dx-dropdown"
);
expect(dropdown).not.toBeNull();
assertDropdownRender(
element,
dropdown,
mockPropsDevelopers.languages
);
expect(
element.shadowRoot.querySelector(
".header_l2_group.header_l2_group-right-ctas dx-dropdown"
)
).toBeNull();
return expect(element).toBeAccessible();
});
// eslint-disable-next-line jest/expect-expect
it("triggers event on language change", testLangEvent);
});
});

@@ -17,19 +17,12 @@ import {

import mockNavDevelopers from "./mockNavDevelopers";
import { Option } from "typings/custom";
const versions = [
const languages: Option[] = [
{
id: "1",
label: "v1"
id: "en-us",
label: "English"
},
{
id: "2",
label: "v2"
},
{
id: "3",
label: "v3"
},
{
id: "4",
label: "v4"
id: "ja-jp",
label: "日本語"
}

@@ -42,2 +35,3 @@ ];

subtitle: "Apex Developer Guides",
languages,
...coveoConfig

@@ -57,5 +51,3 @@ };

scopedNavItems: mockNavEmployees,
subtitle: "Employees",
version: "1",
versions
subtitle: "Employees"
};

@@ -69,5 +61,3 @@

scopedNavItems: mockNavMarketing,
subtitle: "Marketing",
version: "1",
versions
subtitle: "Marketing"
};

@@ -81,5 +71,3 @@

scopedNavItems: mockNavPartners,
subtitle: "Partners",
version: "1",
versions
subtitle: "Partners"
};

@@ -93,5 +81,3 @@

scopedNavItems: mockNavCommerce,
subtitle: "Commerce",
version: "1",
versions
subtitle: "Commerce"
};

@@ -105,5 +91,3 @@

scopedNavItems: mockNavSales,
subtitle: "Sales",
version: "1",
versions
subtitle: "Sales"
};

@@ -117,5 +101,3 @@

scopedNavItems: mockNavSuccess,
subtitle: "Success",
version: "1",
versions
subtitle: "Success"
};

@@ -129,5 +111,3 @@

scopedNavItems: mockNavIntegration,
subtitle: "Integration",
version: "1",
versions
subtitle: "Integration"
};

@@ -141,5 +121,3 @@

scopedNavItems: mockNavPlatform,
subtitle: "Platform",
version: "1",
versions
subtitle: "Platform"
};

@@ -153,5 +131,3 @@

scopedNavItems: mockNavIndustries,
subtitle: "Industries",
version: "1",
versions
subtitle: "Industries"
};

@@ -165,5 +141,3 @@

scopedNavItems: mockNavLearning,
subtitle: "Learning",
version: "1",
versions
subtitle: "Learning"
};

@@ -177,5 +151,3 @@

scopedNavItems: mockNavService,
subtitle: "Service",
version: "1",
versions
subtitle: "Service"
};

@@ -189,5 +161,3 @@

scopedNavItems: mockNavAnalytics,
subtitle: "Analytics",
version: "1",
versions
subtitle: "Analytics"
};

@@ -18,5 +18,28 @@ import { html } from "lit-html";

const controlLang = mockPropsDevelopers.languages.map(({ id }) => id);
export default {
title: "docs/doc-header",
component: "doc-header"
component: "doc-header",
argTypes: {
bailHref: {
defaultValue: "/quip-dev-center",
control: {
type: "text"
}
},
bailLabel: {
defaultValue: "PDF",
control: {
type: "text"
}
},
language: {
defaultValue: controlLang[0],
control: {
options: controlLang,
type: "select"
}
}
}
};

@@ -62,3 +85,4 @@

mockProps: any,
brand: string
brand: string,
args: any
) => html` ${styles()} ${renderPreventNavScript()}

@@ -75,7 +99,7 @@ <div class="fake-url">/</div>

nav-items="${JSON.stringify(mockProps.navItems)}"
languages="${JSON.stringify(mockProps.languages)}"
language="${args.language}"
scoped-nav-items="${JSON.stringify(mockProps.scopedNavItems)}"
versions="${JSON.stringify(mockProps.versions)}"
version="1"
bail-href="/quip-dev-center"
bail-label="Quip Center"
bail-href="${args.bailHref}"
bail-label="${args.bailLabel}"
brand="${brand}"

@@ -85,3 +109,3 @@ onclick="headerClick(event)"

export const Base = () => html`
export const Base = (args: any) => html`
${styles()} ${renderPreventNavScript()}

@@ -91,6 +115,8 @@ <div class="fake-url">/</div>

title="${mockPropsDevelopers.title}"
bail-href="/"
bail-label="PDF"
bail-href="${args.bailHref}"
bail-label="${args.bailLabel}"
subtitle="${mockPropsDevelopers.subtitle}"
nav-items="${JSON.stringify(mockPropsDevelopers.navItems)}"
languages="${JSON.stringify(mockPropsDevelopers.languages)}"
language="${args.language}"
coveo-organization-id="${mockPropsDevelopers.coveoOrganizationId}"

@@ -105,33 +131,36 @@ coveo-public-access-token="${mockPropsDevelopers.coveoPublicAccessToken}"

// BRAND STORIES
export const Employees = () =>
headerStoryGenerator(mockPropsEmployees, "employees");
export const Employees = (args: any) =>
headerStoryGenerator(mockPropsEmployees, "employees", args);
export const Marketing = () =>
headerStoryGenerator(mockPropsMarketing, "marketing");
export const Marketing = (args: any) =>
headerStoryGenerator(mockPropsMarketing, "marketing", args);
export const Partners = () =>
headerStoryGenerator(mockPropsPartners, "partners");
export const Partners = (args: any) =>
headerStoryGenerator(mockPropsPartners, "partners", args);
export const Commerce = () =>
headerStoryGenerator(mockPropsCommerce, "commerce");
export const Commerce = (args: any) =>
headerStoryGenerator(mockPropsCommerce, "commerce", args);
export const Sales = () => headerStoryGenerator(mockPropsSales, "sales");
export const Sales = (args: any) =>
headerStoryGenerator(mockPropsSales, "sales", args);
export const Success = () => headerStoryGenerator(mockPropsSuccess, "success");
export const Success = (args: any) =>
headerStoryGenerator(mockPropsSuccess, "success", args);
export const Integration = () =>
headerStoryGenerator(mockPropsIntegration, "integration");
export const Integration = (args: any) =>
headerStoryGenerator(mockPropsIntegration, "integration", args);
export const Platform = () =>
headerStoryGenerator(mockPropsPlatform, "platform");
export const Platform = (args: any) =>
headerStoryGenerator(mockPropsPlatform, "platform", args);
export const Industries = () =>
headerStoryGenerator(mockPropsIndustries, "industries");
export const Industries = (args: any) =>
headerStoryGenerator(mockPropsIndustries, "industries", args);
export const Learning = () =>
headerStoryGenerator(mockPropsLearning, "learning");
export const Learning = (args: any) =>
headerStoryGenerator(mockPropsLearning, "learning", args);
export const Service = () => headerStoryGenerator(mockPropsService, "service");
export const Service = (args: any) =>
headerStoryGenerator(mockPropsService, "service", args);
export const Analytics = () =>
headerStoryGenerator(mockPropsAnalytics, "analytics");
export const Analytics = (args: any) =>
headerStoryGenerator(mockPropsAnalytics, "analytics", args);

@@ -6,7 +6,11 @@ import { api } from "lwc";

import { toJson } from "utils/normalizers";
import get from "lodash.get";
const TABLET_MATCH = "980px";
const MOBILE_MATCH = "880px";
const SMALL_MOBILE_MATCH = "740px";
export default class Header extends HeaderBase {
@api langValuePath: string = "id"; // allows to override how language property is interpreted, follows valuePath dropdown api.
@api

@@ -21,5 +25,29 @@ get scopedNavItems() {

@api
get languages() {
return this._languages;
}
set languages(value) {
this._languages = toJson(value);
}
@api
get language() {
return this._language;
}
set language(value) {
if (this._language !== value) {
this._language = value;
}
}
private _language: string | null = null;
private _languages!: Option[];
private _scopedNavItems!: Option[];
private smallMobile = false;
private smallMobileMatchMedia!: MediaQueryList;
private tablet = false;
private tabletMatchMedia!: MediaQueryList;
private tablet = false;

@@ -42,6 +70,24 @@ protected mobileBreakpoint(): string {

private get showBailLink(): boolean {
return this.hasBailLink && !this.hasScopedNavItems && !this.mobile;
private get hasLanguages(): boolean {
return !!(this.languages && this.languages.length);
}
private get showMobileLanguages(): boolean {
return this.smallMobile && this.hasLanguages;
}
private get languageLabel(): string {
return (
(this.language &&
this.languages.find(
(lang) => get(lang, this.langValuePath) === this.language
)?.label) ||
this.languages[0].label
);
}
private get showMenuButton(): boolean {
return this.mobile && this.hasNavItems;
}
connectedCallback(): void {

@@ -54,2 +100,11 @@ super.connectedCallback();

this.tabletMatchMedia.addEventListener("change", this.onTabletChange);
this.smallMobileMatchMedia = window.matchMedia(
`(max-width: ${SMALL_MOBILE_MATCH})`
);
this.onSmallMobileChange(this.smallMobileMatchMedia);
this.smallMobileMatchMedia.addEventListener(
"change",
this.onSmallMobileChange
);
}

@@ -63,2 +118,7 @@

);
this.smallMobileMatchMedia.removeEventListener(
"change",
this.onSmallMobileChange
);
}

@@ -69,2 +129,5 @@

private onSmallMobileChange = (e: MediaQueryListEvent | MediaQueryList) =>
(this.smallMobile = e.matches);
protected additionalClasses(): string {

@@ -76,2 +139,8 @@ return cx(

}
private onLangChange(event: CustomEvent<string>): void {
const { detail } = event;
this._language = detail;
this.dispatchEvent(new CustomEvent("langchange", { detail }));
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet