Skip to content

Commit 3159df9

Browse files
authored
[Woo POS][Design System] Update product card & image placeholder design (#15089)
2 parents 07b4d13 + 1efcfa4 commit 3159df9

File tree

11 files changed

+90
-70
lines changed

11 files changed

+90
-70
lines changed

WooCommerce/Classes/POS/Presentation/CartView.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ struct CartView: View {
77

88
@Environment(\.floatingControlAreaSize) var floatingControlAreaSize: CGSize
99
@Environment(\.dynamicTypeSize) var dynamicTypeSize
10-
@Environment(\.colorScheme) var colorScheme
1110

1211
@State private var offSetPosition: CGFloat = 0.0
1312
private var coordinateSpace: CoordinateSpace = .named(Constants.scrollViewCoordinateSpaceIdentifier)
@@ -36,7 +35,7 @@ struct CartView: View {
3635
if let itemsInCartLabel = viewHelper.itemsInCartLabel(for: posModel.cart.count) {
3736
Text(itemsInCartLabel)
3837
.font(Constants.itemsFont)
39-
.foregroundColor(Color.posSecondaryText)
38+
.foregroundColor(Color.posOnSurfaceVariantLowest)
4039
}
4140
}
4241
.accessibilityElement(children: .combine)
@@ -262,7 +261,7 @@ private extension CartView {
262261
} label: {
263262
Image(systemName: Constants.backButtonSymbol)
264263
.font(.posBodyEmphasized, maximumContentSizeCategory: .accessibilityLarge)
265-
.foregroundColor(.primary)
264+
.foregroundColor(.posOnSurface)
266265
}
267266
}
268267
}
@@ -309,4 +308,19 @@ private extension CartView {
309308
return CartView()
310309
.environment(posModel)
311310
}
311+
312+
@available(iOS 17.0, *)
313+
#Preview("Cart with one item") {
314+
let posModel = PointOfSaleAggregateModel(
315+
itemsController: PointOfSalePreviewItemsController(),
316+
cardPresentPaymentService: CardPresentPaymentPreviewService(),
317+
orderController: PointOfSalePreviewOrderController())
318+
posModel.addToCart(.simpleProduct(.init(id: UUID(),
319+
name: "Sample Product",
320+
formattedPrice: "$10.00",
321+
productID: 6,
322+
price: "10")))
323+
return CartView()
324+
.environment(posModel)
325+
}
312326
#endif

WooCommerce/Classes/POS/Presentation/Item Selector/ChildItemList.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private extension ChildItemList {
5151
} label: {
5252
Image(systemName: "chevron.backward")
5353
.font(.posBodyEmphasized, maximumContentSizeCategory: .accessibilityLarge)
54-
.foregroundColor(.primary)
54+
.foregroundColor(.posOnSurface)
5555
}
5656
POSHeaderTitleView(title: title)
5757
Spacer()

WooCommerce/Classes/POS/Presentation/Item Selector/ParentProductCardView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ struct ParentProductCardView: View {
2828
VStack(alignment: .leading, spacing: Constants.textSpacing) {
2929
Text(name)
3030
.lineLimit(2)
31-
.foregroundStyle(Color.posPrimaryText)
31+
.foregroundStyle(Constants.titleColor)
3232
.multilineTextAlignment(.leading)
3333
.font(Constants.itemTitleFont)
3434

3535
Text(detailText)
36-
.foregroundStyle(Color.posSecondaryText)
36+
.foregroundStyle(Constants.detailColor)
3737
.font(Constants.itemDetailFont)
3838
}
3939
.padding(.horizontal, Constants.horizontalTextPadding * (1 / scale))

WooCommerce/Classes/POS/Presentation/Item Selector/PointOfSaleItemListCardConstants.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ enum PointOfSaleItemListCardConstants {
1313
static let accessoryButtonMaxWidth: CGFloat = 136
1414
static let accessoryButtonPadding: CGFloat = 16
1515
static let backgroundColor: Color = .posSurfaceContainerLowest
16+
static let titleColor: Color = .posOnSurface
17+
static let detailColor: Color = .posOnSurfaceVariantHighest
1618
}

WooCommerce/Classes/POS/Presentation/Item Selector/SimpleProductCardView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ struct SimpleProductCardView: View {
2525
VStack(alignment: .leading, spacing: Constants.textSpacing) {
2626
Text(product.name)
2727
.lineLimit(2)
28-
.foregroundStyle(Color.posPrimaryText)
28+
.foregroundStyle(Constants.titleColor)
2929
.multilineTextAlignment(.leading)
3030
.font(Constants.itemTitleFont)
3131

3232
Text(product.formattedPrice)
33-
.foregroundStyle(Color.posSecondaryText)
33+
.foregroundStyle(Constants.detailColor)
3434
.font(Constants.itemDetailFont)
3535
}
3636
.padding(.horizontal, Constants.horizontalTextPadding * (1 / scale))

WooCommerce/Classes/POS/Presentation/Item Selector/VariationCardView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ struct VariationCardView: View {
2424
VStack(alignment: .leading, spacing: Constants.textSpacing) {
2525
Text(variation.name)
2626
.lineLimit(2)
27-
.foregroundStyle(Color.posPrimaryText)
27+
.foregroundStyle(Constants.titleColor)
2828
.multilineTextAlignment(.leading)
2929
.font(Constants.itemTitleFont)
3030

3131
Text(variation.formattedPrice)
32-
.foregroundStyle(Color.posSecondaryText)
32+
.foregroundStyle(Constants.detailColor)
3333
.font(Constants.itemDetailFont)
3434
}
3535
.padding(.horizontal, Constants.horizontalTextPadding * (1 / scale))

WooCommerce/Classes/POS/Presentation/ItemRowView.swift

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ struct ItemRowView: View {
55
private let onItemRemoveTapped: (() -> Void)?
66

77
@ScaledMetric private var scale: CGFloat = 1.0
8-
@Environment(\.colorScheme) var colorScheme
98
@Binding private var showProductImage: Bool
109

10+
private var dimension: CGFloat {
11+
min(Constants.productCardSize * scale, Constants.maximumProductCardSize)
12+
}
13+
1114
init(cartItem: CartItem, showImage: Binding<Bool> = .constant(true), onItemRemoveTapped: (() -> Void)? = nil) {
1215
self.cartItem = cartItem
1316
self._showProductImage = showImage
@@ -20,15 +23,15 @@ struct ItemRowView: View {
2023

2124
VStack(alignment: .leading, spacing: Constants.itemTitleAndPriceSpacing * (1 / scale)) {
2225
Text(cartItem.title)
23-
.foregroundColor(Color.posPrimaryText)
26+
.foregroundColor(PointOfSaleItemListCardConstants.titleColor)
2427
.font(Constants.itemTitleFont)
2528
if let subtitle = cartItem.subtitle {
2629
Text(subtitle)
27-
.foregroundColor(Color.posSecondaryText)
30+
.foregroundColor(PointOfSaleItemListCardConstants.detailColor)
2831
.font(Constants.itemSubtitleFont)
2932
}
3033
Text(cartItem.item.formattedPrice)
31-
.foregroundColor(Color.posSecondaryText)
34+
.foregroundColor(PointOfSaleItemListCardConstants.detailColor)
3235
.font(Constants.itemPriceFont)
3336
}
3437
.frame(maxWidth: .infinity, alignment: .leading)
@@ -49,43 +52,19 @@ struct ItemRowView: View {
4952
}
5053
.frame(maxWidth: .infinity, idealHeight: Constants.productCardSize * scale)
5154
.background(Color.posSurfaceContainerLowest)
52-
.overlay {
53-
RoundedRectangle(cornerRadius: Constants.productCardCornerRadius)
54-
.stroke(Color.posCartItemOutline, lineWidth: cardOutlineWidth)
55-
}
56-
.clipShape(RoundedRectangle(cornerRadius: Constants.productCardCornerRadius))
55+
.posItemCardBorderStyles()
5756
.padding(.horizontal, Constants.horizontalPadding)
5857
}
5958

6059
@ViewBuilder
6160
private var productImage: some View {
6261
if !showProductImage {
6362
EmptyView()
64-
} else if let imageSource = cartItem.item.productImageSource {
65-
ProductImageThumbnail(productImageURL: URL(string: imageSource),
66-
productImageSize: Constants.productCardSize,
67-
scale: scale,
68-
foregroundColor: .clear,
69-
cachesOriginalImage: true)
70-
.frame(width: min(Constants.productCardSize * scale, Constants.maximumProductCardSize),
71-
height: Constants.productCardSize * scale)
72-
.clipped()
7363
} else {
74-
Rectangle()
75-
.frame(width: min(Constants.productCardSize * scale, Constants.maximumProductCardSize),
76-
height: Constants.productCardSize * scale)
77-
.foregroundColor(Color(.secondarySystemFill))
78-
}
79-
}
80-
}
81-
82-
private extension ItemRowView {
83-
var cardOutlineWidth: CGFloat {
84-
switch colorScheme {
85-
case .dark:
86-
return 0
87-
default:
88-
return Constants.cardOutlineWidth
64+
POSItemImageView(imageSource: cartItem.item.productImageSource,
65+
imageSize: dimension,
66+
scale: 1)
67+
.frame(width: dimension, height: dimension)
8968
}
9069
}
9170
}
@@ -94,8 +73,6 @@ private extension ItemRowView {
9473
enum Constants {
9574
static let productCardSize: CGFloat = 96
9675
static let maximumProductCardSize: CGFloat = Self.productCardSize * 1.5
97-
static let productCardCornerRadius: CGFloat = 8
98-
static let cardOutlineWidth: CGFloat = 1
9976
static let horizontalPadding: CGFloat = 16
10077
static let horizontalElementSpacing: CGFloat = 16
10178
static let cardContentHorizontalPadding: CGFloat = 16

WooCommerce/Classes/POS/Presentation/Reusable Views/POSItemCardBorderStylesModifier.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ struct POSItemCardBorderStylesModifier: ViewModifier {
55
content
66
.overlay {
77
RoundedRectangle(cornerRadius: Constants.cardCornerRadius)
8-
.stroke(Color.black, lineWidth: Constants.nilOutline)
8+
.stroke(Color.posShadow, lineWidth: Constants.nilOutline)
99
}
1010
.clipShape(RoundedRectangle(cornerRadius: Constants.cardCornerRadius))
11+
.shadow(color: Color.posShadow.opacity(0.04), radius: 12, x: 0, y: 8)
12+
.shadow(color: Color.posShadow.opacity(0.08), radius: 4, x: 0, y: 2)
1113
}
1214
}
1315

WooCommerce/Classes/POS/Presentation/Reusable Views/POSItemImageView.swift

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,39 @@ struct POSItemImageView: View {
66
let imageSize: CGFloat
77
let scale: CGFloat
88

9+
private var placeholderView: some View {
10+
Rectangle()
11+
.foregroundColor(Constants.placeholderBackgroundColor)
12+
.overlay {
13+
Text(Image(systemName: "archivebox"))
14+
.font(.posButtonSymbol)
15+
.foregroundColor(Constants.placeholderIconColor)
16+
}
17+
}
18+
919
var body: some View {
10-
if let imageSource = imageSource {
20+
if let imageSource {
1121
ProductImageThumbnail(productImageURL: URL(string: imageSource),
1222
productImageSize: imageSize,
1323
scale: scale,
14-
foregroundColor: .clear,
15-
cachesOriginalImage: true)
24+
foregroundColor: Constants.placeholderIconColor,
25+
cachesOriginalImage: true) {
26+
placeholderView
27+
}
1628
} else {
17-
Rectangle()
18-
.foregroundColor(Color(.secondarySystemFill))
29+
placeholderView
1930
}
2031
}
2132
}
2233

34+
private extension POSItemImageView {
35+
enum Constants {
36+
static let placeholderIconDimension: CGFloat = 38
37+
static let placeholderIconColor: Color = .posOnSurfaceVariantLowest
38+
static let placeholderBackgroundColor: Color = .posSurfaceDim
39+
}
40+
}
41+
2342
#Preview("Placeholder") {
2443
POSItemImageView(imageSource: nil,
2544
imageSize: 112,

WooCommerce/Classes/POS/Utils/Color+WooCommercePOS.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,6 @@ extension Color {
1111
)
1212
}
1313

14-
// MARK: - Background
15-
16-
/* POS Background colors are defined in a similar philosophy as system background colors:
17-
*
18-
* The first color is intended to be the main background, farthest back.
19-
* Secondary and tertiary colors are layered on top of the main background, when needed.
20-
*/
21-
22-
// An ugly duckling; intended for use for borders where the bordered view has
23-
// `.posSecondaryBackground` in light mode, even though it's on another `.posSecondaryBackground` view. Does not adapt
24-
static var posCartItemOutline: Color {
25-
Color(
26-
UIColor(red: 220.0/255.0, green: 220.0/255.0, blue: 222.0/255.0, alpha: 1.0)
27-
)
28-
}
29-
3014
// MARK: - Text
3115

3216
private static var posGray: Color {

0 commit comments

Comments
 (0)