@@ -95,38 +145,40 @@ export default function InteractiveBox({ params, components, examples, onParamCh
validator={validator}
liveValidate
noHtml5Validate
- onChange={(data) => {
- onChangeHandler(data.formData);
- setDefaultFormData(data.formData);
- }}
- onSubmit={() => {log("submitted");}}
- onError={log("errors")}
- templates={{
- BaseInputTemplate,
- ArrayFieldTemplate,
- FieldErrorTemplate: () => null,
- ErrorListTemplate: () => null,
- }}
+ onChange={(data) => { onChangeHandler(data.formData); }}
+ templates={templates}
uiSchema={uiSchema}
widgets={widgets}
ref={formRef}
+ fields={fields}
>
-
-
-
>
diff --git a/src/components/ParserOpenRPC/InteractiveBox/styles.module.css b/src/components/ParserOpenRPC/InteractiveBox/styles.module.css
index f3aa2759774..5627e664e24 100644
--- a/src/components/ParserOpenRPC/InteractiveBox/styles.module.css
+++ b/src/components/ParserOpenRPC/InteractiveBox/styles.module.css
@@ -26,10 +26,14 @@
height: 100%;
padding: 12px 16px 12px 12px;
border-left: 4px solid transparent;
+ line-height: 28px;
}
.tableColumnParamFocused {
border-left: 4px solid rgba(16, 152, 252, 1);
}
+.tableColumnParamError {
+ border-left: 4px solid rgba(224, 100, 112, 1);
+}
.tableColumn:first-child {
border-right: 1px solid rgba(132, 140, 150, 1);
}
@@ -40,9 +44,10 @@
justify-content: space-between;
align-items: center;
position: relative;
+ font-size: 14px;
}
.tableValueRowPadding {
- padding: 12px 56px 12px 16px;
+ padding: 12px 72px 12px 16px;
}
.tableColumnType {
display: flex;
@@ -56,26 +61,53 @@
line-height: 24px;
font-size: 14px;
}
-.tableColumnTypeErrorIcon {
- position: absolute;
- right: 13px;
+.tableLabelIconError {
width: 11px;
height: 11px;
+ margin-left: 8px;
background: url("/img/icons/error-icon.svg") no-repeat 50% 50%;
}
-.chevronIcon {
+.tableColumnIcon {
position: absolute;
right: 13px;
width: 11px;
height: 11px;
- background: url("/img/icons/chevron-icon.svg") no-repeat 50% 50%;
}
-.chevronIcon:hover {
+.tableColumnIcon:hover {
cursor: pointer;
}
+.tableColumnIconRemove {
+ background: url("/img/icons/remove-icon.svg") no-repeat 50% 50%;
+}
+.chevronIcon {
+ background: url("/img/icons/chevron-icon.svg") no-repeat 50% 50%;
+ transition: 0.2s transform;
+}
.chevronIconDown {
transform: rotate(180deg);
}
+.chevronIconRight {
+ transform: rotate(90deg);
+}
+.chevronIcon:hover {
+ cursor: pointer;
+}
+.deleteIcon {
+ position: absolute;
+ transform: translateY(-50%);
+ right: 12px;
+ width: 14px;
+ height: 14px;
+ margin-top: -1px;
+ cursor: pointer;
+ background: url("/img/icons/delete-icon.svg") no-repeat 50% 50%;
+}
+.deleteIconCentered {
+ top: 50%;
+}
+.deleteIconComplex {
+ top: 27px;
+}
.dropdown {
display: flex;
align-items: center;
@@ -92,7 +124,7 @@
.dropdownList {
position: absolute;
right: 0;
- opacity: 1;
+ visibility: visible;
list-style: none;
border-radius: 10px;
padding: 0;
@@ -100,19 +132,20 @@
top: 35px;
overflow: hidden;
border: 1px solid rgba(132, 140, 150, 1);
- transition: 0.4s opacity;
+ z-index: 2;
}
.dropdownListClosed {
- opacity: 0;
+ visibility: hidden;
}
.dropdownList li + li {
margin-top: 0;
}
.dropdownItem {
- width: 102px;
+ width: 100%;
padding: 16px;
background-color: rgba(36, 39, 42, 1);
color: #FFFFFF;
+ white-space: nowrap;
}
.dropdownItem:hover {
background-color: rgba(20, 22, 24, 1);
@@ -124,7 +157,8 @@
.tableFooterRow {
position: fixed;
display: flex;
- padding: 21px 16px;
+ justify-content: space-between;
+ padding: 16px;
width: 100%;
bottom: 0;
}
@@ -134,6 +168,33 @@
.tableFooterRowLight {
background-color: #F2F4F6;
}
+.tableButton {
+ display: flex;
+ background: none;
+ border: none;
+}
+.tableButtonAddNewArray {
+ margin: 08px 0 8px 16px;
+ padding: 8px 0;
+ color: rgba(16, 152, 252, 1);
+}
+.tableButtonAddArrayItemName {
+ margin-left: 8px;
+ font-size: 14px;
+ font-weight: 500;
+}
+.tableComplexType {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 332px;
+ background-color: #292A36;
+ overflow-y: scroll;
+ z-index: 1;
+}
+.tableComplexTypeItem {
+ position: relative;
+}
.formControl {
width: 100%;
padding: 12px 72px 12px 16px;
@@ -165,10 +226,14 @@
}
.footerButtons {
display: flex;
+}
+.footerButtonsLeft {
width: 48px;
+ align-items: center;
justify-content: space-between;
+ padding: 6px 0;
}
-.footerButton {
+.footerButtonLeft {
display: flex;
width: 16px;
height: 22px;
@@ -178,21 +243,22 @@
border: none;
border-radius: 0;
}
-.footerButton:hover {
- cursor: pointer;
+.footerButtonRight {
+ padding: 5px 16px!important;
+}
+.footerButtonRightOutline {
+ margin-right: 16px;
}
.footerButtonIcon {
width: 100%;
border-radius: 0;
}
-
.arrayParentRow {
position: relative;
width: 100%;
height: 100%;
padding: 12px 72px 12px 16px;
}
-
.arrayColumnType {
position: absolute;
top: 0;
@@ -205,13 +271,13 @@
font-size: 14px;
cursor: pointer;
}
-
.arrayFormDataWrap {
+ display: block;
+ max-width: 395px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
-
.addItemBtnWrap {
min-height: 52px;
display: flex;
@@ -219,7 +285,6 @@
padding: 12px;
border-bottom: 1px solid rgba(132, 140, 150, 1);
}
-
.addItemBtn {
display: flex;
align-items: center;
@@ -232,7 +297,6 @@
line-height: 1;
cursor: pointer;
}
-
.addItemIcon {
display: inline-flex;
align-items: center;
@@ -246,7 +310,6 @@
line-height: 1;
margin-right: 10px;
}
-
.arrayItemIcon {
position: absolute;
top: 50%;
@@ -256,21 +319,8 @@
line-height: 1;
font-weight: bold;
}
-
.arrayItemRowWrap {
position: relative;
padding-left: 40px;
border-bottom: 1px dashed #848C96;
}
-
-.deleteIcon {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- right: 12px;
- width: 14px;
- height: 14px;
- margin-top: -1px;
- cursor: pointer;
- background: url("/img/icons/delete-icon.svg") no-repeat 50% 50%;
-}
\ No newline at end of file
diff --git a/src/components/ParserOpenRPC/InteractiveBox/templates/ArrayFieldTemplate.tsx b/src/components/ParserOpenRPC/InteractiveBox/templates/ArrayFieldTemplate.tsx
index b3fc3f982f1..b0e18bf64b7 100644
--- a/src/components/ParserOpenRPC/InteractiveBox/templates/ArrayFieldTemplate.tsx
+++ b/src/components/ParserOpenRPC/InteractiveBox/templates/ArrayFieldTemplate.tsx
@@ -1,79 +1,114 @@
-import React from "react";
+import React, { useContext, useState } from "react";
import { useCollapsible, Collapsible } from "@docusaurus/theme-common";
import { ArrayFieldTemplateProps } from "@rjsf/utils";
import { BaseInputTemplate } from "@site/src/components/ParserOpenRPC/InteractiveBox/templates/BaseInputTemplate";
-import clsx from "clsx";
import styles from "@site/src/components/ParserOpenRPC/InteractiveBox/styles.module.css";
+import clsx from "clsx";
+import { ParserOpenRPCContext } from "@site/src/components/ParserOpenRPC";
-export const ArrayFieldTemplate = ({
- title,
- formData,
- items,
- canAdd,
- onAddClick
-}: ArrayFieldTemplateProps) => {
+export const ArrayFieldTemplate = ({ items, canAdd, onAddClick, title, schema, formData, formContext }: ArrayFieldTemplateProps) => {
+ const [isComplexArrayEditView, setIsComplexArrayEditView] = useState(false);
+ const { setIsDrawerContentFixed, setDrawerLabel, isComplexTypeView, setIsComplexTypeView } = useContext(ParserOpenRPCContext);
const { collapsed, toggleCollapsed } = useCollapsible({ initialState: true });
+ const itemsType = schema?.items?.type;
+ const isSimpleArray = itemsType === "string" || itemsType === "boolean" || itemsType === "number" || itemsType === "integer";
+ const addComplexArray = () => {
+ onAddClick();
+ setDrawerLabel(title);
+ setIsDrawerContentFixed(true);
+ setIsComplexArrayEditView(true);
+ setIsComplexTypeView(true);
+ }
+
return (
- <>
+
-
+
-
+
{JSON.stringify(formData, null, " ")}
-
- array
-
+
+
+ {schema.type}
+
-
- <>
- {items.map((el, i) => {
- const props = {
- ...el.children.props,
- isArray: true
- }
- const { index, hasRemove, onDropIndexClick, schema } = el;
- const isNumber = schema.type === "number" || schema.type === "integer";
- return (
-
-
{i+1}
-
- {hasRemove && (
-
+ {isComplexTypeView && isComplexArrayEditView && !isSimpleArray ?
+
+ {items.map(({ children, index, onDropIndexClick, hasRemove }) => (
+
+ {children}
+ {hasRemove && (
+
+
+ )}
+
+ ))}
+ {canAdd ?
+
+
+ Add {title}
+ :
+ null
+ }
+
:
+
+ <>
+ {items.map((el, i) => {
+ const baseInputTemplateProps = {
+ ...el.children.props,
+ isArray: true,
+ value: formData,
+ }
+ const { index, hasRemove, onDropIndexClick, schema } = el;
+ const isNumber = schema.type === "number" || schema.type === "integer";
+ return (
+
+ {i+1}
+
+ {hasRemove && (
+
- )}
+ )}
+
+ )
+ })}
+ {canAdd && (
+
+
+ +
+ Add array item
+
- )
- })}
- {canAdd && (
-
-
- +
- Add array item
-
-
- )}
- >
-
- >
+ )}
+ >
+
+ }
+
);
-};
+}
diff --git a/src/components/ParserOpenRPC/InteractiveBox/templates/BaseInputTemplate.tsx b/src/components/ParserOpenRPC/InteractiveBox/templates/BaseInputTemplate.tsx
index 358aadf6142..be8eef24c90 100644
--- a/src/components/ParserOpenRPC/InteractiveBox/templates/BaseInputTemplate.tsx
+++ b/src/components/ParserOpenRPC/InteractiveBox/templates/BaseInputTemplate.tsx
@@ -10,18 +10,18 @@ interface ExtendedInputProps extends BaseInputTemplateProps {
}
export const BaseInputTemplate = ({
- schema,
- id,
- name,
- value = "",
- disabled,
- onChange,
- rawErrors,
- hideError,
- required,
- formContext,
- isArray
-}: ExtendedInputProps) => {
+ schema,
+ id,
+ name,
+ value = "",
+ disabled,
+ onChange,
+ rawErrors,
+ hideError,
+ required,
+ formContext,
+ isArray
+ }: ExtendedInputProps) => {
const isNumber = schema.type === "number" || schema.type === "integer";
const [isFocused, setIsFocused] = useState(false);
const [inputValue, setInputValue] = useState(isNumber ? 0 : "");
@@ -52,8 +52,9 @@ export const BaseInputTemplate = ({
{!isArray && (
-
)}
@@ -73,15 +74,14 @@ export const BaseInputTemplate = ({
/>
{schema.type}
- {hasErrors && !isNumber ? : null}
{isNumber ? (
<>
{ onInputNumberChange(Number((+inputValue || 0) + 1)); }}
/>
{ inputValue >= 1 && onInputNumberChange(Number((+inputValue || 0) - 1)); }}
/>
>
diff --git a/src/components/ParserOpenRPC/InteractiveBox/widgets/DropdownWidget.tsx b/src/components/ParserOpenRPC/InteractiveBox/widgets/DropdownWidget.tsx
index aa0a50afac0..0c7e3842920 100644
--- a/src/components/ParserOpenRPC/InteractiveBox/widgets/DropdownWidget.tsx
+++ b/src/components/ParserOpenRPC/InteractiveBox/widgets/DropdownWidget.tsx
@@ -17,6 +17,7 @@ export const DropdownWidget = ({ name, value, onChange, schema, options }: Widge
{ setIsOpened(!isOpened); }}>
{schema.type}
+
diff --git a/src/components/ParserOpenRPC/InteractiveBox/widgets/SelectWidget.tsx b/src/components/ParserOpenRPC/InteractiveBox/widgets/SelectWidget.tsx
new file mode 100644
index 00000000000..029e6b3e912
--- /dev/null
+++ b/src/components/ParserOpenRPC/InteractiveBox/widgets/SelectWidget.tsx
@@ -0,0 +1,43 @@
+import React, { useState } from "react";
+import { WidgetProps } from "@rjsf/utils";
+import clsx from "clsx";
+import styles from "@site/src/components/ParserOpenRPC/InteractiveBox/styles.module.css";
+
+export const SelectWidget = ({ value, onChange, schema, options, label }: WidgetProps) => {
+ const [isOpened, setIsOpened] = useState(false);
+ const emptyValue = value === undefined || !options?.enumOptions.some(({ label }) => label === value);
+
+ return (
+
+
+ {label}
+
+
+
+ {emptyValue ? "" : String(value)}
+
+ { setIsOpened(!isOpened); }}>
+ {schema?.enum ? 'enum' : schema?.type}
+
+
+
+
+ {options?.enumOptions?.map(({ label, value }, index) => (
+ - {
+ onChange(value);
+ setIsOpened(false);
+ }}
+ >
+ {String(label)}
+
+ ))}
+
+
+
+
+
+ );
+};
diff --git a/src/components/ParserOpenRPC/ModalDrawer/index.tsx b/src/components/ParserOpenRPC/ModalDrawer/index.tsx
index cd70e29b3c1..16208dab86a 100644
--- a/src/components/ParserOpenRPC/ModalDrawer/index.tsx
+++ b/src/components/ParserOpenRPC/ModalDrawer/index.tsx
@@ -1,30 +1,45 @@
-import React, { useState, useEffect } from "react";
+import React, {useState, useEffect, useRef} from "react";
import clsx from "clsx";
import { useColorMode } from "@docusaurus/theme-common";
import styles from "./styles.module.css";
interface ModalDrawerProps {
- title: string;
+ title: string | React.ReactNode;
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
+ isContentFixed?: boolean;
+ headerLabel?: string | null;
}
-export const ModalDrawer = ({ title, isOpen, onClose, children }: ModalDrawerProps) => {
+export const ModalDrawer = ({ title, isOpen, onClose, children, isContentFixed = false, headerLabel }: ModalDrawerProps) => {
const [showModal, setShowModal] = useState(isOpen);
+ const contentRef = useRef(null);
const { colorMode } = useColorMode();
useEffect(() => {
setShowModal(isOpen);
}, [isOpen]);
+ useEffect(() => {
+ if (isContentFixed && contentRef?.current) {
+ contentRef?.current?.scrollTo(0, 0);
+ }
+ }, [isContentFixed]);
+
return (
-
{title}
+
+ {title}
+ {headerLabel ? {headerLabel} : null}
+
×
-
diff --git a/src/components/ParserOpenRPC/ModalDrawer/styles.module.css b/src/components/ParserOpenRPC/ModalDrawer/styles.module.css
index faf662cc29f..4fcd5412374 100644
--- a/src/components/ParserOpenRPC/ModalDrawer/styles.module.css
+++ b/src/components/ParserOpenRPC/ModalDrawer/styles.module.css
@@ -41,6 +41,40 @@
font-weight: 500;
}
+.modalTitleContainer {
+ display: flex;
+ align-items: center;
+}
+
+.modalHeaderIcon {
+ display: flex;
+ background: none;
+ border: none;
+ padding: 0;
+ margin-right: 8px;
+}
+
+.modalHeaderIconBack {
+ width: 16px;
+ height: 16px;
+}
+
+.modalHeaderLabels {
+ display: flex;
+ align-items: center;
+}
+
+.modalHeaderLabel {
+ display: flex;
+ justify-content: center;
+ margin-left: 8px;
+ padding: 2px 8px;
+ border: 1px solid #848C96;
+ border-radius: 999px;
+ font-size: 12px;
+ line-height: 18px;
+}
+
.modalCloseBtn {
display: block;
padding: 0;
@@ -53,10 +87,17 @@
.modalContent {
height: 394px;
+}
+
+.modalContentScrolled {
overflow-y: auto;
}
-@media (width <= 1200px) {
+.modalContentFixed {
+ overflow-y: hidden;
+}
+
+@media (width <= 996px) {
.modalContainer {
position: fixed;
left: 0;
diff --git a/src/components/ParserOpenRPC/Tooltip/Tooltip.module.css b/src/components/ParserOpenRPC/Tooltip/Tooltip.module.css
index 5f0553c5c4c..f899638b910 100644
--- a/src/components/ParserOpenRPC/Tooltip/Tooltip.module.css
+++ b/src/components/ParserOpenRPC/Tooltip/Tooltip.module.css
@@ -1,6 +1,5 @@
.tooltipContainer {
max-width: 180px;
- max-height: 60px;
font-size: 16px;
}
.tooltipContainer:first-letter {
diff --git a/src/components/ParserOpenRPC/Tooltip/index.tsx b/src/components/ParserOpenRPC/Tooltip/index.tsx
index 510e4688ef2..40348046f92 100644
--- a/src/components/ParserOpenRPC/Tooltip/index.tsx
+++ b/src/components/ParserOpenRPC/Tooltip/index.tsx
@@ -7,14 +7,12 @@ interface TooltipProps {
children: ReactNode;
message: string;
disabled?: boolean;
- theme?: "light" | "dark";
}
-export const Tooltip = ({ children, message, disabled, theme = "light" }: TooltipProps) => (
+export const Tooltip = ({ children, message, disabled }: TooltipProps) => (
{message}
)}
@@ -23,4 +21,4 @@ export const Tooltip = ({ children, message, disabled, theme = "light" }: Toolti
>
{children}
-);
+)
diff --git a/src/components/ParserOpenRPC/global.module.css b/src/components/ParserOpenRPC/global.module.css
index b90a9d70f52..cbf763225ff 100644
--- a/src/components/ParserOpenRPC/global.module.css
+++ b/src/components/ParserOpenRPC/global.module.css
@@ -24,7 +24,7 @@
text-decoration: none;
color: #141618;
background-color: #26A2FC;
- box-shadow: 0px 2px 8px 0px rgba(16, 152, 252, 0.40);
+ box-shadow: 0 2px 8px 0 rgba(16, 152, 252, 0.40);
}
.primaryBtn:disabled {
@@ -35,6 +35,31 @@
box-shadow: none;
}
+.secondaryBtn {
+ background: none;
+ border-radius: 999px;
+ outline: none;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 22px;
+ border: 1px solid rgba(3, 118, 201, 1);
+ color: rgba(3, 118, 201, 1);
+}
+
+.secondaryBtn:hover {
+ text-decoration: none;
+ color: #141618;
+ background-color: #26A2FC;
+ box-shadow: 0 2px 8px 0 rgba(16, 152, 252, 0.40);
+}
+
+.secondaryBtn:disabled {
+ cursor: not-allowed;
+ text-decoration: none;
+ box-shadow: none;
+ opacity: 0.5;
+}
+
.linkBtn {
background: none;
border: 0;
diff --git a/src/components/ParserOpenRPC/index.tsx b/src/components/ParserOpenRPC/index.tsx
index c053e044408..7bcdad5729b 100644
--- a/src/components/ParserOpenRPC/index.tsx
+++ b/src/components/ParserOpenRPC/index.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useState, useEffect } from "react";
+import React, { createContext, useEffect, useMemo, useState } from 'react'
import { usePluginData } from "@docusaurus/useGlobalData";
import { ResponseItem, NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc";
import DetailsBox from "@site/src/components/ParserOpenRPC/DetailsBox";
@@ -8,18 +8,34 @@ import RequestBox from "@site/src/components/ParserOpenRPC/RequestBox";
import ErrorsBox from "@site/src/components/ParserOpenRPC/ErrorsBox";
import { ModalDrawer } from "@site/src/components/ParserOpenRPC/ModalDrawer";
import global from "./global.module.css";
+import modalDrawerStyles from "./ModalDrawer/styles.module.css";
+import clsx from "clsx";
+import { useColorMode } from "@docusaurus/theme-common";
interface ParserProps {
network: NETWORK_NAMES;
method?: string;
}
+interface ParserOpenRPCContextProps {
+ setIsDrawerContentFixed?: (isFixed: boolean) => void
+ setDrawerLabel?: (label: string) => void;
+ isComplexTypeView: boolean;
+ setIsComplexTypeView: (isComplexTypeView: boolean) => void;
+}
+
+export const ParserOpenRPCContext = createContext(null)
+
export default function ParserOpenRPC({ network, method }: ParserProps) {
if (!method || !network) return null;
const [metamaskInstalled, setMetamaskInstalled] = useState(false);
const [isModalOpen, setModalOpen] = useState(false);
const [reqResult, setReqResult] = useState(null);
const [paramsData, setParamsData] = useState([]);
+ const [isDrawerContentFixed, setIsDrawerContentFixed] = useState(false);
+ const [drawerLabel, setDrawerLabel] = useState(null);
+ const [isComplexTypeView, setIsComplexTypeView] = useState(false);
+ const { colorMode } = useColorMode();
const openModal = () => setModalOpen(true);
const closeModal = () => setModalOpen(false);
@@ -80,50 +96,81 @@ export default function ParserOpenRPC({ network, method }: ParserProps) {
setReqResult(response);
} catch (e) {
setReqResult(e);
- };
+ }
};
+ const closeComplexTypeView = () => {
+ setIsComplexTypeView(false);
+ setIsDrawerContentFixed(false);
+ setDrawerLabel(null);
+ }
+
+ const onModalClose = () => {
+ closeModal();
+ closeComplexTypeView();
+ }
+
return (
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ Editing Param
+
+ :
+ "Customize request"}
+ isOpen={isModalOpen}
+ onClose={onModalClose}
+ isContentFixed={isDrawerContentFixed}
+ headerLabel={drawerLabel ? drawerLabel : null}
+ >
+
+
-
-
-
-
-
+
);
}
\ No newline at end of file
diff --git a/src/css/custom.css b/src/css/custom.css
index c0ce063a4fe..7307122adda 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -293,7 +293,38 @@ html[data-theme="light"] .api-card:hover {
transition: all 0.3s;
}
+form {
+ position: relative;
+}
+
fieldset {
- border: 0;
+ border: none;
padding: 0;
-}
\ No newline at end of file
+ margin: 0;
+}
+
+fieldset#root {
+ position: relative;
+ padding-bottom: 10px;
+}
+
+button:hover {
+ cursor: pointer;
+}
+
+[data-theme="light"] .tippy-tooltip {
+ background-color: rgba(20, 22, 24, 1);
+}
+
+[data-theme="light"] .tippy-popper[x-placement^=top] [x-arrow] {
+ border-top-color: rgba(20, 22, 24, 1);
+}
+
+[data-theme="dark"] .tippy-tooltip {
+ background-color: rgba(255, 255, 255, 1);
+ color: rgba(20, 22, 24, 1);
+}
+
+[data-theme="dark"] .tippy-popper[x-placement^=top] [x-arrow] {
+ border-top-color: rgba(255, 255, 255, 1);
+}
diff --git a/static/img/icons/chevron-left-dark-icon.svg b/static/img/icons/chevron-left-dark-icon.svg
new file mode 100644
index 00000000000..bb1932ab02c
--- /dev/null
+++ b/static/img/icons/chevron-left-dark-icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/static/img/icons/chevron-left-light-icon.svg b/static/img/icons/chevron-left-light-icon.svg
new file mode 100644
index 00000000000..7bc727bf07f
--- /dev/null
+++ b/static/img/icons/chevron-left-light-icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/static/img/icons/plus-icon.svg b/static/img/icons/plus-icon.svg
new file mode 100644
index 00000000000..a1b01bb2bb1
--- /dev/null
+++ b/static/img/icons/plus-icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/static/img/icons/remove-icon.svg b/static/img/icons/remove-icon.svg
new file mode 100644
index 00000000000..eee1c47bfd1
--- /dev/null
+++ b/static/img/icons/remove-icon.svg
@@ -0,0 +1,3 @@
+