[WIP] UI for item remove button
It's code for a remove button in item lists! When you click it, you see a "TODO" alert. Not shipping this change until it's wired up!
This commit is contained in:
parent
818a443dfe
commit
64db3dd1b7
2 changed files with 109 additions and 28 deletions
|
@ -408,6 +408,7 @@ export function ClosetListContents({
|
||||||
{itemsToShow.length > 0 ? (
|
{itemsToShow.length > 0 ? (
|
||||||
<ClosetItemList
|
<ClosetItemList
|
||||||
items={itemsToShow}
|
items={itemsToShow}
|
||||||
|
canEdit={isCurrentUser}
|
||||||
tradeMatchingMode={tradeMatchingMode}
|
tradeMatchingMode={tradeMatchingMode}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -446,12 +447,12 @@ export function ClosetListContents({
|
||||||
const ITEM_CARD_WIDTH = 112 + 16;
|
const ITEM_CARD_WIDTH = 112 + 16;
|
||||||
const ITEM_CARD_HEIGHT = 171 + 16;
|
const ITEM_CARD_HEIGHT = 171 + 16;
|
||||||
|
|
||||||
function ClosetItemList({ items, tradeMatchingMode }) {
|
function ClosetItemList({ items, canEdit, tradeMatchingMode }) {
|
||||||
const renderItem = (item) => (
|
const renderItem = (item) => (
|
||||||
<ItemCard
|
<ClosetListItemCard
|
||||||
key={item.id}
|
key={item.id}
|
||||||
item={item}
|
item={item}
|
||||||
variant="grid"
|
canEdit={canEdit}
|
||||||
tradeMatchingMode={tradeMatchingMode}
|
tradeMatchingMode={tradeMatchingMode}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -521,6 +522,19 @@ function ClosetItemList({ items, tradeMatchingMode }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ClosetListItemCard({ item, canEdit, tradeMatchingMode }) {
|
||||||
|
return (
|
||||||
|
<ItemCard
|
||||||
|
key={item.id}
|
||||||
|
item={item}
|
||||||
|
variant="grid"
|
||||||
|
tradeMatchingMode={tradeMatchingMode}
|
||||||
|
showRemoveButton={canEdit}
|
||||||
|
onRemove={() => alert("TODO")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function buildClosetListPath(closetList) {
|
export function buildClosetListPath(closetList) {
|
||||||
let ownsOrWants;
|
let ownsOrWants;
|
||||||
if (closetList.ownsOrWantsItems === "OWNS") {
|
if (closetList.ownsOrWantsItems === "OWNS") {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
|
IconButton,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
useTheme,
|
useTheme,
|
||||||
|
@ -10,15 +11,18 @@ import { ClassNames } from "@emotion/react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { safeImageUrl, useCommonStyles } from "../util";
|
import { safeImageUrl, useCommonStyles } from "../util";
|
||||||
import { CheckIcon, StarIcon } from "@chakra-ui/icons";
|
import { CheckIcon, CloseIcon, StarIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
function SquareItemCard({
|
function SquareItemCard({
|
||||||
item,
|
item,
|
||||||
|
showRemoveButton = false,
|
||||||
|
onRemove = () => {},
|
||||||
tradeMatchingMode = null,
|
tradeMatchingMode = null,
|
||||||
footer = null,
|
footer = null,
|
||||||
...props
|
...props
|
||||||
}) {
|
}) {
|
||||||
const outlineShadowValue = useToken("shadows", "outline");
|
const outlineShadowValue = useToken("shadows", "outline");
|
||||||
|
const mdRadiusValue = useToken("radii", "md");
|
||||||
|
|
||||||
const tradeMatchOwnShadowColor = useColorModeValue("green.500", "green.200");
|
const tradeMatchOwnShadowColor = useColorModeValue("green.500", "green.200");
|
||||||
const tradeMatchWantShadowColor = useColorModeValue("blue.400", "blue.200");
|
const tradeMatchWantShadowColor = useColorModeValue("blue.400", "blue.200");
|
||||||
|
@ -46,33 +50,70 @@ function SquareItemCard({
|
||||||
// SquareItemCard renders in large lists of 1k+ items, so we get a big
|
// SquareItemCard renders in large lists of 1k+ items, so we get a big
|
||||||
// perf win by using Emotion directly instead of Chakra's styled-system
|
// perf win by using Emotion directly instead of Chakra's styled-system
|
||||||
// Box.
|
// Box.
|
||||||
<Link
|
<div
|
||||||
to={`/items/${item.id}`}
|
|
||||||
className={css`
|
className={css`
|
||||||
transition: all 0.2s;
|
position: relative;
|
||||||
&:hover,
|
display: flex;
|
||||||
&:focus {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
&:focus {
|
|
||||||
box-shadow: ${outlineShadowValue};
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
`}
|
`}
|
||||||
{...props}
|
role="group"
|
||||||
>
|
>
|
||||||
<SquareItemCardLayout
|
<Link
|
||||||
name={item.name}
|
to={`/items/${item.id}`}
|
||||||
thumbnailImage={
|
className={css`
|
||||||
<ItemThumbnail
|
border-radius: ${mdRadiusValue};
|
||||||
item={item}
|
transition: all 0.2s;
|
||||||
tradeMatchingMode={tradeMatchingMode}
|
&:hover,
|
||||||
/>
|
&:focus {
|
||||||
}
|
transform: scale(1.05);
|
||||||
boxShadow={tradeMatchShadow}
|
}
|
||||||
footer={footer}
|
&:focus {
|
||||||
/>
|
box-shadow: ${outlineShadowValue};
|
||||||
</Link>
|
outline: none;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<SquareItemCardLayout
|
||||||
|
name={item.name}
|
||||||
|
thumbnailImage={
|
||||||
|
<ItemThumbnail
|
||||||
|
item={item}
|
||||||
|
tradeMatchingMode={tradeMatchingMode}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
removeButton={
|
||||||
|
showRemoveButton ? (
|
||||||
|
<SquareItemCardRemoveButton onClick={onRemove} />
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
boxShadow={tradeMatchShadow}
|
||||||
|
footer={footer}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
{showRemoveButton && (
|
||||||
|
<div
|
||||||
|
className={css`
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
transform: translate(50%, -50%);
|
||||||
|
/* Apply some padding, so accidental clicks around the button
|
||||||
|
* don't click the link instead, or vice-versa! */
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
[role="group"]:hover &,
|
||||||
|
[role="group"]:focus-within &,
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<SquareItemCardRemoveButton onClick={onRemove} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</ClassNames>
|
</ClassNames>
|
||||||
);
|
);
|
||||||
|
@ -363,6 +404,32 @@ function ItemThumbnailKindBadge({ colorScheme, children }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SquareItemCardRemoveButton({ onClick }) {
|
||||||
|
const backgroundColor = useColorModeValue("gray.200", "gray.500");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
aria-label="Remove"
|
||||||
|
title="Remove"
|
||||||
|
icon={<CloseIcon />}
|
||||||
|
size="xs"
|
||||||
|
borderRadius="full"
|
||||||
|
boxShadow="lg"
|
||||||
|
backgroundColor={backgroundColor}
|
||||||
|
onClick={onClick}
|
||||||
|
_hover={{
|
||||||
|
// Override night mode's fade-out on hover
|
||||||
|
opacity: 1,
|
||||||
|
transform: "scale(1.15, 1.15)",
|
||||||
|
}}
|
||||||
|
_focus={{
|
||||||
|
transform: "scale(1.15, 1.15)",
|
||||||
|
boxShadow: "outline",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function SquareItemCardSkeleton({ minHeightNumLines, footer = null }) {
|
export function SquareItemCardSkeleton({ minHeightNumLines, footer = null }) {
|
||||||
return (
|
return (
|
||||||
<SquareItemCardLayout
|
<SquareItemCardLayout
|
||||||
|
|
Loading…
Reference in a new issue