Skip to content

Commit 37974bb

Browse files
authored
CAL-46: Create code documentation
Ticket: https://mijick.atlassian.net/browse/CAL-46
1 parent b227c1e commit 37974bb

8 files changed

+120
-64
lines changed

Sources/Internal/Enums/MWeekday.swift

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// MWeekday.swift of CalendarView
3+
//
4+
// Created by Alina Petrovska on 29.10.2023.
5+
6+
// - GitHub: https://github.com/Mijick
7+
//
8+
// Copyright ©2023 Mijick. Licensed under MIT License.
9+
10+
11+
extension MWeekday {
12+
static var allCases: [MWeekday] {
13+
let firstDayIndex = MCalendar.firstWeekday.rawValue
14+
let weekDaysIndexes = [Int](firstDayIndex ... 7) + [Int](1 ..< firstDayIndex)
15+
16+
return .init(weekDaysIndexes)
17+
}
18+
}
19+
20+
// MARK: - Helpers
21+
fileprivate extension [MWeekday] {
22+
init(_ indexes: [Int]) { self = indexes.compactMap { .init(rawValue: $0) }}
23+
}

Sources/Public/Configurables/Public+CalendarConfig.swift

+38-7
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,68 @@ import SwiftUI
1313

1414
// MARK: - Calendar Configuration
1515
public extension CalendarConfig {
16+
/// Sets the start date of the calendar.
17+
/// DEFAULT: Current month
1618
func startMonth(_ value: Date) -> Self { MCalendar.startDate = value.start(of: .month); return self }
19+
20+
/// Sets the end date of the calendar.
21+
/// DEFAULT: A date in 10 years
1722
func endMonth(_ value: Date) -> Self { MCalendar.endDate = value.end(of: .month); return self }
23+
24+
/// Sets the first day of the week.
25+
/// DEFAULT:: Monday
1826
func firstWeekday(_ value: MWeekday) -> Self { MCalendar.firstWeekday = value; return self }
27+
28+
/// Sets the locale of the calendar.
29+
/// DEFAULT: AutoupdatingCurrent
1930
func locale(_ value: Locale) -> Self { MCalendar.locale = value; return self }
2031
}
2132

2233
// MARK: - Distances Between Objects
2334
public extension CalendarConfig {
35+
/// Sets the top scroll padding in the view.
2436
func monthsTopPadding(_ value: CGFloat) -> Self { changing(path: \.monthsPadding.top, to: value) }
37+
38+
/// Sets the bottom scroll padding in the view.
2539
func monthsBottomPadding(_ value: CGFloat) -> Self { changing(path: \.monthsPadding.bottom, to: value) }
40+
41+
/// Sets the distance between the month label and the day cell in the view.
2642
func monthLabelToDaysDistance(_ value: CGFloat) -> Self { changing(path: \.monthLabelDaysSpacing, to: value) }
43+
44+
/// Sets the spacing between months in the view.
2745
func monthsSpacing(_ value: CGFloat) -> Self { changing(path: \.monthsSpacing, to: value) }
46+
47+
/// Sets the vertical spacing between day cells in the view.
2848
func daysVerticalSpacing(_ value: CGFloat) -> Self { changing(path: \.daysSpacing.vertical, to: value) }
49+
50+
/// Sets the horizontal spacing between day cells in the view.
2951
func daysHorizontalSpacing(_ value: CGFloat) -> Self { changing(path: \.daysSpacing.horizontal, to: value) }
3052
}
3153

32-
// MARK: - Custom Views
54+
// MARK: - View Customisation
3355
public extension CalendarConfig {
34-
func monthLabel(_ builder: @escaping (Date) -> some MonthLabel) -> Self { changing(path: \.monthLabel, to: builder) }
35-
func weekdaysView(_ builder: @escaping () -> some WeekdaysView) -> Self { changing(path: \.weekdaysView, to: builder) }
36-
func dayView(_ builder: @escaping (Date, Bool, Binding<Date?>?, Binding<MDateRange?>?) -> some DayView) -> Self { changing(path: \.dayView, to: builder) }
56+
/// Sets the background for the months view.
57+
func monthsViewBackground(_ value: Color) -> Self { changing(path: \.monthsViewBackground, to: value) }
3758
}
3859

39-
// MARK: - View Customisation
60+
// MARK: - Custom Views
4061
public extension CalendarConfig {
41-
func monthsViewBackground(_ value: Color) -> Self { changing(path: \.monthsViewBackground, to: value) }
62+
/// Replaces the default weekdays view with a selected implementation.
63+
func weekdaysView(_ builder: @escaping () -> some WeekdaysView) -> Self { changing(path: \.weekdaysView, to: builder) }
64+
65+
/// Replaces the default month label with a selected implementation.
66+
func monthLabel(_ builder: @escaping (Date) -> some MonthLabel) -> Self { changing(path: \.monthLabel, to: builder) }
67+
68+
/// Replaces the default day view with a selected implementation.
69+
func dayView(_ builder: @escaping (Date, Bool, Binding<Date?>?, Binding<MDateRange?>?) -> some DayView) -> Self { changing(path: \.dayView, to: builder) }
4270
}
4371

4472
// MARK: - Modifiers
4573
public extension CalendarConfig {
74+
/// Scrolls the calendar to the selected date.
4675
func scrollTo(date: Date?) -> Self { changing(path: \.scrollDate, to: date) }
76+
77+
/// Triggers when a new month is about to be visible.
4778
func onMonthChange(_ value: @escaping (Date) -> ()) -> Self { changing(path: \.onMonthChange, to: value) }
4879
}
4980

@@ -57,8 +88,8 @@ public struct CalendarConfig: Configurable { public init() {}
5788

5889
private(set) var monthsViewBackground: Color = .clear
5990

60-
private(set) var monthLabel: (Date) -> any MonthLabel = DefaultMonthLabel.init
6191
private(set) var weekdaysView: () -> any WeekdaysView = DefaultWeekdaysView.init
92+
private(set) var monthLabel: (Date) -> any MonthLabel = DefaultMonthLabel.init
6293
private(set) var dayView: (Date, Bool, Binding<Date?>?, Binding<MDateRange?>?) -> any DayView = DefaultDayView.init
6394

6495
private(set) var scrollDate: Date? = nil

Sources/Public/Enums/Public+MWeekday.swift

-15
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,4 @@
88
// Copyright ©2023 Mijick. Licensed under MIT License.
99

1010

11-
import Foundation
12-
1311
public enum MWeekday: Int { case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday }
14-
extension MWeekday {
15-
static var allCases: [MWeekday] {
16-
let firstDayIndex = MCalendar.firstWeekday.rawValue
17-
let weekDaysIndexes = [Int](firstDayIndex ... 7) + [Int](1 ..< firstDayIndex)
18-
19-
return .init(weekDaysIndexes)
20-
}
21-
}
22-
23-
// MARK: - Helpers
24-
fileprivate extension [MWeekday] {
25-
init(_ indexes: [Int]) { self = indexes.compactMap { .init(rawValue: $0) }}
26-
}

Sources/Public/Extensions/Public+MCalendarView.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,5 @@
1212
import SwiftUI
1313

1414
extension MCalendarView {
15-
public init(selectedDate: Binding<Date?>?, selectedRange: Binding<MDateRange?>?, configBuilder: (CalendarConfig) -> CalendarConfig = { $0 }) {
16-
self.init(selectedDate, selectedRange, configBuilder)
17-
}
15+
public init(selectedDate: Binding<Date?>?, selectedRange: Binding<MDateRange?>?, configBuilder: (CalendarConfig) -> CalendarConfig = { $0 }) { self.init(selectedDate, selectedRange, configBuilder) }
1816
}

Sources/Public/View Protocols/Public+DayView.swift

+27-24
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,14 @@ public protocol DayView: View {
2929
func onSelection()
3030
}
3131

32-
// MARK: - Customising View
32+
// MARK: - Default View Implementation
3333
public extension DayView {
3434
func createContent() -> AnyView { createDefaultContent().erased() }
3535
func createDayLabel() -> AnyView { createDefaultDayLabel().erased() }
3636
func createSelectionView() -> AnyView { createDefaultSelectionView().erased() }
3737
func createRangeSelectionView() -> AnyView { createDefaultRangeSelectionView().erased() }
38-
39-
var body: some View { createBody() }
4038
}
4139
private extension DayView {
42-
func createBody() -> some View {
43-
Group {
44-
if isCurrentMonth { createBodyForCurrentMonth() }
45-
else { createBodyForOtherMonth() }
46-
}
47-
}
4840
func createDefaultContent() -> some View { ZStack {
4941
createSelectionView()
5042
createRangeSelectionView()
@@ -68,16 +60,6 @@ private extension DayView {
6860
.active(if: isWithinRange())
6961
}
7062
}
71-
private extension DayView {
72-
func createBodyForCurrentMonth() -> some View {
73-
createContent()
74-
.frame(maxWidth: .infinity, maxHeight: .infinity)
75-
.aspectRatio(1.0, contentMode: .fit)
76-
.onAppear(perform: onAppear)
77-
.onTapGesture(perform: onSelection)
78-
}
79-
func createBodyForOtherMonth() -> some View { Rectangle().fill(Color.clear) }
80-
}
8163
private extension DayView {
8264
var rangeSelectionViewCorners: RoundedRectangle.Corner {
8365
if isBeginningOfRange() { return [.topLeft, .bottomLeft] }
@@ -87,31 +69,52 @@ private extension DayView {
8769
}
8870
}
8971

90-
// MARK: - Handling Actions
72+
// MARK: - Default Logic Implementation
9173
public extension DayView {
9274
func onAppear() {}
9375
func onSelection() { selectedDate?.wrappedValue = date }
9476
}
9577

96-
// MARK: - Text Formatting
78+
// MARK: - Helpers
79+
80+
// MARK: Text Formatting
9781
public extension DayView {
82+
/// Returns a string of the selected format for the date.
9883
func getStringFromDay(format: String) -> String { MDateFormatter.getString(from: date, format: format) }
9984
}
10085

101-
// MARK: - Date Helpers
86+
// MARK: Date Helpers
10287
public extension DayView {
10388
func isPast() -> Bool { date.isBefore(.day, than: .now) }
10489
func isToday() -> Bool { date.isSame(.day, as: .now) }
10590
}
10691

107-
// MARK: - Day Selection Helpers
92+
// MARK: Day Selection Helpers
10893
public extension DayView {
10994
func isSelected() -> Bool { date.isSame(.day, as: selectedDate?.wrappedValue) || isBeginningOfRange() || isEndOfRange() }
11095
}
11196

112-
// MARK: - Range Selection Helpers
97+
// MARK: Range Selection Helpers
11398
public extension DayView {
11499
func isBeginningOfRange() -> Bool { date.isSame(.day, as: selectedRange?.wrappedValue?.getRange()?.lowerBound) }
115100
func isEndOfRange() -> Bool { date.isSame(.day, as: selectedRange?.wrappedValue?.getRange()?.upperBound) }
116101
func isWithinRange() -> Bool { selectedRange?.wrappedValue?.isRangeCompleted() == true && selectedRange?.wrappedValue?.contains(date) == true }
117102
}
103+
104+
// MARK: - Others
105+
public extension DayView {
106+
var body: some View { Group {
107+
if isCurrentMonth { createBodyForCurrentMonth() }
108+
else { createBodyForOtherMonth() }
109+
}}
110+
}
111+
private extension DayView {
112+
func createBodyForCurrentMonth() -> some View {
113+
createContent()
114+
.frame(maxWidth: .infinity, maxHeight: .infinity)
115+
.aspectRatio(1.0, contentMode: .fit)
116+
.onAppear(perform: onAppear)
117+
.onTapGesture(perform: onSelection)
118+
}
119+
func createBodyForOtherMonth() -> some View { Rectangle().fill(Color.clear) }
120+
}

Sources/Public/View Protocols/Public+MonthLabel.swift

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
import SwiftUI
1212

1313
public protocol MonthLabel: View {
14+
// MARK: Required Attributes
1415
var month: Date { get }
1516

17+
// MARK: View Customisation
1618
func createContent() -> AnyView
1719
}
1820

19-
// MARK: - Customizing View
21+
// MARK: - Default View Implementation
2022
public extension MonthLabel {
2123
func createContent() -> AnyView { createDefaultContent().erased() }
22-
var body: some View { createContent() }
2324
}
2425
private extension MonthLabel {
2526
func createDefaultContent() -> some View {
@@ -31,5 +32,11 @@ private extension MonthLabel {
3132

3233
// MARK: - Helpers
3334
public extension MonthLabel {
35+
/// Returns a string of the selected format for the month.
3436
func getString(format: String) -> String { MDateFormatter.getString(from: month, format: format) }
3537
}
38+
39+
// MARK: - Others
40+
public extension MonthLabel {
41+
var body: some View { createContent() }
42+
}

Sources/Public/View Protocols/Public+WeekdayLabel.swift

+10-3
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
import SwiftUI
1212

1313
public protocol WeekdayLabel: View {
14+
// MARK: Required Attributes
1415
var weekday: MWeekday { get }
1516

17+
// MARK: View Customisation
1618
func createContent() -> AnyView
1719
}
1820

19-
// MARK: - Customising View
21+
// MARK: - Default View Implementation
2022
public extension WeekdayLabel {
2123
func createContent() -> AnyView { createDefaultContent().erased() }
22-
var body: some View { createContent() }
2324
}
2425
private extension WeekdayLabel {
2526
func createDefaultContent() -> some View {
@@ -31,8 +32,14 @@ private extension WeekdayLabel {
3132

3233
// MARK: - Helpers
3334
public extension WeekdayLabel {
35+
/// Returns a string of the selected format for the weekday.
36+
func getString(with format: WeekdaySymbolFormat) -> String { MDateFormatter.getString(for: weekday, format: format) }
37+
38+
/// Returns a type-erased object.
3439
func erased() -> AnyWeekdayLabel { .init(self) }
3540
}
41+
42+
// MARK: - Others
3643
public extension WeekdayLabel {
37-
func getString(with format: WeekdaySymbolFormat) -> String { MDateFormatter.getString(for: weekday, format: format) }
44+
var body: some View { createContent() }
3845
}

Sources/Public/View Protocols/Public+WeekdaysView.swift

+12-10
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,31 @@
1010

1111
import SwiftUI
1212

13-
public protocol WeekdaysView: View {
13+
public protocol WeekdaysView: View {
14+
// MARK: View Customisation
1415
func createContent() -> AnyView
1516
func createWeekdayLabel(_ weekday: MWeekday) -> AnyWeekdayLabel
1617
}
1718

18-
// MARK: - Customising View
19+
// MARK: - Default View Implementation
1920
public extension WeekdaysView {
20-
func createContent() -> AnyView { createDefaultContent().erased() }
21-
func createWeekdaysView() -> AnyView { createDefaultWeekdaysView().erased() }
21+
func createContent() -> AnyView { createWeekdaysView().erased() }
2222
func createWeekdayLabel(_ weekday: MWeekday) -> AnyWeekdayLabel { createDefaultWeekDayLabel(weekday).erased() }
23-
24-
var body: some View { createContent() }
2523
}
2624
private extension WeekdaysView {
27-
func createDefaultContent() -> some View { createWeekdaysView() }
28-
func createDefaultWeekdaysView() -> some View { HStack(spacing: 0) { ForEach(weekdays, id: \.self, content: createWeekdayItem) }}
2925
func createDefaultWeekDayLabel(_ weekday: MWeekday) -> DefaultWeekdayLabel { DefaultWeekdayLabel(weekday: weekday) }
3026
}
27+
28+
// MARK: - Helpers
29+
public extension WeekdaysView {
30+
/// Creates weekdays view using the selected weekday labels. Cannot be overriden.
31+
func createWeekdaysView() -> some View { HStack(spacing: 0) { ForEach(MWeekday.allCases, id: \.self, content: createWeekdayItem) } }
32+
}
3133
private extension WeekdaysView {
3234
func createWeekdayItem(_ weekday: MWeekday) -> some View { createWeekdayLabel(weekday).frame(maxWidth: .infinity) }
3335
}
3436

35-
// MARK: Helpers
37+
// MARK: - Others
3638
public extension WeekdaysView {
37-
var weekdays: [MWeekday] { MWeekday.allCases }
39+
var body: some View { createContent() }
3840
}

0 commit comments

Comments
 (0)