-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathPreviewVariants.swift
More file actions
97 lines (81 loc) · 2.48 KB
/
PreviewVariants.swift
File metadata and controls
97 lines (81 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import SwiftUI
struct PreviewView: Identifiable {
let id = UUID()
let value: AnyView
let name: String
}
extension View {
func previewVariant(named name: String) -> PreviewView {
PreviewView(value: AnyView(self), name: name)
}
}
struct PreviewVariants: View {
init(
modifiers: [NamedViewModifier] = .previewDefault,
layout: PreviewLayout = .device,
@ArrayBuilder<PreviewView> views: () -> [PreviewView])
{
self.modifiers = modifiers
self.layout = layout
self.views = views()
}
var body: some View {
ForEach(modifiers) { modifier in
ForEach(views) { view in
let displayName = [view.name, modifier.name]
.filter { !$0.isEmpty }
.joined(separator: ", ")
AnyView(modifier.value(view.value))
.previewDisplayName(displayName)
.previewLayout(layout)
}
}
}
private let modifiers: [NamedViewModifier]
private let layout: PreviewLayout
private let views: [PreviewView]
}
struct NamedViewModifier {
var name: String
var value: (any View) -> any View
}
extension NamedViewModifier: Identifiable {
var id: String { name }
}
extension NamedViewModifier {
static var unmodified: NamedViewModifier {
.init(name: "", value: { $0 })
}
static var darkMode: NamedViewModifier {
.init(name: "Dark mode", value: { $0.preferredColorScheme(.dark).environment(\.colorScheme, .dark) })
}
static var landscape: NamedViewModifier {
.init(name: "Landscape", value: { $0.previewInterfaceOrientation(.landscapeLeft) })
}
static var xxlTextSize: NamedViewModifier {
.init(name: "XXL Text Size", value: { $0.dynamicTypeSize(.xxxLarge) })
}
@available(macOS, unavailable)
@available(watchOS, unavailable)
@available(visionOS, unavailable)
@available(tvOS, unavailable)
static var accessibility: NamedViewModifier {
.init(name: "Accessibility", value: { $0.snapshotAccessibility(true) })
}
static var rtl: NamedViewModifier {
.init(name: "RTL", value: { $0.environment(\.layoutDirection, .rightToLeft) })
}
}
extension [NamedViewModifier] {
/// The default named view modifiers in a ``PreviewVariants``.
static var previewDefault: [NamedViewModifier] {
#if os(iOS)
if UserDefaults.standard.bool(forKey: "NSDoubleLocalizedStrings") {
return [.unmodified, .darkMode, .xxlTextSize, .rtl, .landscape]
}
return [.unmodified, .darkMode, .xxlTextSize, .rtl, .accessibility, .landscape]
#else
[.unmodified, .darkMode, .rtl]
#endif
}
}