Skip to content

Commit

Permalink
feat(ImageBase): create ImageBase
Browse files Browse the repository at this point in the history
  • Loading branch information
inomdzhon committed Sep 5, 2022
1 parent 76c484f commit ae00ed7
Show file tree
Hide file tree
Showing 10 changed files with 673 additions and 0 deletions.
128 changes: 128 additions & 0 deletions src/components/ImageBase/ImageBase.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
.ImageBase {
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-sizing: border-box;
color: var(--vkui--color_icon_secondary);
background-color: var(--vkui--color_background);
background-size: cover;
box-shadow: inset 0 0 0 var(--thin-border)
var(--vkui--color_image_border_alpha);
}

.ImageBase__img {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
border: none;
border-radius: inherit;
object-fit: cover;
visibility: hidden;
}

.ImageBase--loaded .ImageBase__img {
visibility: visible;
}

.ImageBase__badge {
right: 0;
bottom: 0;
}

.ImageBase__badge--shift {
right: -2px;
bottom: -2px;
}

/**
* CMP:
* CellButton
*/
.CellButton > .ImageBase .Icon {
color: var(--vkui--color_icon_accent);
}

.CellButton--danger > .ImageBase .Icon {
color: var(--vkui--color_icon_negative);
}

/**
* CMP:
* PanelHeader
*/
.PanelHeader__before .ImageBase {
margin-left: 8px;
}

.PanelHeader__after .ImageBase {
margin-right: 8px;
}

/**
* CMP:
* SimpleCell
*/
.SimpleCell > .ImageBase {
margin-right: 12px;
}

.SimpleCell > .ImageBase--sz-28,
.SimpleCell > .ImageBase--sz-32 {
margin-top: 10px;
margin-bottom: 10px;
}

.SimpleCell > .ImageBase--sz-40 {
margin-top: 4px;
margin-bottom: 4px;
}

.SimpleCell > .ImageBase--sz-48,
.SimpleCell > .ImageBase--sz-72 {
margin-top: 6px;
margin-bottom: 6px;
}

.SimpleCell--ios > .ImageBase--sz-28,
.SimpleCell--ios > .ImageBase--sz-32 {
margin-left: 4px;
}

.SimpleCell--sizeY-compact > .ImageBase--sz-28,
.SimpleCell--sizeY-compact > .ImageBase--sz-32 {
margin-top: 8px;
margin-bottom: 8px;
}

.SimpleCell--sizeY-compact > .ImageBase--sz-40 {
margin-top: 2px;
margin-bottom: 2px;
}

.SimpleCell--sizeY-compact > .ImageBase--sz-48 {
margin-top: 4px;
margin-bottom: 4px;
}

@media (--sizeY-compact) {
.SimpleCell--sizeY-none > .ImageBase--sz-28,
.SimpleCell--sizeY-none > .ImageBase--sz-32 {
margin-top: 8px;
margin-bottom: 8px;
}

.SimpleCell--sizeY-none > .ImageBase--sz-40 {
margin-top: 2px;
margin-bottom: 2px;
}

.SimpleCell--sizeY-none > .ImageBase--sz-48 {
margin-top: 4px;
margin-bottom: 4px;
}
}
119 changes: 119 additions & 0 deletions src/components/ImageBase/ImageBase.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as React from "react";
import "@testing-library/jest-dom/extend-expect";
import { render, screen } from "@testing-library/react";
import { baselineComponent, imgOnlyAttributes } from "../../testing/utils";
import { ImageBase, ImageBaseProps } from "./ImageBase";
import { Icon20GiftCircleFillRed as Icon20GiftCircleFillRedLib } from "@vkontakte/icons";

const TEST_LOCATORS = {
HOST: {
id: "image-base",
},
ICON: {
id: "test-icon",
get selector() {
return `[data-testid="${this.id}"]`;
},
},
};

const ImageBaseTest = (props: ImageBaseProps) => (
<ImageBase {...props} data-testid={TEST_LOCATORS.HOST.id} />
);

const Icon20GiftCircleFillRedTest = (
props: React.ComponentProps<typeof Icon20GiftCircleFillRedLib>
) => {
return (
<Icon20GiftCircleFillRedLib
{...props}
data-testid={TEST_LOCATORS.ICON.id}
/>
);
};

const imageBase = () => screen.getByTestId(TEST_LOCATORS.HOST.id);
const img = () => imageBase().querySelector("img");

describe("ImageBase", () => {
baselineComponent(ImageBase);

describe("Image", () => {
it("Renders img if src is passed", () => {
render(<ImageBaseTest src="#" />);

expect(img()).toBeInTheDocument();
});

it("Does not render img if there is no src", () => {
render(<ImageBaseTest />);

expect(img()).not.toBeInTheDocument();
});

it("Show fallback icon if there is no src", () => {
render(<ImageBaseTest FallbackIcon={Icon20GiftCircleFillRedTest} />);

expect(
imageBase().querySelector(TEST_LOCATORS.ICON.selector)
).toBeInTheDocument();
});

it("Show children instead fallback icon if there is no src", () => {
const CHILDREN = "42";
render(
<ImageBaseTest FallbackIcon={Icon20GiftCircleFillRedTest}>
{CHILDREN}
</ImageBaseTest>
);

expect(imageBase()).toHaveTextContent(CHILDREN);
expect(
imageBase().querySelector(TEST_LOCATORS.ICON.selector)
).not.toBeInTheDocument();
});

it("Passes ref to img", () => {
const refCallback = jest.fn();
render(<ImageBaseTest src="#" getRef={refCallback} />);

expect(refCallback).toBeCalled();
});

it("Passes all img attributes to img", () => {
render(<ImageBaseTest {...imgOnlyAttributes} />);

Object.keys(imgOnlyAttributes).forEach((attr) => {
expect(img()).toHaveAttribute(attr);
});
});
});

describe("Badge", () => {
it("Renders badge if passed", () => {
render(<ImageBaseTest badge={{ Icon: Icon20GiftCircleFillRedTest }} />);

expect(
imageBase().querySelector(TEST_LOCATORS.ICON.selector)
).toBeInTheDocument();
});

it("Doesn't render badge if not passed", () => {
render(<ImageBaseTest />);

expect(
imageBase().querySelector(TEST_LOCATORS.ICON.selector)
).not.toBeInTheDocument();
});
});

describe("Overlay", () => {
it("Renders overlay icon if passed", () => {
render(<ImageBaseTest overlay={{ Icon: Icon20GiftCircleFillRedTest }} />);

expect(
imageBase().querySelector(TEST_LOCATORS.ICON.selector)
).toBeInTheDocument();
});
});
});
Loading

0 comments on commit ae00ed7

Please sign in to comment.