diff --git a/Sources/Orbit/Components/Alert.swift b/Sources/Orbit/Components/Alert.swift
index 76b9b4c853c..6b5c449e32c 100644
--- a/Sources/Orbit/Components/Alert.swift
+++ b/Sources/Orbit/Components/Alert.swift
@@ -1,38 +1,48 @@
import SwiftUI
-/// Breaks the main user flow to present information.
+/// Orbit component that breaks the main user flow to present information.
///
-/// There are times when just simple information isn’t enough and the user needs
-/// to take additional steps to resolve the problem or get additional details.
+/// An ``Alert`` consists of a title, description, icon, optional custom content and at most two actions.
///
-/// In such cases, provide additional actions for your message.
-/// Alerts use special status buttons to match the button color with the alert color.
+/// ```swift
+/// Alert("Alert") {
+/// Button("Primary") { /* Tap action */ }
+/// Button("Secondary") { /* Tap action */ }
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The title and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
///
-/// Use at most two actions in each Alert: one primary and one subtle.
+/// A default ``Status/info`` status can be modified by ``status(_:)`` modifier:
///
/// ```swift
-/// Alert("Alert", description: "Description") {
-/// customContent
-/// } buttons: {
-/// Button("Primary") { /* */ }
-/// Button("Secondary") { /* */ }
-/// }
-/// .status(.warning)
+/// Alert("Alert", description: "Please check your visa")
+/// .status(.warning)
/// ```
///
-/// The button priority can be overridden by using `buttonPriority()` modifier.
+/// The default button priority can be overridden by ``buttonPriority(_:)`` modifier:
///
/// ```swift
/// Alert("Alert") {
-/// customContent
+/// content
/// } buttons: {
-/// Button("Secondary Only") { /* */ }
-/// .buttonPriority(.secondary)
+/// Button("Secondary Only") {
+/// // Tap action
+/// }
+/// .buttonPriority(.secondary)
/// }
/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/alert/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// For compact variant, use ``AlertInline`` component.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/alert/)
public struct Alert: View {
private let title: String
@@ -56,7 +66,7 @@ public struct Alert: View {
public extension Alert {
- /// Creates Orbit Alert component.
+ /// Creates Orbit ``Alert`` component.
init(
_ title: String = "",
description: String = "",
@@ -73,7 +83,7 @@ public extension Alert {
}
}
- /// Creates Orbit Alert component with no buttons.
+ /// Creates Orbit ``Alert`` component with no buttons.
init(
_ title: String = "",
description: String = "",
@@ -89,7 +99,7 @@ public extension Alert {
}
}
- /// Creates Orbit Alert component with custom content and icon.
+ /// Creates Orbit ``Alert`` component with custom content and icon.
init(
_ title: String = "",
description: String = "",
diff --git a/Sources/Orbit/Components/AlertInline.swift b/Sources/Orbit/Components/AlertInline.swift
index 33807c5ac36..e549e020802 100644
--- a/Sources/Orbit/Components/AlertInline.swift
+++ b/Sources/Orbit/Components/AlertInline.swift
@@ -1,12 +1,38 @@
import SwiftUI
-/// Breaks the main user flow to present information.
+/// Orbit component that breaks the main user flow to present information.
///
-/// There are times when just simple information isn’t enough and the user needs
-/// to take additional steps to resolve the problem or get additional details.
+/// An ``AlertInline`` (an inline variant of ``Alert``) consists of a title, icon and a single action.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/alert/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// ```swift
+/// AlertInline("Alert") {
+/// Button("Primary") {
+/// // Tap action
+/// }
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The title and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// A default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// AlertInline("Alert") {
+/// Button("Primary") {
+/// // Tap action
+/// }
+/// }
+/// .status(.warning)
+/// ```
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/alert/)
public struct AlertInline: View {
private let title: String
@@ -28,7 +54,7 @@ public struct AlertInline: View {
public extension AlertInline {
- /// Creates Orbit AlertInline component.
+ /// Creates Orbit ``AlertInline`` component.
init(
_ title: String = "",
icon: Icon.Symbol? = nil,
@@ -40,7 +66,7 @@ public extension AlertInline {
}
}
- /// Creates Orbit AlertInline component with custom content and icon.
+ /// Creates Orbit ``AlertInline`` component with custom content and icon.
init(
_ title: String = "",
isSubtle: Bool = false,
diff --git a/Sources/Orbit/Components/Badge.swift b/Sources/Orbit/Components/Badge.swift
index 6f9cd435c6e..1c4ce24ed5e 100644
--- a/Sources/Orbit/Components/Badge.swift
+++ b/Sources/Orbit/Components/Badge.swift
@@ -1,11 +1,37 @@
import SwiftUI
-/// Presents users with short, relevant information.
+/// Orbit component that displays non-actionable, short and static information.
///
-/// Badges are indicators of static information.
-/// They can be updated when a status changes, but they should not be actionable.
+/// A ``Badge`` consists of a title and up to two icons.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/badge/)
+/// ```swift
+/// Badge("Label", icon: .grid, type: .lightInverted)
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The label and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// ```swift
+/// Badge("Label", type: .status(nil))
+/// .textColor(.inkNormal)
+/// .iconColor(.redNormal)
+/// .iconSize(.small)
+/// ```
+///
+/// When type is set to ``BadgeType/status(_:inverted:)`` with a `nil` value, the default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// Badge("Label", type: .status(nil))
+/// .status(.warning)
+/// ```
+///
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/badge/)
public struct Badge: View, PotentiallyEmptyView {
@Environment(\.backgroundShape) private var backgroundShape
@@ -47,7 +73,7 @@ public struct Badge: View, PotentiallyEmp
}
}
- @ViewBuilder var resolvedBackground: some View {
+ @ViewBuilder private var resolvedBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -55,11 +81,15 @@ public struct Badge: View, PotentiallyEmp
}
}
- var resolvedLabelColor: Color {
+ var isEmpty: Bool {
+ leadingIcon.isEmpty && label.isEmpty && trailingIcon.isEmpty
+ }
+
+ private var resolvedLabelColor: Color {
textColor ?? labelColor
}
- var labelColor: Color {
+ private var labelColor: Color {
switch type {
case .light: return .inkDark
case .lightInverted: return .whiteNormal
@@ -69,7 +99,7 @@ public struct Badge: View, PotentiallyEmp
}
}
- var defaultBackgroundColor: Color {
+ private var defaultBackgroundColor: Color {
switch type {
case .light: return .whiteDarker
case .lightInverted: return .inkDark
@@ -79,15 +109,11 @@ public struct Badge: View, PotentiallyEmp
}
}
- var minTextWidth: CGFloat {
+ private var minTextWidth: CGFloat {
Text.Size.small.lineHeight * sizeCategory.ratio - .xSmall
}
- var isEmpty: Bool {
- leadingIcon.isEmpty && label.isEmpty && trailingIcon.isEmpty
- }
-
- var defaultStatus: Status {
+ private var defaultStatus: Status {
status ?? .info
}
}
@@ -95,10 +121,7 @@ public struct Badge: View, PotentiallyEmp
// MARK: - Inits
public extension Badge {
- /// Creates Orbit Badge component.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``Badge`` component.
init(
_ label: String = "",
icon: Icon.Symbol? = nil,
@@ -112,10 +135,7 @@ public extension Badge {
}
}
- /// Creates Orbit Badge component with custom icons.
- ///
- /// - Parameters:
- /// - style: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``Badge`` component with custom icons.
init(
_ label: String = "",
type: BadgeType = .neutral,
@@ -130,6 +150,8 @@ public extension Badge {
}
// MARK: - Types
+
+/// A type of Orbit ``Badge`` and ``NotificationBadge``.
public enum BadgeType {
case light
@@ -137,6 +159,7 @@ public enum BadgeType {
case neutral
case status(_ status: Status? = nil, inverted: Bool = false)
+ /// An Orbit ``BadgeType`` `status` type with no value provided.
public static var status: Self {
.status(nil)
}
diff --git a/Sources/Orbit/Components/BadgeList.swift b/Sources/Orbit/Components/BadgeList.swift
index a94ca280b15..7fef28b862d 100644
--- a/Sources/Orbit/Components/BadgeList.swift
+++ b/Sources/Orbit/Components/BadgeList.swift
@@ -1,19 +1,43 @@
import SwiftUI
-/// Presents a list of short details with added visual information.
+/// Orbit component that displays non-actionable, short details with added visual information.
///
-/// The items in the list should all be static information, *not* actionable.
+/// A ``BadgeList`` consists of a description and icon.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/information/badgelist/)
+/// ```swift
+/// BadgeList("You must collect your baggage", icon: .baggage)
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The label color can be modified by ``textColor(_:)``:
+///
+/// ```swift
+/// BadgeList("Label")
+/// .textColor(.blueNormal)
+/// ```
+///
+/// When type is set to ``BadgeListType/status(_:)`` with a `nil` value, the default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// BadgeList("Does not include guarantee", type: .status(nil))
+/// .status(.warning)
+/// ```
+///
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/information/badgelist/)
public struct BadgeList: View, PotentiallyEmptyView {
@Environment(\.status) private var status
@Environment(\.textAccentColor) private var textAccentColor
@Environment(\.textColor) private var textColor
- let type: BadgeListType
- @ViewBuilder let icon: Icon
- @ViewBuilder let content: Content
+ private let type: BadgeListType
+ @ViewBuilder private let icon: Icon
+ @ViewBuilder private let content: Content
public var body: some View {
if isEmpty == false {
@@ -32,7 +56,7 @@ public struct BadgeList: View, PotentiallyEmptyView {
}
}
- @ViewBuilder var badge: some View {
+ @ViewBuilder private var badge: some View {
if icon.isEmpty {
Orbit.Icon(.grid)
.iconSize(.small)
@@ -42,14 +66,18 @@ public struct BadgeList: View, PotentiallyEmptyView {
}
}
- @ViewBuilder var badgeBackground: some View {
+ @ViewBuilder private var badgeBackground: some View {
if icon.isEmpty == false {
backgroundColor
.clipShape(Circle())
}
}
+
+ var isEmpty: Bool {
+ content.isEmpty && icon.isEmpty
+ }
- public var iconColor: Color {
+ private var iconColor: Color {
switch type {
case .neutral: return .inkNormal
case .status(let status): return (status ?? defaultStatus).color
@@ -57,7 +85,7 @@ public struct BadgeList: View, PotentiallyEmptyView {
}
}
- public var backgroundColor: Color {
+ private var backgroundColor: Color {
switch type {
case .neutral: return .cloudLight
case .status(let status): return (status ?? defaultStatus).lightColor
@@ -65,22 +93,15 @@ public struct BadgeList: View, PotentiallyEmptyView {
}
}
- var defaultStatus: Status {
+ private var defaultStatus: Status {
status ?? .info
}
-
- var isEmpty: Bool {
- content.isEmpty && icon.isEmpty
- }
}
// MARK: - Inits
public extension BadgeList {
- /// Creates Orbit BadgeList component.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``BadgeList`` component.
init(
_ label: String = "",
icon: Icon.Symbol? = nil,
@@ -92,10 +113,7 @@ public extension BadgeList {
}
}
- /// Creates Orbit BadgeList component with custom icon.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``BadgeList`` component with custom icon.
init(
_ label: String = "",
type: BadgeListType = .neutral,
@@ -108,10 +126,7 @@ public extension BadgeList {
}
}
- /// Creates Orbit BadgeList component with custom icon and content.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``BadgeList`` component with custom icon and content.
init(
type: BadgeListType = .neutral,
@ViewBuilder content: () -> Content,
@@ -125,10 +140,17 @@ public extension BadgeList {
// MARK: - Types
+/// A type of Orbit ``BadgeList``.
public enum BadgeListType: Equatable, Hashable {
case neutral
case status(_ status: Status?)
+ // FIXME: Remove and use override modifiers
case custom(iconColor: Color, backgroundColor: Color)
+
+ /// An Orbit ``BadgeListType`` `status` type with no value provided.
+ public static var status: Self {
+ .status(nil)
+ }
}
// MARK: - Previews
diff --git a/Sources/Orbit/Components/Button.swift b/Sources/Orbit/Components/Button.swift
index 0ad340a9a7c..41ace7f57ef 100644
--- a/Sources/Orbit/Components/Button.swift
+++ b/Sources/Orbit/Components/Button.swift
@@ -1,9 +1,50 @@
import SwiftUI
-/// Displays a single important action a user can take.
+/// Orbit component that displays a primary control that initiates an action.
+/// A counterpart of the native `SwiftUI.Button` with `borderedProminent` button style.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/button/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// A ``Button`` consists of a label and up to two icons.
+///
+/// ```swift
+/// Button("Continue", icon: .chevronForward) {
+/// // Tap action
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The label and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// ```swift
+/// Button("Continue") {
+/// // Tap action
+/// }
+/// .textColor(.blueLight)
+/// .iconColor(.blueNormal)
+/// .iconSize(.large)
+/// ```
+///
+/// When type is set to ``ButtonType/status(_:isSubtle:)`` with a `nil` value,
+/// the default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// Button("Delete", type: .status(nil)) {
+/// // Tap action
+/// }
+/// .status(.critical)
+/// ```
+///
+/// Before the action is triggered, a relevant haptic feedback, based on the `Button` type, is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+/// The default ``ButtonSize/regular`` size can be modified by a ``buttonSize(_:)`` modifier.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/button/)
public struct Button: View, PotentiallyEmptyView {
@Environment(\.suppressButtonStyle) private var suppressButtonStyle
@@ -29,7 +70,7 @@ public struct Button: View, PotentiallyEm
}
}
- @ViewBuilder var button: some View {
+ @ViewBuilder private var button: some View {
if isEmpty == false {
SwiftUI.Button() {
action()
@@ -47,12 +88,7 @@ public struct Button: View, PotentiallyEm
// MARK: - Inits
public extension Button {
- /// Creates Orbit Button component.
- ///
- /// Button size can be specified using `.buttonSize()` modifier.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A style can be optionally modified using `status()` modifier when `nil` status value is provided.
+ /// Creates Orbit ``Button`` component.
init(
_ label: String = "",
icon: Icon.Symbol? = nil,
@@ -69,12 +105,7 @@ public extension Button {
}
}
- /// Creates Orbit Button component with custom icons.
- ///
- /// Button size can be specified using `.buttonSize()` modifier.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A style can be optionally modified using `status()` modifier when `nil` status value is provided.
+ /// Creates Orbit ``Button`` component with custom icons.
init(
_ label: String = "",
type: ButtonType = .primary,
@@ -92,6 +123,7 @@ public extension Button {
// MARK: - Types
+/// A predefined type of Orbit ``Button``.
public enum ButtonType {
case primary
case primarySubtle
diff --git a/Sources/Orbit/Components/ButtonLink.swift b/Sources/Orbit/Components/ButtonLink.swift
index 9e50f69d5de..b5e53329cce 100644
--- a/Sources/Orbit/Components/ButtonLink.swift
+++ b/Sources/Orbit/Components/ButtonLink.swift
@@ -1,11 +1,51 @@
import SwiftUI
-/// Displays a single, less important action a user can take.
+/// Orbit component that displays a less important control that initiates an action.
+/// A counterpart of the native `SwiftUI.Button` with `plain` button style.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/buttonlink/)
+/// A ``ButtonLink`` consists of a label and up to two icons.
+///
+/// ```swift
+/// ButtonLink("Edit", icon: .edit) {
+/// // Tap action
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The icon color can be modified by ``iconColor(_:)`` modifier.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// ```swift
+/// ButtonLink("More", icon: .informationCircle) {
+/// // Tap action
+/// }
+/// .iconColor(.blueNormal)
+/// .iconSize(.large)
+/// ```
+///
+/// When type is set to ``ButtonLinkType/status(_:)`` with a `nil` value, the default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// ButtonLink("Delete", type: .status(nil)) {
+/// // Tap action
+/// }
+/// .status(.critical)
+/// ```
+///
+/// Before the action is triggered, a relevant haptic feedback, based on the `ButtonLink` type, is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier or by specifying the ``ButtonSize/compact`` size.
+/// The default ``ButtonSize/regular`` size can be modified by a ``buttonSize(_:)`` modifier.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/buttonlink/)
public struct ButtonLink: View, PotentiallyEmptyView {
- @Environment(\.suppressButtonStyle) var suppressButtonStyle
+ @Environment(\.suppressButtonStyle) private var suppressButtonStyle
private let label: String
private let type: ButtonLinkType
@@ -30,7 +70,7 @@ public struct ButtonLink: View, Potential
}
}
- @ViewBuilder var button: some View {
+ @ViewBuilder private var button: some View {
SwiftUI.Button() {
action()
} label: {
@@ -46,12 +86,7 @@ public struct ButtonLink: View, Potential
// MARK: - Inits
public extension ButtonLink {
- /// Creates Orbit ButtonLink component.
- ///
- /// Button size can be specified using `.buttonSize()` modifier.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A style can be optionally modified using `status()` modifier when `nil` status value is provided.
+ /// Creates Orbit ``ButtonLink`` component.
init(
_ label: String = "",
type: ButtonLinkType = .primary,
@@ -68,12 +103,7 @@ public extension ButtonLink {
}
}
- /// Creates Orbit ButtonLink component with custom icons.
- ///
- /// Button size can be specified using `.buttonSize()` modifier.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A style can be optionally modified using `status()` modifier when `nil` status value is provided.
+ /// Creates Orbit ``ButtonLink`` component with custom icons.
init(
_ label: String = "",
type: ButtonLinkType = .primary,
@@ -90,6 +120,8 @@ public extension ButtonLink {
}
// MARK: - Types
+
+/// A predefined type of Orbit ``ButtonLink``.
public enum ButtonLinkType: Equatable {
case primary
case critical
@@ -113,7 +145,7 @@ struct ButtonLinkPreviews: PreviewProvider {
static var standalone: some View {
VStack(spacing: 0) {
- ButtonLink("ButtonLink", action: {})
+ ButtonLink("ButtonLink", icon: .grid, action: {})
.buttonSize(.regular)
ButtonLink("ButtonLink", type: .critical, action: {})
.buttonSize(.regular)
diff --git a/Sources/Orbit/Components/Card.swift b/Sources/Orbit/Components/Card.swift
index ad924d29fbe..41f7ec4fc04 100644
--- a/Sources/Orbit/Components/Card.swift
+++ b/Sources/Orbit/Components/Card.swift
@@ -1,25 +1,42 @@
import SwiftUI
-/// Separates content into sections.
+/// Orbit component that separates content into sections.
///
-/// Card is a wrapping component around a custom content.
+/// A ``Card`` consists of a title, description, optional action and a custom content.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/card/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// ```swift
+/// Card("Card", description: "Description") {
+/// content1
+/// content2
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The title color can be modified by ``textColor(_:)`` modifier.
+/// The default background can be overridden by ``backgroundStyle(_:)-9odue`` modifier.
+///
+/// ### Layout
+///
+/// The component adds a `VStack` over the provided content. Avoid using the component when the content is large and should be embedded in a lazy stack.
+///
+/// Component expands horizontally unless prevented by native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/card/)
public struct Card: View {
@Environment(\.backgroundShape) private var backgroundShape
@Environment(\.idealSize) private var idealSize
- let title: String
- let description: String
- let action: CardAction
- let headerSpacing: CGFloat
- let contentLayout: CardContentLayout
- let contentAlignment: HorizontalAlignment
- let showBorder: Bool
- let titleStyle: Heading.Style
- @ViewBuilder let content: Content
+ private let title: String
+ private let description: String
+ private let action: CardAction
+ private let headerSpacing: CGFloat
+ private let contentLayout: CardContentLayout
+ private let contentAlignment: HorizontalAlignment
+ private let showBorder: Bool
+ private let titleStyle: Heading.Style
+ @ViewBuilder private let content: Content
public var body: some View {
VStack(alignment: .leading, spacing: headerSpacing) {
@@ -43,7 +60,7 @@ public struct Card: View {
.accessibilityElement(children: .contain)
}
- @ViewBuilder var header: some View {
+ @ViewBuilder private var header: some View {
if isHeaderEmpty == false {
HStack(alignment: .top, spacing: 0) {
VStack(alignment: .leading, spacing: .xxSmall) {
@@ -77,7 +94,7 @@ public struct Card: View {
}
}
- @ViewBuilder var resolvedBackground: some View {
+ @ViewBuilder private var resolvedBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -85,7 +102,7 @@ public struct Card: View {
}
}
- var isHeaderEmpty: Bool {
+ private var isHeaderEmpty: Bool {
if case .none = action, title.isEmpty, description.isEmpty {
return true
} else {
@@ -93,11 +110,11 @@ public struct Card: View {
}
}
- var isContentEmpty: Bool {
+ private var isContentEmpty: Bool {
content is EmptyView
}
- var contentPadding: CGFloat {
+ private var contentPadding: CGFloat {
switch contentLayout {
case .fill: return 0
case .default: return .medium
@@ -105,7 +122,7 @@ public struct Card: View {
}
}
- var contentSpacing: CGFloat {
+ private var contentSpacing: CGFloat {
switch contentLayout {
case .fill: return 0
case .default(let spacing): return spacing
@@ -117,7 +134,7 @@ public struct Card: View {
// MARK: - Inits
public extension Card {
- /// Creates Orbit Card component.
+ /// Creates Orbit ``Card`` component.
init(
_ title: String = "",
description: String = "",
@@ -151,13 +168,13 @@ public extension AccessibilityID {
// MARK: - Types
-/// Specifies the trailing action of Card component.
+/// The trailing action of Orbit ``Card`` header.
public enum CardAction {
case none
case buttonLink(_ label: String, type: ButtonLinkType = .primary, action: () -> Void)
}
-/// Specifies the padding and spacing behavior of Card content.
+/// The layout of Orbit ``Card`` content.
public enum CardContentLayout {
/// Content fills all available space with no padding or spacing.
case fill
diff --git a/Sources/Orbit/Components/CarrierLogo.swift b/Sources/Orbit/Components/CarrierLogo.swift
index 8dd5f50f0e4..c37b63de1d0 100644
--- a/Sources/Orbit/Components/CarrierLogo.swift
+++ b/Sources/Orbit/Components/CarrierLogo.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Displays logos of transport carriers.
+/// Orbit component that displays one or more logos of transport carriers.
///
/// Carrier logos can include up to four logos at once. With one logo, by default it occupies the entire space.
/// With multiple logos, the logos are shrunk to the same size (no matter how many more there are).
@@ -9,98 +9,113 @@ import SwiftUI
/// they’re in the top left and bottom right. With three, the second logo shifts to the bottom left
/// and the third is present in the top right. With four, the logos take up all four corners.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/visuals/carrierlogo/)
-public struct CarrierLogo: View {
-
- struct SingleCarrierImage: View {
-
- let image: Image
-
- init(_ image: Image) {
- self.image = image
- }
-
- var body: some View {
- image
- .resizable()
- .cornerRadius(BorderRadius.desktop)
- }
- }
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/visuals/carrierlogo/)
+public struct CarrierLogo: View, PotentiallyEmptyView {
- let images: [Image]
- let size: Icon.Size
+ private let images: [Image]
+ private let size: Icon.Size
public var body: some View {
content
.frame(width: size.value, height: size.value)
}
- @ViewBuilder var content: some View {
+ @ViewBuilder private var content: some View {
switch images.count {
case 0: EmptyView()
- case 1: SingleCarrierImage(images[0])
+ case 1: SingleCarrierImage(image: images[0])
case 2: twoImages
case 3: threeImages
default: fourImages
}
}
- var twoImages: some View {
+ @ViewBuilder private var twoImages: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
- SingleCarrierImage(images[0])
+ SingleCarrierImage(image: images[0])
Color.clear
}
HStack(spacing: 0) {
Color.clear
- SingleCarrierImage(images[1])
+ SingleCarrierImage(image: images[1])
}
}
}
- var threeImages: some View {
- VStack(spacing: 2) {
- HStack(spacing: 2) {
- SingleCarrierImage(images[0])
- SingleCarrierImage(images[2])
+ @ViewBuilder private var threeImages: some View {
+ VStack(spacing: .xxxSmall) {
+ HStack(spacing: .xxxSmall) {
+ SingleCarrierImage(image: images[0])
+ SingleCarrierImage(image: images[2])
}
- HStack(spacing: 2) {
- SingleCarrierImage(images[1])
+ HStack(spacing: .xxxSmall) {
+ SingleCarrierImage(image: images[1])
Color.clear
}
}
}
- var fourImages: some View {
- VStack(spacing: 2) {
- HStack(spacing: 2) {
- SingleCarrierImage(images[0])
- SingleCarrierImage(images[2])
+ @ViewBuilder private var fourImages: some View {
+ VStack(spacing: .xxxSmall) {
+ HStack(spacing: .xxxSmall) {
+ SingleCarrierImage(image: images[0])
+ SingleCarrierImage(image: images[2])
}
- HStack(spacing: 2) {
- SingleCarrierImage(images[1])
- SingleCarrierImage(images[3])
+ HStack(spacing: .xxxSmall) {
+ SingleCarrierImage(image: images[1])
+ SingleCarrierImage(image: images[3])
}
}
}
+
+ var isEmpty: Bool {
+ images.isEmpty
+ }
+}
+
+// MARK: - Inits
+public extension CarrierLogo {
- /// Creates an Orbit `CarrierLogo` component with a single logo image.
+ /// Creates an Orbit ``CarrierLogo`` component with a single logo image.
+ ///
/// - Parameters:
/// - image: a logo image.
/// - size: the size of the view. The image will occupy the whole view.
- public init(image: Image, size: Icon.Size) {
+ init(image: Image, size: Icon.Size) {
self.images = [image]
self.size = size
}
- /// Creates an Orbit `CarrierLogo` component with multiple images.
+ /// Creates an Orbit ``CarrierLogo`` component with multiple images.
+ ///
/// - Parameter images: logo images to show in the view.
- public init(images: [Image]) {
+ init(images: [Image]) {
self.images = images
self.size = .large
}
}
+// MARK: - Types
+private extension CarrierLogo {
+
+ struct SingleCarrierImage: View {
+
+ let image: Image
+
+ var body: some View {
+ image
+ .resizable()
+ .cornerRadius(BorderRadius.desktop)
+ }
+ }
+}
+
+// MARK: - Previews
struct CarrierLogoPreviews: PreviewProvider {
static let square = Image(systemName: "square.fill")
diff --git a/Sources/Orbit/Components/Checkbox.swift b/Sources/Orbit/Components/Checkbox.swift
index 1455d5fdcfc..d5bd8ab22e2 100644
--- a/Sources/Orbit/Components/Checkbox.swift
+++ b/Sources/Orbit/Components/Checkbox.swift
@@ -1,20 +1,51 @@
import SwiftUI
-/// Enables users to pick multiple options from a group.
+/// Orbit input component that displays a selectable option to pick from multiple selectable options.
+/// A counterpart of the native `SwiftUI.Toggle` with `checkbox` style applied.
///
-/// Can be also used to display just the checkbox with no label or description.
+/// A ``Checkbox`` consists of a title, description and the checkbox indicator.
+///
+/// ```swift
+/// Checkbox("Free", isChecked: $isFree)
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier:
+///
+/// ```swift
+/// Checkbox(isChecked: $isFree)
+/// .disabled()
+/// ```
+///
+/// Before the selection is changed, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Customizing appearance
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/checkbox/)
+/// The title color can be modified by ``textColor(_:)`` modifier:
+///
+/// ```swift
+/// Checkbox("Free", isChecked: $isFree)
+/// .textColor(.blueNormal)
+/// ```
+///
+/// ### Layout
+///
+/// When the provided textual content is empty, the component results in a standalone control.
+///
+/// ```swift
+/// Checkbox(isChecked: $isFree)
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/checkbox/)
public struct Checkbox: View {
- @Environment(\.isEnabled) var isEnabled
- @Environment(\.textColor) var textColor
+ @Environment(\.isEnabled) private var isEnabled
+ @Environment(\.textColor) private var textColor
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
- let title: String
- let description: String
- let state: State
- @Binding var isChecked: Bool
+ private let title: String
+ private let description: String
+ private let state: State
+ @Binding private var isChecked: Bool
public var body: some View {
SwiftUI.Button {
@@ -43,13 +74,13 @@ public struct Checkbox: View {
)
}
- var labelColor: Color {
+ private var labelColor: Color {
isEnabled
? textColor ?? .inkDark
: .cloudDarkHover
}
- var descriptionColor: Color {
+ private var descriptionColor: Color {
isEnabled
? .inkNormal
: .cloudDarkHover
@@ -59,7 +90,7 @@ public struct Checkbox: View {
// MARK: - Inits
public extension Checkbox {
- /// Creates Orbit Checkbox component.
+ /// Creates Orbit ``Checkbox`` component.
init(
_ title: String = "",
description: String = "",
@@ -73,6 +104,7 @@ public extension Checkbox {
// MARK: - Types
public extension Checkbox {
+ /// A state of Orbit ``Checkbox``.
enum State {
case normal
case error
diff --git a/Sources/Orbit/Components/ChoiceTile.swift b/Sources/Orbit/Components/ChoiceTile.swift
index ab7bbd79cdd..9d2cc459f45 100644
--- a/Sources/Orbit/Components/ChoiceTile.swift
+++ b/Sources/Orbit/Components/ChoiceTile.swift
@@ -1,9 +1,50 @@
import SwiftUI
-/// Enables users to encapsulate radio or checkbox to pick exactly one option from a group.
+/// Orbit input component that displays a rich selectable option to pick from a single or multiple selection group.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/choice-tile/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// A ``ChoiceTile`` consists of a title, description, icon, content and a selection indicator.
+///
+/// ```swift
+/// ChoiceTile("Full", isSelected: $isFull) {
+/// // Tap action
+/// } content: {
+/// // Content
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The title and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// The default background can be overridden by ``backgroundStyle(_:)-9odue`` modifier.
+///
+/// ```swift
+/// ChoiceTile("Full", icon: .informationCircle, isSelected: $isFull) {
+/// // Tap action
+/// }
+/// .textColor(.blueDark)
+/// .iconColor(.inkNormal)
+/// .iconSize(.small)
+/// .backgroundStyle(.cloudLight)
+/// ```
+///
+/// A ``Status`` can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// ChoiceTile("Not available") {
+/// // Tap action
+/// }
+/// .status(.critical)
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/choice-tile/)
public struct ChoiceTile: View {
@Environment(\.backgroundShape) private var backgroundShape
@@ -11,22 +52,20 @@ public struct ChoiceTile Void
- @ViewBuilder let content: Content
- @ViewBuilder let icon: Icon
- @ViewBuilder let header: Header
- @ViewBuilder let illustration: Illustration
+ private let title: String
+ private let description: String
+ private let badgeOverlay: String
+ private let indicator: ChoiceTileIndicator
+ private let titleStyle: Heading.Style
+ private let isSelected: Bool
+ private let isError: Bool
+ private let message: Message?
+ private let alignment: ChoiceTileAlignment
+ private let action: () -> Void
+ @ViewBuilder private let content: Content
+ @ViewBuilder private let icon: Icon
+ @ViewBuilder private let header: Header
+ @ViewBuilder private let illustration: Illustration
public var body: some View {
SwiftUI.Button {
@@ -37,7 +76,7 @@ public struct ChoiceTile: View {
- let headerVerticalPadding: CGFloat
- let showSeparator: Bool
- let isExpanded: Binding?
- @ViewBuilder let content: Content
- @ViewBuilder let header: Header
+ private let headerVerticalPadding: CGFloat
+ private let showSeparator: Bool
+ private let isExpanded: Binding?
+ @ViewBuilder private let content: Content
+ @ViewBuilder private let header: Header
public var body: some View {
BindingSource(isExpanded, fallbackInitialValue: false) { $isExpanded in
@@ -41,16 +49,18 @@ public struct Collapse: View {
}
}
- @ViewBuilder var separator: some View {
+ @ViewBuilder private var separator: some View {
if showSeparator {
Separator()
}
}
}
+// MARK: - Inits
+
public extension Collapse {
- /// Creates Orbit Collapse component with a binding to the expansion state.
+ /// Creates Orbit ``Collapse`` component with a binding to the expansion state.
init(
isExpanded: Binding,
showSeparator: Bool = true,
@@ -64,7 +74,7 @@ public extension Collapse {
self.isExpanded = isExpanded
}
- /// Creates Orbit Collapse component.
+ /// Creates Orbit ``Collapse`` component.
init(@ViewBuilder content: () -> Content, showSeparator: Bool = true, @ViewBuilder header: () -> Header) {
self.header = header()
self.headerVerticalPadding = 0
@@ -76,7 +86,7 @@ public extension Collapse {
public extension Collapse where Header == Text {
- /// Creates Orbit Collapse component with a binding to the expansion state.
+ /// Creates Orbit ``Collapse`` component with a binding to the expansion state.
init(_ title: String, isExpanded: Binding, showSeparator: Bool = true, @ViewBuilder content: () -> Content) {
self.header = Text(title)
self.headerVerticalPadding = .small
@@ -85,7 +95,7 @@ public extension Collapse where Header == Text {
self.isExpanded = isExpanded
}
- /// Creates Orbit Collapse component.
+ /// Creates Orbit ``Collapse`` component.
init(_ title: String, showSeparator: Bool = true, @ViewBuilder content: () -> Content) {
self.header = Text(title)
self.headerVerticalPadding = .small
diff --git a/Sources/Orbit/Components/CountryFlag.swift b/Sources/Orbit/Components/CountryFlag.swift
index b945581eff4..c42217f48fd 100644
--- a/Sources/Orbit/Components/CountryFlag.swift
+++ b/Sources/Orbit/Components/CountryFlag.swift
@@ -1,23 +1,27 @@
import SwiftUI
-/// Displays flags of countries from around the world.
-///
-/// The component is sized in a similar way as `Icon`, using `iconSize()` modifier.
+/// Orbit component that displays flag of a country.
///
/// ```swift
/// CountryFlag(.us)
/// .iconSize(.large)
/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/countryflag/)
+/// ### Layout
+///
+/// The component size can be modified by ``iconSize(_:)`` modifier.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/countryflag/)
public struct CountryFlag: View, PotentiallyEmptyView {
- @Environment(\.textSize) var textSize
- @Environment(\.iconSize) var iconSize
- @Environment(\.sizeCategory) var sizeCategory
+ @Environment(\.textSize) private var textSize
+ @Environment(\.iconSize) private var iconSize
+ @Environment(\.sizeCategory) private var sizeCategory
- let countryCode: CountryCode?
- let border: Border
+ private let countryCode: CountryCode?
+ private let border: Border
public var body: some View {
if let countryCode {
@@ -35,12 +39,16 @@ public struct CountryFlag: View, PotentiallyEmptyView {
.accessibility(label: SwiftUI.Text(countryCode.rawValue))
}
}
+
+ var isEmpty: Bool {
+ countryCode == nil
+ }
- var clipShape: some InsettableShape {
+ private var clipShape: some InsettableShape {
RoundedRectangle(cornerRadius: cornerRadius)
}
- var cornerRadius: CGFloat {
+ private var cornerRadius: CGFloat {
switch border {
case .none: return 0
case .default(let cornerRadius?): return cornerRadius
@@ -48,19 +56,15 @@ public struct CountryFlag: View, PotentiallyEmptyView {
}
}
- var size: CGFloat {
+ private var size: CGFloat {
(iconSize ?? textSize.map(Icon.Size.fromTextSize(size:)) ?? Icon.Size.normal.value) * sizeCategory.ratio
}
-
- var isEmpty: Bool {
- countryCode == nil
- }
}
// MARK: - Inits
public extension CountryFlag {
- /// Creates Orbit CountryFlag component.
+ /// Creates Orbit ``CountryFlag`` component.
init(_ countryCode: CountryCode, border: Border = .default()) {
self.init(
countryCode: countryCode,
@@ -68,9 +72,9 @@ public extension CountryFlag {
)
}
- /// Creates Orbit CountryFlag component with a string country code.
+ /// Creates Orbit ``CountryFlag`` component using a country code string.
///
- /// If a corresponding image is not found, the flag for unknown codes is used.
+ /// - Note: If a corresponding image is not found, the flag for unknown flag is used.
init(_ countryCode: String, border: Border = .default()) {
self.init(
countryCode: countryCode.isEmpty ? nil : .init(countryCode),
@@ -82,6 +86,7 @@ public extension CountryFlag {
// MARK: - Types
public extension CountryFlag {
+ /// Orbit ``CountryFlag`` border.
enum Border {
case none
case `default`(cornerRadius: CGFloat? = nil)
@@ -94,6 +99,7 @@ public extension CountryFlag {
}
}
+ /// Orbit ``CountryFlag`` size.
enum Size {
case width(_ width: CGFloat)
case icon(_ size: Icon.Size = .normal)
diff --git a/Sources/Orbit/Components/Coupon.swift b/Sources/Orbit/Components/Coupon.swift
index 47de1ac97c2..09c96b3ea94 100644
--- a/Sources/Orbit/Components/Coupon.swift
+++ b/Sources/Orbit/Components/Coupon.swift
@@ -1,9 +1,19 @@
import SwiftUI
-/// Orbit component that highlights promo codes.
+/// Orbit component that displays promo codes.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/visuals/coupon/)
-public struct Coupon: View {
+/// ```swift
+/// Coupon("HXT3B81F")
+/// .textColor(.blueDark)
+/// .textSize(.small)
+/// ```
+///
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/visuals/coupon/)
+public struct Coupon: View, PotentiallyEmptyView {
@Environment(\.textSize) private var textSize
@@ -22,12 +32,16 @@ public struct Coupon: View {
.foregroundColor(.cloudDark)
)
}
+
+ var isEmpty: Bool {
+ label.isEmpty
+ }
}
// MARK: - Inits
public extension Coupon {
- /// Creates Orbit Coupon component.
+ /// Creates Orbit ``Coupon`` component.
init(_ label: String = "") {
self.label = label
}
diff --git a/Sources/Orbit/Components/Dialog.swift b/Sources/Orbit/Components/Dialog.swift
index 9812e4e94fb..e825524c1b8 100644
--- a/Sources/Orbit/Components/Dialog.swift
+++ b/Sources/Orbit/Components/Dialog.swift
@@ -1,20 +1,50 @@
import SwiftUI
-/// Prompts users to take or complete an action.
+/// Orbit component that prompts user to complete an action.
+/// A counterpart of the native `alert()` modifier.
///
-/// Use at most three actions in a Dialog. A Dialog expands both horizontally
-/// and vertically and is meant to be used as a modal fullscreen overlay.
+/// A ``Dialog`` consists of a title, description, illustration, at most three buttons and an optional custom content.
///
/// ```swift
/// Dialog("Title") {
-/// Button("Primary") { /* */ }
-/// Button("Secondary") { /* */ }
-/// Button("Tertiary") { /* */ }
+/// // Content
+/// } buttons: {
+/// Button("Primary") { /* Tap action */ }
+/// Button("Secondary") { /* Tap action */ }
+/// Button("Tertiary") { /* Tap action */ }
+/// } illustration: {
+/// Illustration(.accommodation)
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// A ``Status`` of buttons can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// Dialog("Title") {
+/// Button("Primary") { /* Tap action */ }
+/// Button("Secondary") { /* Tap action */ }
/// }
/// .status(.critical)
/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/overlay/dialog/)
+/// The default button priority can be overridden by ``buttonPriority(_:)`` modifier:
+///
+/// ```swift
+/// Dialog("Title") {
+/// Button("Secondary Only") {
+/// // Tap action
+/// }
+/// .buttonPriority(.secondary)
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// The component expands in both axis and is meant to be used as a fullscreen modal overlay.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/overlay/dialog/)
public struct Dialog: View {
private let title: String
@@ -51,7 +81,7 @@ public struct Dialog: View {
.accessibilityElement(children: .contain)
}
- @ViewBuilder var texts: some View {
+ @ViewBuilder private var texts: some View {
if title.isEmpty == false || description.isEmpty == false {
VStack(alignment: .leading, spacing: .xSmall) {
Heading(title, style: .title4)
@@ -64,7 +94,7 @@ public struct Dialog: View {
}
}
- var shape: some InsettableShape {
+ private var shape: some InsettableShape {
RoundedRectangle(cornerRadius: .small)
}
}
@@ -72,7 +102,7 @@ public struct Dialog: View {
// MARK: - Inits
extension Dialog {
- /// Creates Orbit Dialog component.
+ /// Creates Orbit ``Dialog`` component.
public init(
_ title: String = "",
description: String = "",
diff --git a/Sources/Orbit/Components/EmptyState.swift b/Sources/Orbit/Components/EmptyState.swift
index 693e75fdec0..5b578ada04a 100644
--- a/Sources/Orbit/Components/EmptyState.swift
+++ b/Sources/Orbit/Components/EmptyState.swift
@@ -1,15 +1,41 @@
import SwiftUI
-/// Indicates when there’s no data to show, like when a search has no results.
+/// Orbit component that indicates there is no data to display.
+/// A counterpart of the native `SwiftUI.ContentUnavailableView`.
+///
+/// An ``EmptyState`` consists of a title, description, icon, optional custom content and at most two actions.
///
/// ```swift
-/// EmptyState("No items") {
-/// Button("Add item") { /* */ }
+/// EmptyState("No travelers") {
+/// Button("Add new traveler") { /* Tap action */ }
/// }
-/// .status(.critical)
/// ```
+///
+/// ### Customizing appearance
+///
+/// The title color can be modified by ``textColor(_:)`` modifier.
+///
+/// A ``Status`` of buttons can be modified by ``status(_:)`` modifier:
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/progress-indicators/emptystate/)
+/// ```swift
+/// EmptyState("No data") {
+/// Button("Add item") { /* Tap action */ }
+/// }
+/// .status(.warning)
+/// ```
+///
+/// The default button priority can be overridden by ``buttonPriority(_:)`` modifier:
+///
+/// ```swift
+/// EmptyState("No data") {
+/// Button("Secondary Only") {
+/// // Tap action
+/// }
+/// .buttonPriority(.secondary)
+/// }
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/progress-indicators/emptystate/)
public struct EmptyState: View {
private let title: String
@@ -61,7 +87,7 @@ public struct EmptyState: View
// MARK: - Inits
public extension EmptyState {
- /// Creates Orbit EmptyState component.
+ /// Creates Orbit ``EmptyState`` component.
init(
_ title: String = "",
description: String = "",
@@ -78,7 +104,7 @@ public extension EmptyState {
}
}
- /// Creates Orbit EmptyState component with no action.
+ /// Creates Orbit ``EmptyState`` component with no action.
init(
_ title: String = "",
description: String = "",
diff --git a/Sources/Orbit/Components/Heading.swift b/Sources/Orbit/Components/Heading.swift
index 736cc81f135..2de31d67ef4 100644
--- a/Sources/Orbit/Components/Heading.swift
+++ b/Sources/Orbit/Components/Heading.swift
@@ -1,8 +1,69 @@
import SwiftUI
-/// Shows the content hierarchy and improves the reading experience. Also known as Title.
+/// Orbit component that displays title that helps to define content hierarchy.
+/// A counterpart of the native `SwiftUI.Text` with one of the title font styles applied.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/heading/)
+/// A ``Heading`` is created using one of predefined title styles.
+///
+/// ```swift
+/// Heading("Passengers", style: .title2)
+/// ```
+///
+/// ### Customizing appearance
+///
+/// Textual properties can be modified in two ways:
+/// - Modifiers applied directly to `Heading` that return the same type, such as ``textColor(_:)-80ix5`` or ``textAccentColor(_:)-k54u``.
+/// These can also be used for concatenation with other Orbit textual components like ``Text`` or ``Icon``.
+/// See the `InstanceMethods` section below for full list.
+/// - Modifiers applied to view hierarchy, such as ``textColor(_:)-828ud`` or ``textIsCopyable(_:)``.
+/// See a full list of `View` extensions in documentation.
+///
+/// ```swift
+/// VStack {
+/// // Will result in `inkNormal` color
+/// Heading("Override", type: .title3)
+/// .textColor(.inkNormal)
+///
+/// // Will result in `blueDark` color passed from environment
+/// Heading("Modified", type: .title3)
+///
+/// // Will result in a default `inkDark` color, ignoring the environment value
+/// Heading("Default", type: .title3)
+/// .textColor(nil)
+///
+/// // Will result in mixed `redNormal` and `blueDark` colors
+/// Heading("Concatenated", type: .title3)
+/// .textColor(.redNormal)
+/// + Heading(" Title", type: .title2)
+/// .bold()
+/// + Icon(.grid)
+/// .iconColor(.redNormal)
+/// }
+/// .textColor(.blueDark)
+/// ```
+///
+/// Formatting and behaviour for ``TextLink``s found in the text can be modified by ``textLinkAction(_:)`` and
+/// ``textLinkColor(_:)`` modifiers.
+///
+/// ```swift
+/// Heading("Information for Passenger", type: .title3)
+/// .textLinkColor(.inkNormal)
+/// .textLinkAction {
+/// // TextLink tap Action
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// Orbit text components use a designated vertical padding that is the same in both single and multiline variant.
+/// This makes it easier to align them consistently next to other Orbit components like ``Icon`` not only based on the baseline,
+/// but also by `top` or `bottom` edges, provided the component text sizes match according to Orbit rules.
+///
+/// Orbit text components have a fixed vertical size.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/heading/)
public struct Heading: View, FormattedTextBuildable {
// Builder properties
@@ -27,7 +88,7 @@ public struct Heading: View, FormattedTextBuildable {
.accessibility(addTraits: .isHeader)
}
- @ViewBuilder var textContent: Text {
+ @ViewBuilder private var textContent: Text {
Text(content)
.textColor(color)
.textSize(custom: style.size)
@@ -47,15 +108,11 @@ public struct Heading: View, FormattedTextBuildable {
// MARK: - Inits
public extension Heading {
- /// Creates Orbit Heading component.
- ///
- /// Modifiers like `textAccentColor()` or `italic()` can be used to further adjust the formatting.
- /// To specify the formatting and behaviour for `TextLink`s found in the text, use `textLinkAction()` and
- /// `textLinkColor()` modifiers.
+ /// Creates Orbit ``Heading`` component.
///
/// - Parameters:
/// - content: String to display. Supports html formatting tags ``, ``, `[`, `` and ``.
- /// - style: Heading style.
+ /// - style: A predefined title style.
init(
_ content: String,
style: Style,
@@ -72,7 +129,7 @@ public extension Heading {
// MARK: - Types
public extension Heading {
- /// Orbit heading style.
+ /// Orbit ``Heading`` style that represents the default size and color of a title.
enum Style: Equatable {
/// 28 pts.
case title1
@@ -87,7 +144,7 @@ public extension Heading {
/// 13 pts.
case title6
- /// Text font size value.
+ /// Orbit `Heading` ``Heading/Style`` font size.
public var size: CGFloat {
switch self {
case .title1: return 28
@@ -99,7 +156,7 @@ public extension Heading {
}
}
- /// Designated line height.
+ /// Orbit `Heading` ``Heading/Style`` designated line height.
public var lineHeight: CGFloat {
switch self {
case .title1: return 32
@@ -111,6 +168,7 @@ public extension Heading {
}
}
+ /// Orbit `Heading` ``Heading/Style`` font weight.
public var weight: Font.Weight {
switch self {
case .title1, .title4, .title5, .title6: return .bold
diff --git a/Sources/Orbit/Components/HorizontalScroll.swift b/Sources/Orbit/Components/HorizontalScroll.swift
index 90be84f31e1..48c5fcc9c35 100644
--- a/Sources/Orbit/Components/HorizontalScroll.swift
+++ b/Sources/Orbit/Components/HorizontalScroll.swift
@@ -1,18 +1,42 @@
import SwiftUI
import Combine
-public enum HorizontalScrollItemWidth {
- /// Width ratio calculated from the available container width.
- case ratio(CGFloat = 0.48, maxWidth: CGFloat? = Layout.readableMaxWidth - 270)
- /// Custom fixed width.
- case fixed(CGFloat)
-}
-
-/// Groups items onto one accessible row even on small screens.
+/// Orbit component that groups items onto one accessible scrollable row.
+/// In contrast to the native horizontal `SwiftUI.ScrollView`, this component offers snapping to item leading edges both manually and programmatically.
+///
+/// A ``HorizontalScroll`` consists of provided content that will be arranged horizontally with the consistent item width and provided spacing.
+///
+/// ```swift
+/// HorizontalScroll {
+/// Tile("Choice 1")
+/// Tile("Choice 2")
+/// Tile("Choice 3")
+/// }
+/// ```
+///
+/// The content can be scrolled programatically when wrapped inside ``HorizontalScrollReader``.
+///
+/// ```swift
+/// HorizontalScrollReader { scrollProxy in
+/// HorizontalScroll {
+/// Tile("Choice 1")
+/// Tile("Choice 2")
+/// Tile("Choice 3")
+/// }
+///
+/// Button("Scroll to first choice") {
+/// scrollProxy.scrollTo(0)
+/// }
+/// }
+/// ```
///
-/// Can be used to present similar items (such as cards with baggage options) as a single row even on small screens.
+/// ### Layout
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/layout/horizontalscroll/)
+/// The component adds `HStack` over the provided content.
+///
+/// Component expands horizontally and has a layout similar to the native `ScrollView` with `horizontal` scrollable axis.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/layout/horizontalscroll/)
public struct HorizontalScroll: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@@ -37,10 +61,10 @@ public struct HorizontalScroll: View {
private let snapAnimationDuration: CGFloat = 0.8
private let programaticSnapAnimationDuration: CGFloat = 0.5
- let spacing: CGFloat
- let isSnapping: Bool
- let itemWidth: HorizontalScrollItemWidth
- @ViewBuilder let content: Content
+ private let spacing: CGFloat
+ private let isSnapping: Bool
+ private let itemWidth: HorizontalScrollItemWidth
+ @ViewBuilder private let content: Content
public var body: some View {
scrollViewContent
@@ -53,7 +77,7 @@ public struct HorizontalScroll: View {
.padding(-clippingPadding)
}
- @ViewBuilder var scrollViewContent: some View {
+ @ViewBuilder private var scrollViewContent: some View {
GeometryReader { geometry in
HStack(alignment: .top, spacing: spacing) {
content
@@ -102,7 +126,7 @@ public struct HorizontalScroll: View {
}
}
- @ViewBuilder var contentHeightReader: some View {
+ @ViewBuilder private var contentHeightReader: some View {
GeometryReader { geometry in
Color.clear.preference(
key: ContentSizePreferenceKey.self,
@@ -111,17 +135,17 @@ public struct HorizontalScroll: View {
}
}
- @ViewBuilder var availableWidthReader: some View {
+ @ViewBuilder private var availableWidthReader: some View {
SingleAxisGeometryReader(axis: .horizontal) { width in
Color.clear.preference(key: ScrollViewWidthPreferenceKey.self, value: width)
}
}
- var isIdle: Bool {
+ private var isIdle: Bool {
(scrollingInProgress || isAnimating) == false
}
- var screenLayoutHorizontalPadding: CGFloat {
+ private var screenLayoutHorizontalPadding: CGFloat {
guard let screenLayoutPadding = screenLayoutPadding else {
return spacing
}
@@ -129,7 +153,7 @@ public struct HorizontalScroll: View {
return screenLayoutPadding.horizontal(horizontalSizeClass: horizontalSizeClass)
}
- var scrollingGesture: some Gesture {
+ private var scrollingGesture: some Gesture {
DragGesture(minimumDistance: .xxxSmall)
.onChanged { gesture in
updateOffset(gesture: gesture)
@@ -139,22 +163,22 @@ public struct HorizontalScroll: View {
}
}
- var scrollStoppingGesture: some Gesture {
+ private var scrollStoppingGesture: some Gesture {
TapGesture()
.onEnded {
stopSnappingAnimation()
}
}
- var isContentBiggerThanScrollView: Bool {
+ private var isContentBiggerThanScrollView: Bool {
contentSize.width > scrollViewWidth
}
- var maxOffset: CGFloat {
+ private var maxOffset: CGFloat {
-contentSize.width + scrollViewWidth
}
- var resolvedItemWidth: CGFloat {
+ private var resolvedItemWidth: CGFloat {
switch itemWidth {
case .ratio(let ratio, let maxWidth):
let ratio = max(0.05, ratio)
@@ -313,15 +337,13 @@ public struct HorizontalScroll: View {
// MARK: - Inits
public extension HorizontalScroll {
- /// Creates Orbit HorizontalScroll component.
- ///
- /// Can be scrolled programatically when wrapped inside `HorizontalScrollReader`.
+ /// Creates Orbit ``HorizontalScroll`` component.
///
/// - Parameters:
/// - isSnapping: Specifies whether the scrolling should snap items to their leading edge.
/// - spacing: Spacing between items.
/// - itemWidth: Horizontal sizing of each item.
- /// - content: Child items that will be horizontally laid out based on above parameters.
+ /// - content: Items that will be arranged horizontally based on above parameters.
init(
isSnapping: Bool = true,
spacing: CGFloat = .small,
@@ -335,6 +357,16 @@ public extension HorizontalScroll {
}
}
+// MARK: - Types
+
+/// Width for all items used in Orbit ``HorizontalScroll``.
+public enum HorizontalScrollItemWidth {
+ /// Width ratio calculated from the available container width.
+ case ratio(CGFloat = 0.48, maxWidth: CGFloat? = Layout.readableMaxWidth - 270)
+ /// Custom fixed width.
+ case fixed(CGFloat)
+}
+
// MARK: - Preference keys
private struct ScrollViewWidthPreferenceKey: PreferenceKey {
diff --git a/Sources/Orbit/Components/Icon.swift b/Sources/Orbit/Components/Icon.swift
index dc50970b5c1..28230817cff 100644
--- a/Sources/Orbit/Components/Icon.swift
+++ b/Sources/Orbit/Components/Icon.swift
@@ -1,30 +1,58 @@
import SwiftUI
-/// An Orbit Icon component.
+/// Orbit component that displays an icon.
+/// A counterpart of the native SF Symbols represented by the native `SwiftUI.Image` created using `systemName` parameter.
///
-/// Icon is concatenable with Text and Heading components, allowing the construction of multiline texts that include icons.
-/// Apart from Orbit symbol, an Icon can be constructed from SF Symbol with matching Orbit icon size.
+/// An ``Icon`` is created using predefined Orbit ``Icon/Symbol``.
///
/// ```swift
-/// Text("2") + Icon("multiply") + Icon(.baggage)
+/// Icon(.accomodation)
/// ```
///
-/// Icon can be further styled using either `Icon` modifiers or global modifiers `iconColor`, `textColor`, `textFontWeight`, `baselineOffset`.
+/// The ``Icon`` can also be created using SF Symbol `String` to make it possible to mix with Orbit components.
///
/// ```swift
-/// VStack {
-/// Icon(.grid)
-/// .iconColor(nil)
+/// Icon(systemName: "pencil.circle")
+/// ```
+///
+/// ### Customizing appearance
///
-/// Icon("circle.fill")
-/// .fontWeight(.bold)
-/// .baselineOffset(-2)
+/// Icon properties can be modified in two ways:
+/// - Modifiers applied directly to `Icon` that return the same type, such as ``iconColor(_:)-1h3pr`` or ``iconSize(_:)-4p0n3``.
+/// These can also be used for concatenation with other Orbit textual components like ``Heading`` or ``Text``.
+/// See the `InstanceMethods` section below for full list.
+/// - Modifiers applied to view hierarchy, such as ``iconColor(_:)-e48e`` or ``iconSize(_:)-1pg82``.
+/// See a full list of `View` extensions in documentation.
+///
+/// ```swift
+/// VStack {
+/// // Will result in `inkNormal` color
+/// Icon(.grid)
+/// .iconColor(.inkNormal)
+///
+/// // Will result in `blueDark` color passed from environment
+/// Icon(.grid)
+///
+/// // Will result in a default `inkDark` color, ignoring the environment value
+/// Icon(.grid)
+/// .iconColor(nil)
+///
+/// // Will result in mixed `redNormal` and `blueDark` colors
+/// Icon(.accomodation)
+/// .iconColor(.redNormal)
+/// + Icon(.grid)
+/// .baselineOffset(-2)
+/// + Text(" concatenated ")
+/// .bold()
/// }
-/// .iconColor(.redNormal)
-/// .textFontWeight(.medium)
+/// .textColor(.blueDark)
/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/icon/)
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/icon/)
public struct Icon: View, TextBuildable, PotentiallyEmptyView {
/// Approximate size ratio between SF Symbol and Orbit icon symbol.
@@ -40,9 +68,9 @@ public struct Icon: View, TextBuildable, PotentiallyEmptyView {
@Environment(\.textFontWeight) private var textFontWeight
@Environment(\.textSize) private var textSize
@Environment(\.sizeCategory) private var sizeCategory
-
+
private let content: Content?
-
+
// Builder properties
var baselineOffset: CGFloat?
var fontWeight: Font.Weight?
@@ -73,6 +101,10 @@ public struct Icon: View, TextBuildable, PotentiallyEmptyView {
.alignmentGuide(.lastTextBaseline) { $0[.lastTextBaseline] + resolvedBaselineOffset }
}
}
+
+ var isEmpty: Bool {
+ content?.isEmpty ?? true
+ }
private var textRepresentableEnvironment: TextRepresentableEnvironment {
.init(
@@ -86,11 +118,7 @@ public struct Icon: View, TextBuildable, PotentiallyEmptyView {
sizeCategory: sizeCategory
)
}
-
- public var isEmpty: Bool {
- content?.isEmpty ?? true
- }
-
+
private func sfSymbolFont(_ textRepresentableEnvironment: TextRepresentableEnvironment) -> Font {
.system(
size: sfSymbolSize(textRepresentableEnvironment) * textRepresentableEnvironment.sizeCategory.ratio,
@@ -133,12 +161,12 @@ public struct Icon: View, TextBuildable, PotentiallyEmptyView {
// MARK: - Inits
public extension Icon {
- /// Creates Orbit Icon component for provided Orbit symbol.
+ /// Creates Orbit ``Icon`` component.
init(_ symbol: Icon.Symbol?) {
self.init(symbol.map { Icon.Content.symbol($0) })
}
- /// Creates Orbit Icon component for provided SF Symbol that matches the Orbit symbol sizing, reflecting the Dynamic Type settings.
+ /// Creates Orbit ``Icon`` component for provided SF Symbol that matches the Orbit symbol sizing, reflecting the Dynamic Type settings.
init(_ systemName: String) {
self.init(.sfSymbol(systemName))
}
@@ -147,7 +175,7 @@ public extension Icon {
// MARK: - Types
public extension Icon {
- /// Preferred icon size in both dimensions. Actual size may differ based on icon content.
+ /// Preferred Orbit ``Icon`` size in both dimensions. The actual size may differ based on icon content.
enum Size: Equatable {
/// Size 16.
case small
@@ -158,6 +186,7 @@ public extension Icon {
/// Size 28.
case xLarge
+ /// Orbit `Icon` ``Icon/Size`` value.
public var value: CGFloat {
switch self {
case .small: return 16
@@ -167,7 +196,7 @@ public extension Icon {
}
}
- /// Icon size matching text line height.
+ /// Orbit `Icon` ``Icon/Size`` matching the text size.
public static func fromTextSize(size: CGFloat) -> CGFloat {
Text.Size.lineHeight(forTextSize: size)
}
@@ -202,7 +231,7 @@ extension Icon: TextRepresentable {
}
@available(iOS 14.0, *)
- func text(textRepresentableEnvironment: TextRepresentableEnvironment) -> SwiftUI.Text? {
+ private func text(textRepresentableEnvironment: TextRepresentableEnvironment) -> SwiftUI.Text? {
switch content {
case .none:
return nil
diff --git a/Sources/Orbit/Components/InputField.swift b/Sources/Orbit/Components/InputField.swift
index 94b621e65a0..77270ffa973 100644
--- a/Sources/Orbit/Components/InputField.swift
+++ b/Sources/Orbit/Components/InputField.swift
@@ -1,21 +1,22 @@
import SwiftUI
import UIKit
-/// Orbit component that offers a simple text input. The component is an equivalent of the native `TextField` component.
+/// Orbit input component that that displays a single-line text input control.
+/// A counterpart of the native `SwiftUI.TextField`.
+///
+/// The ``InputField`` consists of a label, message and a binding to a string value:
///
-/// The InputField is created with an optional label and a binding to a string value.
-///
/// ```swift
/// InputField("Label", value: $email, prompt: "E-mail")
/// .keyboardType(.emailAddress)
/// .returnKeyType(.done)
/// .focused($isEmailFocused)
/// .inputFieldReturnAction {
-/// // Action after the value is submitted
+/// // Submit action
/// }
/// ```
///
-/// For secure version, the `passwordStrength` hint can be provided.
+/// For secure version, the `passwordStrength` hint can be provided:
///
/// ```swift
/// InputField(
@@ -27,13 +28,25 @@ import UIKit
/// )
/// ```
///
-/// The component uses a custom ``TextField`` component (implemented using `UITextField`) that represents the native `TextField`.
+/// In order to instantly switch focus between text fields on submit,
+/// return `false` from the ``inputFieldShouldReturnAction(_:)-82nse`` after switching the focus.
///
+/// ```swift
+/// InputField("Label", value: $email, prompt: "E-mail")
+/// .focused($focus, equals: .email)
+/// .inputFieldShouldReturnAction {
+/// focus = .name
+/// return false
+/// }
+/// ```
+///
+/// The component uses a custom ``TextField`` component (implemented using `UITextField`).
+///
/// ### Layout
///
/// The component expands horizontally.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/inputfield/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/inputfield/)
public struct InputField: View, TextFieldBuildable {
@Environment(\.inputFieldBeginEditingAction) private var inputFieldBeginEditingAction
diff --git a/Sources/Orbit/Components/KeyValue.swift b/Sources/Orbit/Components/KeyValue.swift
index 551d98a8e1d..04de6de4d94 100644
--- a/Sources/Orbit/Components/KeyValue.swift
+++ b/Sources/Orbit/Components/KeyValue.swift
@@ -1,13 +1,25 @@
import SwiftUI
-/// A pair of label and value to display read-only information.
+/// Orbit component that displays a pair of label and a value.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/keyvalue/)
+/// A ``KeyValue`` consists of a label and a value that is copyable by default.
+///
+/// ```swift
+/// KeyValue("First Name", value: "Pavel")
+/// ```
+///
+/// ### Layout
+///
+/// The text alignment can be modified by ``multilineTextAlignment(_:)``.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/keyvalue/)
public struct KeyValue: View, PotentiallyEmptyView {
- let key: String
- let value: String
- let size: Size
+ private let key: String
+ private let value: String
+ private let size: Size
public var body: some View {
if isEmpty == false {
@@ -32,7 +44,7 @@ public struct KeyValue: View, PotentiallyEmptyView {
// MARK: - Inits
extension KeyValue {
- /// Creates Orbit KeyValue component.
+ /// Creates Orbit ``KeyValue`` component.
public init(
_ key: String = "",
value: String = "",
@@ -47,6 +59,7 @@ extension KeyValue {
// MARK: - Types
extension KeyValue {
+ /// Orbit ``KeyValue`` size.
public enum Size {
case normal
case large
diff --git a/Sources/Orbit/Components/List.swift b/Sources/Orbit/Components/List.swift
index 677d18359e5..5ed7e0cccff 100644
--- a/Sources/Orbit/Components/List.swift
+++ b/Sources/Orbit/Components/List.swift
@@ -1,21 +1,38 @@
import SwiftUI
-/// Shows related items.
+/// Orbit component that displays vertically arranged related items.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/list/)
+/// A ``List`` typically consists of ``ListItem`` content.
+///
+/// ```swift
+/// List {
+/// ListItem("Planes", icon: .airplane)
+/// ListItem("Trains")
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// The component arranges list items in a `VStack` aligned to `leading` edge.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/list/)
public struct List: View {
- let spacing: CGFloat
- @ViewBuilder let content: Content
+ private let spacing: CGFloat
+ @ViewBuilder private let content: Content
public var body: some View {
VStack(alignment: .leading, spacing: spacing) {
content
}
}
+}
- /// Creates Orbit List component, wrapping ListItem content.
- public init(spacing: CGFloat = .xSmall, @ViewBuilder content: () -> Content) {
+// MARK: - Inits
+public extension List {
+
+ /// Creates Orbit ``List`` component that wraps ``ListItem`` content.
+ init(spacing: CGFloat = .xSmall, @ViewBuilder _ content: () -> Content) {
self.spacing = spacing
self.content = content()
}
diff --git a/Sources/Orbit/Components/ListChoice.swift b/Sources/Orbit/Components/ListChoice.swift
index 0e2640889e3..839e25d6357 100644
--- a/Sources/Orbit/Components/ListChoice.swift
+++ b/Sources/Orbit/Components/ListChoice.swift
@@ -1,25 +1,78 @@
import SwiftUI
-/// Shows one of a selectable list of items with similar structures.
+/// Orbit input component that displays a selectable row as a choice in a group of similar items.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/listchoice/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// A ``ListChoice`` consists of a title, description, icon, disclosure and content.
+///
+/// ```swift
+/// ListChoice("Profile", icon: .user) {
+/// // Tap action
+/// } content: {
+/// // Content
+/// }
+/// ```
+///
+/// A secondary header content can be provided using `String` value:
+///
+/// ```swift
+/// ListChoice(title, description: description, value: value) {
+/// // Tap action
+/// }
+/// ```
+///
+/// or using a custom content:
+///
+/// ```swift
+/// ListChoice(title, description: description, icon: .user) {
+/// // Tap action
+/// } content: {
+/// // Custom content
+/// } header: {
+/// // Header trailing content
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The title and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// The default background can be overridden by ``backgroundStyle(_:)-9odue`` modifier.
+///
+/// A ``Status`` can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// ListChoice("Not available") {
+/// // Action
+/// }
+/// .status(.critical)
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/listchoice/)
public struct ListChoice: View, PotentiallyEmptyView {
- public let verticalPadding: CGFloat = .small // = 45 height @ normal size
+ private let verticalPadding: CGFloat = .small // = 45 height @ normal size
@Environment(\.idealSize) private var idealSize
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
- let title: String
- let description: String
- let value: String
- let disclosure: ListChoiceDisclosure
- let showSeparator: Bool
- let action: () -> Void
- @ViewBuilder let content: Content
- @ViewBuilder let icon: Icon
- @ViewBuilder let header: Header
+ private let title: String
+ private let description: String
+ private let value: String
+ private let disclosure: ListChoiceDisclosure
+ private let showSeparator: Bool
+ private let action: () -> Void
+ @ViewBuilder private let content: Content
+ @ViewBuilder private let icon: Icon
+ @ViewBuilder private let header: Header
public var body: some View {
if isEmpty == false {
@@ -45,7 +98,7 @@ public struct ListChoice: View, Potenti
}
}
- @ViewBuilder var buttonContent: some View {
+ @ViewBuilder private var buttonContent: some View {
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: 0) {
headerRow
@@ -64,7 +117,7 @@ public struct ListChoice: View, Potenti
.frame(maxWidth: idealSize.horizontal == true ? nil : .infinity, alignment: .leading)
}
- @ViewBuilder var headerRow: some View {
+ @ViewBuilder private var headerRow: some View {
if isHeaderEmpty == false || (header is EmptyView) == false {
HStack(spacing: 0) {
headerTexts
@@ -82,7 +135,7 @@ public struct ListChoice: View, Potenti
}
}
- @ViewBuilder var headerTexts: some View {
+ @ViewBuilder private var headerTexts: some View {
if isHeaderEmpty == false {
HStack(alignment: .top, spacing: .xSmall) {
icon
@@ -107,7 +160,7 @@ public struct ListChoice: View, Potenti
}
}
- @ViewBuilder var disclosureView: some View {
+ @ViewBuilder private var disclosureView: some View {
switch disclosure {
case .none:
EmptyView()
@@ -129,7 +182,7 @@ public struct ListChoice: View, Potenti
}
}
- @ViewBuilder func disclosureButton(type: ListChoiceDisclosure.ButtonType) -> some View {
+ @ViewBuilder private func disclosureButton(type: ListChoiceDisclosure.ButtonType) -> some View {
Button(type: type == .add ? .primarySubtle : .criticalSubtle) {
// No action
} icon: {
@@ -142,7 +195,7 @@ public struct ListChoice: View, Potenti
.idealSize()
}
- @ViewBuilder var separator: some View {
+ @ViewBuilder private var separator: some View {
if showSeparator {
Separator()
}
@@ -152,15 +205,15 @@ public struct ListChoice: View, Potenti
isHeaderEmpty && header.isEmpty && content.isEmpty && disclosure == .none
}
- var isHeaderEmpty: Bool {
+ private var isHeaderEmpty: Bool {
icon.isEmpty && isHeaderTextEmpty
}
- var isHeaderTextEmpty: Bool {
+ private var isHeaderTextEmpty: Bool {
title.isEmpty && description.isEmpty
}
- var accessibilityTraitsToAdd: AccessibilityTraits {
+ private var accessibilityTraitsToAdd: AccessibilityTraits {
switch disclosure {
case .none, .disclosure, .button(.add), .buttonLink, .checkbox(false, _), .radio(false, _), .icon:
return []
@@ -168,9 +221,13 @@ public struct ListChoice: View, Potenti
return .isSelected
}
}
+}
- /// Creates Orbit ListChoice component with custom content.
- public init(
+// MARK: - Inits
+public extension ListChoice {
+
+ /// Creates Orbit ``ListChoice`` component with custom content.
+ init(
_ title: String = "",
description: String = "",
value: String = "",
@@ -191,12 +248,8 @@ public struct ListChoice: View, Potenti
self.icon = icon()
self.header = header()
}
-}
-
-// MARK: - Inits
-public extension ListChoice {
-
- /// Creates Orbit ListChoice component.
+
+ /// Creates Orbit ``ListChoice`` component.
init(
_ title: String = "",
description: String = "",
@@ -226,7 +279,7 @@ public extension ListChoice {
public extension ListChoice where Header == Text {
- /// Creates Orbit ListChoice component with text header value.
+ /// Creates Orbit ``ListChoice`` component with a text value as a header.
init(
_ title: String = "",
description: String = "",
@@ -258,8 +311,10 @@ public extension ListChoice where Header == Text {
// MARK: - Types
+/// Disclosure used in Orbit ``ListChoice``.
public enum ListChoiceDisclosure: Equatable {
+ /// Orbit ``ListChoiceDisclosure`` button type.
public enum ButtonType {
case add
case remove
diff --git a/Sources/Orbit/Components/NotificationBadge.swift b/Sources/Orbit/Components/NotificationBadge.swift
index 8f3fe51b343..732d3e6dbf4 100644
--- a/Sources/Orbit/Components/NotificationBadge.swift
+++ b/Sources/Orbit/Components/NotificationBadge.swift
@@ -1,8 +1,27 @@
import SwiftUI
-/// Shows simple, non-interactive information in a circular badge.
+/// Orbit component that displays non-actionable, short and static information in a circular badge.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/information/notificationbadge/)
+/// A ``NotificationBadge`` consists of a short label or icon.
+///
+/// ```swift
+/// NotificationBadge("1", type: .lightInverted)
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The label and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+///
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// When type is set to ``BadgeType/status(_:inverted:)`` with a `nil` value, the default ``Status/info`` status can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// NotificationBadge(.user, type: .status(nil))
+/// .status(.warning)
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/information/notificationbadge/)
public struct NotificationBadge: View {
@Environment(\.backgroundShape) private var backgroundShape
@@ -10,8 +29,8 @@ public struct NotificationBadge: View {
@Environment(\.sizeCategory) private var sizeCategory
@Environment(\.textColor) private var textColor
- private let type: BadgeType
@ViewBuilder private let content: Content
+ private let type: BadgeType
public var body: some View {
if isEmpty == false {
@@ -29,7 +48,7 @@ public struct NotificationBadge: View {
}
- @ViewBuilder var resolvedBackground: some View {
+ @ViewBuilder private var resolvedBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -37,17 +56,7 @@ public struct NotificationBadge: View {
}
}
- var defaultBackgroundColor: Color {
- switch type {
- case .light: return .whiteDarker
- case .lightInverted: return .inkDark
- case .neutral: return .cloudLight
- case .status(let status, true): return (status ?? defaultStatus).color
- case .status(let status, false): return (status ?? defaultStatus).lightColor
- }
- }
-
- @ViewBuilder var background: some View {
+ @ViewBuilder private var background: some View {
switch type {
case .light: Color.whiteDarker
case .lightInverted: Color.inkDark
@@ -56,12 +65,22 @@ public struct NotificationBadge: View {
case .status(let status, false): (status ?? defaultStatus).lightColor
}
}
+
+ private var defaultBackgroundColor: Color {
+ switch type {
+ case .light: return .whiteDarker
+ case .lightInverted: return .inkDark
+ case .neutral: return .cloudLight
+ case .status(let status, true): return (status ?? defaultStatus).color
+ case .status(let status, false): return (status ?? defaultStatus).lightColor
+ }
+ }
- var resolvedTextColor: Color {
+ private var resolvedTextColor: Color {
textColor ?? labelColor
}
- var labelColor: Color {
+ private var labelColor: Color {
switch type {
case .light: return .inkDark
case .lightInverted: return .whiteNormal
@@ -71,34 +90,28 @@ public struct NotificationBadge: View {
}
}
- var minWidth: CGFloat {
+ private var minWidth: CGFloat {
Text.Size.small.lineHeight * sizeCategory.ratio
}
- var defaultStatus: Status {
+ private var defaultStatus: Status {
status ?? .info
}
+}
- /// Creates Orbit NotificationBadge component with custom content.
- ///
- /// - Parameters:
- /// - type: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
- public init(
+// MARK: - Inits
+public extension NotificationBadge {
+
+ /// Creates Orbit ``NotificationBadge`` component with custom content.
+ init(
type: BadgeType = .status(nil),
@ViewBuilder content: () -> Content
) {
self.type = type
self.content = content()
}
-}
-
-// MARK: - Inits
-public extension NotificationBadge {
-
- /// Creates Orbit NotificationBadge component containing text.
- ///
- /// - Parameters:
- /// - style: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+
+ /// Creates Orbit ``NotificationBadge`` component containing text.
init(
_ label: String,
type: BadgeType = .status(nil)
@@ -110,10 +123,7 @@ public extension NotificationBadge {
}
}
- /// Creates Orbit NotificationBadge component containing icon.
- ///
- /// - Parameters:
- /// - style: A visual style of component. A `status` style can be optionally modified using `status()` modifier when `nil` value is provided.
+ /// Creates Orbit ``NotificationBadge`` component containing icon.
init(
_ icon: Icon.Symbol,
type: BadgeType = .status(nil)
@@ -126,7 +136,7 @@ public extension NotificationBadge {
}
// MARK: - Types
-public extension NotificationBadge {
+private extension NotificationBadge {
enum Content {
case icon(Icon.Symbol)
diff --git a/Sources/Orbit/Components/Radio.swift b/Sources/Orbit/Components/Radio.swift
index 531a5919312..ee2e9076239 100644
--- a/Sources/Orbit/Components/Radio.swift
+++ b/Sources/Orbit/Components/Radio.swift
@@ -1,20 +1,51 @@
import SwiftUI
-/// Enables users to pick exactly one option from a group.
+/// Orbit input component that displays a single selectable option to pick from a group.
+/// A counterpart of the native `SwiftUI.Picker` with `radioGroup` style applied.
///
-/// Can be also used to display just the radio rounded indicator.
+/// A ``Radio`` consists of a title, description and the radio indicator.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/radio/)
+/// ```swift
+/// Radio("Free", isChecked: $isFree)
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier:
+///
+/// ```swift
+/// Radio(isChecked: $isFree)
+/// .disabled()
+/// ```
+///
+/// Before the selection is changed, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Customizing appearance
+///
+/// The title color can be modified by ``textColor(_:)`` modifier:
+///
+/// ```swift
+/// Radio("Free", isChecked: $isFree)
+/// .textColor(.blueNormal)
+/// ```
+///
+/// ### Layout
+///
+/// When the provided textual content is empty, the component results in a standalone control.
+///
+/// ```swift
+/// Radio(isChecked: $isFree)
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/radio/)
public struct Radio: View {
@Environment(\.isEnabled) private var isEnabled
@Environment(\.textColor) private var textColor
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
- let title: String
- let description: String
- let state: State
- @Binding var isChecked: Bool
+ private let title: String
+ private let description: String
+ private let state: State
+ @Binding private var isChecked: Bool
public var body: some View {
SwiftUI.Button {
@@ -43,13 +74,13 @@ public struct Radio: View {
)
}
- var labelColor: Color {
+ private var labelColor: Color {
isEnabled
? textColor ?? .inkDark
: .cloudDarkHover
}
- var descriptionColor: Color {
+ private var descriptionColor: Color {
isEnabled
? .inkNormal
: .cloudDarkHover
@@ -59,7 +90,7 @@ public struct Radio: View {
// MARK: - Inits
public extension Radio {
- /// Creates Orbit Radio component.
+ /// Creates Orbit ``Radio`` component.
init(
_ title: String = "",
description: String = "",
@@ -73,6 +104,7 @@ public extension Radio {
// MARK: - Types
public extension Radio {
+ /// A state of Orbit ``Radio``.
enum State {
case normal
case error
diff --git a/Sources/Orbit/Components/SegmentedSwitch.swift b/Sources/Orbit/Components/SegmentedSwitch.swift
index d3cc4868645..fbd4f8b51fe 100644
--- a/Sources/Orbit/Components/SegmentedSwitch.swift
+++ b/Sources/Orbit/Components/SegmentedSwitch.swift
@@ -1,12 +1,12 @@
import SwiftUI
-/// Showing choices from which only one can be selected.
+/// Orbit input component that displays two choices to pick from.
+/// A counterpart of the native `SwiftUI.Picker` with `segmented` style applied.
///
-/// Specify two, or at most, three views in the content closure,
-/// giving each an `.identifier` that matches a value
-/// of the selection binding:
+/// A ``SegmentedSwitch`` consists of a label and two or three choices.
+/// Each choice must be given an Orbit `identifier` that matches a value of the selection binding:
///
-/// ```
+/// ```swift
/// enum Direction {
/// case left
/// case right
@@ -21,21 +21,25 @@ import SwiftUI
/// .identifier(Direction.right)
/// }
/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
///
-/// SegmentedSwitch can be in error state only in unselected state.
-///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/interaction/segmentedswitch/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/interaction/segmentedswitch/)
public struct SegmentedSwitch: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.idealSize) private var idealSize
@Binding private var selection: Selection?
- let label: String
- let message: Message?
- let content: Content
+ private let label: String
+ private let message: Message?
+ private let content: Content
- let borderWidth: CGFloat = BorderWidth.active
- let horizontalPadding: CGFloat = .small
+ private let borderWidth: CGFloat = BorderWidth.active
+ private let horizontalPadding: CGFloat = .small
public var body: some View {
FieldWrapper(label, message: message) {
@@ -61,7 +65,7 @@ public struct SegmentedSwitch: View {
.accessibility(hint: .init(message?.description ?? ""))
}
- @ViewBuilder func selectedSegmentButton(preferences: [IDPreference]) -> some View {
+ @ViewBuilder private func selectedSegmentButton(preferences: [IDPreference]) -> some View {
if let index = preferences.firstIndex(where: isSelected) {
segmentButton(preferences: preferences, index: index) {
segmentBackground
@@ -71,7 +75,7 @@ public struct SegmentedSwitch: View {
}
}
- @ViewBuilder func unselectedSegmentButtons(_ preferences: [IDPreference]) -> some View {
+ @ViewBuilder private func unselectedSegmentButtons(_ preferences: [IDPreference]) -> some View {
ForEach(unselectedPreferences(preferences), id: \.1.id) { index, preference in
segmentButton(preferences: preferences, index: index) {
Color.clear
@@ -83,7 +87,7 @@ public struct SegmentedSwitch: View {
.animation(.easeOut(duration: 0.2), value: selection)
}
- @ViewBuilder func segmentButton(
+ @ViewBuilder private func segmentButton(
preferences: [IDPreference],
index: Int,
@ViewBuilder label: @escaping () -> some View
@@ -114,7 +118,7 @@ public struct SegmentedSwitch: View {
}
}
- @ViewBuilder func noSelectionBackground(_ preferences: [IDPreference]) -> some View {
+ @ViewBuilder private func noSelectionBackground(_ preferences: [IDPreference]) -> some View {
if selection == nil {
GeometryReader { geometry in
segmentBackground
@@ -139,13 +143,13 @@ public struct SegmentedSwitch: View {
}
}
- @ViewBuilder var segmentBackground: some View {
+ @ViewBuilder private var segmentBackground: some View {
(colorScheme == .light ? Color.whiteDarker : Color.cloudDarkActive)
.clipShape(RoundedRectangle(cornerRadius: BorderRadius.default - 1))
.padding(borderWidth)
}
- @ViewBuilder var separator: some View {
+ @ViewBuilder private var separator: some View {
(message?.status?.color ?? .cloudNormal)
.frame(width: borderWidth)
.frame(maxHeight: .infinity)
@@ -168,7 +172,36 @@ public struct SegmentedSwitch: View {
idealSize.horizontal == true
}
- public init(
+ private func measurements(
+ index: Int,
+ preferences: [IDPreference],
+ idealSize: Bool,
+ horizontalPadding: CGFloat,
+ separatorWidth: CGFloat,
+ in geometry: GeometryProxy
+ ) -> (width: CGFloat, minX: CGFloat) {
+ if idealSize {
+ let minX = preferences.prefix(upTo: index).reduce(into: 0) { finalMinX, preference in
+ finalMinX += geometry[preference.bounds].width + separatorWidth + horizontalPadding * 2
+ }
+ let width = geometry[preferences[index].bounds].width + horizontalPadding * 2
+
+ return (width, minX)
+ } else {
+ let width = geometry.size.width / CGFloat(preferences.count)
+ let minX = (geometry[preferences[index].bounds].minX / width).rounded(.down) * width
+
+ return (width, minX)
+ }
+ }
+
+}
+
+// MARK: - Inits
+public extension SegmentedSwitch {
+
+ /// Creates Orbit ``SegmentedSwitch`` component with optional selection.
+ init(
_ label: String = "",
selection: Binding,
message: Message? = nil,
@@ -180,7 +213,8 @@ public struct SegmentedSwitch: View {
self.content = content()
}
- public init(
+ /// Creates Orbit ``SegmentedSwitch`` component with non-optional selection.
+ init(
_ label: String = "",
selection: Binding,
message: Message? = nil,
@@ -198,29 +232,6 @@ public struct SegmentedSwitch: View {
}
}
-private func measurements(
- index: Int,
- preferences: [IDPreference],
- idealSize: Bool,
- horizontalPadding: CGFloat,
- separatorWidth: CGFloat,
- in geometry: GeometryProxy
-) -> (width: CGFloat, minX: CGFloat) {
- if idealSize {
- let minX = preferences.prefix(upTo: index).reduce(into: 0) { finalMinX, preference in
- finalMinX += geometry[preference.bounds].width + separatorWidth + horizontalPadding * 2
- }
- let width = geometry[preferences[index].bounds].width + horizontalPadding * 2
-
- return (width, minX)
- } else {
- let width = geometry.size.width / CGFloat(preferences.count)
- let minX = (geometry[preferences[index].bounds].minX / width).rounded(.down) * width
-
- return (width, minX)
- }
-}
-
// MARK: - Previews
struct SegmentedSwitchPreviews: PreviewProvider {
@@ -330,8 +341,8 @@ struct SegmentedSwitchPreviews: PreviewProvider {
label: String = "Gender",
message: Message? = nil
) -> some View {
- StateWrapper(selection) { value in
- SegmentedSwitch(label, selection: value, message: message) {
+ StateWrapper(selection) { $value in
+ SegmentedSwitch(label, selection: $value, message: message) {
Text(firstOption)
.identifier(Gender.male)
@@ -349,8 +360,8 @@ struct SegmentedSwitchPreviews: PreviewProvider {
label: String = "Gender",
message: Message? = nil
) -> some View {
- StateWrapper(selection) { value in
- SegmentedSwitch(label, selection: value, message: message) {
+ StateWrapper(selection) { $value in
+ SegmentedSwitch(label, selection: $value, message: message) {
Text(firstOption)
.identifier(Gender.male)
diff --git a/Sources/Orbit/Components/Select.swift b/Sources/Orbit/Components/Select.swift
index d5dbe0a7e3e..c86049c42b8 100644
--- a/Sources/Orbit/Components/Select.swift
+++ b/Sources/Orbit/Components/Select.swift
@@ -1,12 +1,42 @@
import SwiftUI
-/// Also known as dropdown. Offers a simple form control to select from many options.
+/// Orbit component that displays a dropdown control to select from many options.
+/// A counterpart of the native `SwiftUI.Picker` with `default` style.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/select/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// A ``Select`` consists of a label, value, icon and a default trailing disclosure.
+///
+/// ```swift
+/// Select("Country", value: "Czechia") {
+/// // Tap action
+/// }
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// ### Customizing appearance
+///
+/// The label and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// ```swift
+/// Select("Country", value: "Czechia") {
+/// // Tap action
+/// }
+/// .textColor(.blueLight)
+/// .iconColor(.blueNormal)
+/// .iconSize(.large)
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/select/)
public struct Select: View {
- public let verticalTextPadding: CGFloat = .small // = 44 @ normal text size
+ private let verticalTextPadding: CGFloat = .small // = 44 @ normal text size
@Environment(\.isEnabled) private var isEnabled
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
@@ -91,7 +121,7 @@ public struct Select: View {
// MARK: - Inits
public extension Select {
- /// Creates Orbit Select component.
+ /// Creates Orbit ``Select`` component.
init(
_ label: String = "",
prefix: Icon.Symbol? = nil,
@@ -123,7 +153,7 @@ public extension Select {
}
- /// Creates Orbit Select component with custom prefix or suffix.
+ /// Creates Orbit ``Select`` component with custom prefix or suffix.
init(
_ label: String = "",
value: String?,
diff --git a/Sources/Orbit/Components/Separator.swift b/Sources/Orbit/Components/Separator.swift
index aeb8d0b8df2..478a281d4a9 100644
--- a/Sources/Orbit/Components/Separator.swift
+++ b/Sources/Orbit/Components/Separator.swift
@@ -1,15 +1,34 @@
import SwiftUI
-/// Separates content.
+/// Orbit component that displays vertical separator between content.
+///
+/// A ``Separator`` consists of an optional label.
+///
+/// ```swift
+/// Separator("OR", thickness: .hairline)
+/// ```
///
-/// - Important: Component expands horizontally to infinity.
+/// ### Customizing appearance
+///
+/// The label color can be modified by ``textColor(_:)`` modifier.
+///
+/// ```swift
+/// Separator("OR")
+/// .textColor(.blueLight)
+/// ```
+///
+/// ### Layout
+///
+/// Component expands horizontally.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/structure/separator/)
public struct Separator: View {
@Environment(\.textColor) private var textColor
- let label: String
- let color: Color
- let thickness: CGFloat
+ private let label: String
+ private let color: Color
+ private let thickness: CGFloat
public var body: some View {
if label.isEmpty {
@@ -30,12 +49,12 @@ public struct Separator: View {
}
}
- @ViewBuilder var line: some View {
+ @ViewBuilder private var line: some View {
color
.frame(height: thickness)
}
- @ViewBuilder var leadingLine: some View {
+ @ViewBuilder private var leadingLine: some View {
HStack(spacing: 0) {
line
LinearGradient(colors: [color, color.opacity(0)], startPoint: .leading, endPoint: .trailing)
@@ -44,7 +63,7 @@ public struct Separator: View {
}
}
- @ViewBuilder var trailingLine: some View {
+ @ViewBuilder private var trailingLine: some View {
HStack(spacing: 0) {
LinearGradient(colors: [color, color.opacity(0)], startPoint: .trailing, endPoint: .leading)
.frame(width: .large)
@@ -57,7 +76,7 @@ public struct Separator: View {
// MARK: - Inits
public extension Separator {
- /// Creates Orbit Separator component.
+ /// Creates Orbit ``Separator`` component.
init(
_ label: String = "",
color: Color = .cloudNormal,
@@ -72,11 +91,13 @@ public extension Separator {
// MARK: - Types
public extension Separator {
+ /// Orbit ``Separator`` thickness.
enum Thickness {
case `default`
case hairline
case custom(CGFloat)
+ /// Value of Orbit `Separator` ``Separator/Thickness``.
public var value: CGFloat {
switch self {
case .`default`: return 1
diff --git a/Sources/Orbit/Components/Skeleton.swift b/Sources/Orbit/Components/Skeleton.swift
index 3724b8bb712..1615c985a8c 100644
--- a/Sources/Orbit/Components/Skeleton.swift
+++ b/Sources/Orbit/Components/Skeleton.swift
@@ -1,8 +1,18 @@
import SwiftUI
-/// Shows content placeholder before data is loaded.
+/// Orbit component that displays placeholder before data is loaded.
+/// A counterpart of the native `redacted()` modifier.
+///
+/// A ``Skeleton`` is defined by a shape that mimics the shape and size of loaded content.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/progress-indicators/skeleton/)
+/// ```swift
+/// Skeleton(.button)
+/// Skeleton(.image)
+/// Skeleton(.atomic(.rectangle), animation: animation)
+/// .frame(height: 60)
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/progress-indicators/skeleton/)
public struct Skeleton: View {
public static let color: Color = .cloudNormal
@@ -26,7 +36,7 @@ public struct Skeleton: View {
}
}
- @ViewBuilder var content: some View {
+ @ViewBuilder private var content: some View {
switch preset {
case .atomic(let atomic):
switch atomic {
@@ -68,18 +78,34 @@ public struct Skeleton: View {
}
}
- var roundedRectangle: RoundedRectangle {
+ @ViewBuilder private func line(height: CGFloat) -> some View {
+ roundedRectangle.fill(color).frame(height: height)
+ }
+
+ private var roundedRectangle: RoundedRectangle {
RoundedRectangle(cornerRadius: borderRadius)
}
+}
- @ViewBuilder func line(height: CGFloat) -> some View {
- roundedRectangle.fill(color).frame(height: height)
+// MARK: - Inits
+public extension Skeleton {
+
+ /// Creates Orbit ``Skeleton`` component.
+ init(
+ _ preset: Preset,
+ borderRadius: CGFloat = BorderRadius.desktop,
+ animation: Animation = .default
+ ) {
+ self.preset = preset
+ self.borderRadius = borderRadius
+ self.animation = animation
}
}
// MARK: - Types
extension Skeleton {
+ /// Orbit ``Skeleton`` shape and size preset.
public enum Preset {
public enum Atomic {
@@ -93,8 +119,13 @@ extension Skeleton {
case image(height: CGFloat? = nil)
case list(rows: Int, rowHeight: CGFloat = 20, spacing: CGFloat = .xSmall)
case text(lines: Int, lineHeight: CGFloat = 20, spacing: CGFloat = .xSmall)
+
+ public static let button: Self = .button()
+ public static let card: Self = .card()
+ public static let image: Self = .image()
}
+ /// Orbit ``Skeleton`` animation.
public enum Animation {
case none
case `default`
@@ -110,21 +141,6 @@ extension Skeleton {
}
}
-// MARK: - Inits
-public extension Skeleton {
-
- /// Creates Orbit Skeleton component.
- init(
- _ preset: Preset,
- borderRadius: CGFloat = BorderRadius.desktop,
- animation: Animation = .default
- ) {
- self.preset = preset
- self.borderRadius = borderRadius
- self.animation = animation
- }
-}
-
// MARK: - Previews
struct SkeletonPreviews: PreviewProvider {
@@ -132,9 +148,9 @@ struct SkeletonPreviews: PreviewProvider {
PreviewWrapper {
content(animation: .none)
contentAtomic(animation: .none)
- Skeleton(.card(), borderRadius: BorderRadius.large, animation: .none)
+ Skeleton(.card, borderRadius: BorderRadius.large, animation: .none)
.frame(height: 100)
- Skeleton(.image(), borderRadius: BorderRadius.large, animation: .none)
+ Skeleton(.image, borderRadius: BorderRadius.large, animation: .none)
.frame(height: 100)
livePreview
}
@@ -164,7 +180,7 @@ struct SkeletonPreviews: PreviewProvider {
Skeleton(.list(rows: 3), animation: animation)
Skeleton(.image(height: 150), animation: animation)
Skeleton(.card(height: 200), animation: animation)
- Skeleton(.button(), animation: animation)
+ Skeleton(.button, animation: animation)
Skeleton(.text(lines: 4), animation: animation)
}
}
diff --git a/Sources/Orbit/Components/Slider.swift b/Sources/Orbit/Components/Slider.swift
index ff2cb9c19c2..35812598e88 100644
--- a/Sources/Orbit/Components/Slider.swift
+++ b/Sources/Orbit/Components/Slider.swift
@@ -2,23 +2,42 @@ import SwiftUI
public typealias SliderValue = BinaryFloatingPoint & Strideable & CustomStringConvertible
-/// Enables selection from a range of values.
+/// Orbit input component that displays a range of values.
+/// A counterpart of the native `SwiftUI.Slider`.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/interaction/slider/)
+/// A ``Slider`` consists of a label and two or three choices.
+///
+/// ```swift
+/// Slider(
+/// value: $value,
+/// valueLabel: value.description,
+/// startLabel: "15",
+/// endLabel: "200",
+/// range: 15...200
+/// )
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// ### Layout
+///
+/// Component expands horizontally.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/interaction/slider/)
public struct Slider: View where Value: SliderValue, Value.Stride: BinaryFloatingPoint {
- enum SelectedValue {
+ private enum SelectedValue {
case single(Binding?)
case range(Binding>?)
}
- @Environment(\.sizeCategory) var sizeCategory
+ @Environment(\.sizeCategory) private var sizeCategory
- let value: SelectedValue
- let valueLabel: String
- let startLabel: String
- let endLabel: String
- let range: ClosedRange
+ private let value: SelectedValue
+ private let valueLabel: String
+ private let startLabel: String
+ private let endLabel: String
+ private let range: ClosedRange
@State private var isFirstThumbDrag = false
@State private var isSecondThumbDrag = false
@@ -73,13 +92,13 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
.accessibility(hint: .init(accessibilityHint))
}
- @ViewBuilder var track: some View {
+ @ViewBuilder private var track: some View {
RoundedRectangle(cornerRadius: lineHeight)
.fill(.cloudDark)
.frame(minHeight: lineHeight, maxHeight: lineHeight)
}
- @ViewBuilder func controls(sliderWidth: CGFloat) -> some View {
+ @ViewBuilder private func controls(sliderWidth: CGFloat) -> some View {
let thumbDiameter = SliderThumb.circleDiameter * sizeCategory.controlRatio
let thumbRadius = thumbDiameter / 2
let thumbTrackWidth = sliderWidth - thumbDiameter
@@ -105,7 +124,7 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
}
}
- @ViewBuilder func firstThumb(atPosition horizontalPosition: CGFloat, width: CGFloat) -> some View {
+ @ViewBuilder private func firstThumb(atPosition horizontalPosition: CGFloat, width: CGFloat) -> some View {
thumb(
horizontalPosition: horizontalPosition,
width: width,
@@ -116,7 +135,7 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
.zIndex(isFirstThumbDrag ? 1 : 0)
}
- @ViewBuilder func secondThumb(atPosition horizontalPosition: CGFloat, width: CGFloat) -> some View {
+ @ViewBuilder private func secondThumb(atPosition horizontalPosition: CGFloat, width: CGFloat) -> some View {
thumb(
horizontalPosition: horizontalPosition,
width: width,
@@ -127,7 +146,7 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
.zIndex(isSecondThumbDrag ? 1 : 0)
}
- @ViewBuilder func thumb(
+ @ViewBuilder private func thumb(
horizontalPosition: CGFloat,
width: CGFloat,
isDragging: Binding,
@@ -171,7 +190,7 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
)
}
- @ViewBuilder func strokedPath(from: CGFloat, to: CGFloat) -> some View {
+ @ViewBuilder private func strokedPath(from: CGFloat, to: CGFloat) -> some View {
Path { path in
path.move(to: .init(x: from, y: lineCenter))
path.addLine(to: .init(x: to, y: lineCenter))
@@ -215,7 +234,7 @@ public struct Slider: View where Value: SliderValue, Value.Stride: Binary
// MARK: - Inits
public extension Slider {
- /// Creates Orbit Slider component.
+ /// Creates Orbit ``Slider`` component.
init(
value: Binding,
valueLabel: String = "",
@@ -239,7 +258,7 @@ public extension Slider {
self.buckets = range.chunked(into: step ?? Value.Stride(range.upperBound - range.lowerBound))
}
- /// Creates Orbit ranged Slider component.
+ /// Creates Orbit ``Slider`` component with a binding to a closed range value.
init(
valueRange: Binding>,
valueLabel: String = "",
diff --git a/Sources/Orbit/Components/SocialButton.swift b/Sources/Orbit/Components/SocialButton.swift
index 0f7db5911b3..e7f265e93bc 100644
--- a/Sources/Orbit/Components/SocialButton.swift
+++ b/Sources/Orbit/Components/SocialButton.swift
@@ -1,12 +1,25 @@
import SwiftUI
-/// Lets users sign in using a social service.
+/// Orbit component that displays a control that initiates an action related to a social service.
///
-/// Social buttons are designed to ease the flow for users signing in.
-/// Don’t use them in any other case or in any complex scenarios.
+/// A ``SocialButton`` consists of a label and predefined icon.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/socialbutton/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// ```swift
+/// SocialButton("Sign in with Facebook", service: .facebook) {
+/// // Tap action
+/// }
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+/// The default ``ButtonSize/regular`` size can be modified by a ``buttonSize(_:)`` modifier.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/socialbutton/)
public struct SocialButton: View {
@Environment(\.colorScheme) private var colorScheme
@@ -40,7 +53,7 @@ public struct SocialButton: View {
.backgroundStyle(background, active: backgroundActive)
}
- @ViewBuilder var logo: some View {
+ @ViewBuilder private var logo: some View {
switch service {
case .apple: Self.appleLogo.foregroundColor(.whiteNormal).padding(1)
case .google: Self.googleLogo
@@ -49,7 +62,7 @@ public struct SocialButton: View {
}
}
- var textColor: Color {
+ private var textColor: Color {
switch service {
case .apple: return .whiteNormal
case .google: return .inkDark
@@ -58,7 +71,7 @@ public struct SocialButton: View {
}
}
- var background: Color {
+ private var background: Color {
switch service {
case .apple: return colorScheme == .light ? .black : .white
case .google: return .cloudNormal
@@ -67,7 +80,7 @@ public struct SocialButton: View {
}
}
- var backgroundActive: Color {
+ private var backgroundActive: Color {
switch service {
case .apple: return colorScheme == .light ? .inkNormalActive : .inkNormalActive
case .google: return .cloudNormalActive
@@ -80,7 +93,7 @@ public struct SocialButton: View {
// MARK: - Inits
public extension SocialButton {
- /// Creates Orbit SocialButton component.
+ /// Creates Orbit ``SocialButton`` component.
init(_ label: String, service: Service, action: @escaping () -> Void) {
self.label = label
self.service = service
@@ -95,6 +108,7 @@ extension SocialButton {
private static let googleLogo = Image(.google).resizable()
private static let facebookLogo = Image(.facebook).resizable()
+ /// Orbit ``SocialButton`` social service or login method.
public enum Service {
case apple
case google
diff --git a/Sources/Orbit/Components/Stepper.swift b/Sources/Orbit/Components/Stepper.swift
index 6eb75209dda..451a2070785 100644
--- a/Sources/Orbit/Components/Stepper.swift
+++ b/Sources/Orbit/Components/Stepper.swift
@@ -1,17 +1,29 @@
import SwiftUI
-/// Enables incremental changes of a counter without a direct input.
+/// Orbit input component that displays a value with and inputs to make incremental changes.
+/// A counterpart of the native `SwiftUI.Stepper`.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/interaction/stepper/)
+/// A ``Stepper`` consists of a value and increment and decrement buttons.
+///
+/// ```swift
+/// Stepper(
+/// value: $value,
+/// minValue: -5,
+/// maxValue: 20
+/// )
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/interaction/stepper/)
public struct Stepper: View {
- @Binding var value: Int
-
- let minValue: Int
- let maxValue: Int
- let style: Style
+ @Environment(\.isEnabled) private var isEnabled
- @Environment(\.isEnabled) var isEnabled
+ @Binding private var value: Int
+ private let maxValue: Int
+ private let minValue: Int
+ private let style: Style
public var body: some View {
HStack(alignment: .center, spacing: 0) {
@@ -21,14 +33,14 @@ public struct Stepper: View {
}
}
- @ViewBuilder var valueText: some View {
+ @ViewBuilder private var valueText: some View {
Text("\(value)")
.frame(minWidth: .xMedium)
.accessibility(.stepperValue)
.accessibility(value: .init(value.description))
}
- @ViewBuilder var decrementButton: some View {
+ @ViewBuilder private var decrementButton: some View {
StepperButton(.minus, style: style) {
value -= 1
}
@@ -36,16 +48,20 @@ public struct Stepper: View {
.accessibility(.stepperDecrement)
}
- @ViewBuilder var incrementButton: some View {
+ @ViewBuilder private var incrementButton: some View {
StepperButton(.plus, style: style) {
value += 1
}
.environment(\.isEnabled, isEnabled && value < maxValue)
.accessibility(.stepperIncrement)
}
+}
+
+// MARK: - Inits
+public extension Stepper {
- /// Creates Orbit Stepper component.
- public init(
+ /// Creates Orbit ``Stepper`` component.
+ init(
value: Binding,
minValue: Int,
maxValue: Int,
@@ -61,6 +77,7 @@ public struct Stepper: View {
// MARK: - Styles
extension Stepper {
+ /// Orbit ``Stepper`` style.
public enum Style {
case primary
case secondary
diff --git a/Sources/Orbit/Components/Switch.swift b/Sources/Orbit/Components/Switch.swift
index eef10d77f94..393fa91939b 100644
--- a/Sources/Orbit/Components/Switch.swift
+++ b/Sources/Orbit/Components/Switch.swift
@@ -1,24 +1,30 @@
import SwiftUI
-/// Offers a control to toggle a setting on or off.
+/// Orbit input component that displays a binary toggle control.
+/// A counterpart of the native `SwiftUI.Toggle`.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/interaction/switch/)
+/// ```swift
+/// Switch(isOn: $isOn)
+/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/interaction/switch/)
public struct Switch: View {
- public static let size = CGSize(width: 50, height: 28)
- public static let circleDiameter: CGFloat = 30
- public static let dotDiameter: CGFloat = 10
-
- static let borderColor = Color(white: 0.2, opacity: 0.25)
- static let animation = Animation.spring(response: 0.25, dampingFraction: 0.6)
+ private static let size = CGSize(width: 50, height: 28)
+ private static let circleDiameter: CGFloat = 30
+ private static let dotDiameter: CGFloat = 10
+ private static let borderColor = Color(white: 0.2, opacity: 0.25)
+ private static let animation = Animation.spring(response: 0.25, dampingFraction: 0.6)
@Environment(\.sizeCategory) private var sizeCategory
@Environment(\.colorScheme) private var colorScheme
@Environment(\.isEnabled) private var isEnabled
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
- @Binding var isOn: Bool
-
- let hasIcon: Bool
+
+ private let hasIcon: Bool
+ @Binding private var isOn: Bool
public var body: some View {
capsule
@@ -34,14 +40,14 @@ public struct Switch: View {
.disabled(isEnabled == false)
}
- @ViewBuilder var capsule: some View {
+ @ViewBuilder private var capsule: some View {
Capsule(style: .circular)
.frame(width: width, height: height)
.foregroundColor(tint)
.animation(Self.animation, value: isOn)
}
- @ViewBuilder var indicator: some View {
+ @ViewBuilder private var indicator: some View {
Circle()
.frame(width: circleDiameter, height: circleDiameter)
.foregroundColor(indicatorColor)
@@ -58,7 +64,7 @@ public struct Switch: View {
.animation(Self.animation, value: isOn)
}
- @ViewBuilder var indicatorSymbol: some View {
+ @ViewBuilder private var indicatorSymbol: some View {
if hasIcon {
Icon(isOn ? .lock : .lockOpen)
.iconSize(.small)
@@ -71,42 +77,46 @@ public struct Switch: View {
}
}
- var tint: Color {
+ private var tint: Color {
(isOn ? .blueNormal : capsuleBackgroundColor)
.opacity(isEnabled ? 1 : 0.5)
}
- var iconTint: Color {
+ private var iconTint: Color {
(isOn ? Color.blueNormal : Color.inkNormal)
.opacity(isEnabled ? 1 : 0.5)
}
- var capsuleBackgroundColor: Color {
+ private var capsuleBackgroundColor: Color {
colorScheme == .light ? .cloudDark : .cloudDark
}
- var indicatorColor: Color {
+ private var indicatorColor: Color {
colorScheme == .light ? .whiteNormal : .cloudNormal
}
- var width: CGFloat {
+ private var width: CGFloat {
Self.size.width * sizeCategory.controlRatio
}
- var height: CGFloat {
+ private var height: CGFloat {
Self.size.height * sizeCategory.controlRatio
}
- var circleDiameter: CGFloat {
+ private var circleDiameter: CGFloat {
Self.circleDiameter * sizeCategory.controlRatio
}
- var dotDiameter: CGFloat {
+ private var dotDiameter: CGFloat {
Self.dotDiameter * sizeCategory.controlRatio
}
+}
- /// Creates Orbit Switch component.
- public init(isOn: Binding, hasIcon: Bool = false) {
+// MARK: - Previews
+public extension Switch {
+
+ /// Creates Orbit ``Switch`` component.
+ init(isOn: Binding, hasIcon: Bool = false) {
self._isOn = isOn
self.hasIcon = hasIcon
}
diff --git a/Sources/Orbit/Components/Tabs.swift b/Sources/Orbit/Components/Tabs.swift
index 6a067671027..e8b6bca6f4d 100644
--- a/Sources/Orbit/Components/Tabs.swift
+++ b/Sources/Orbit/Components/Tabs.swift
@@ -1,25 +1,40 @@
import SwiftUI
-/// Separates content into groups within a single context.
+/// Orbit input component that displays a control for switching between multiple contents in a group.
+/// A counterpart of the native `SwiftUI.Picker` with `segmented` style applied. A typical use case is switching between tabs in a native `SwiftUI.TabView`.
///
-/// The following example shows component with 3 tabs:
+/// A ``Tabs`` consists of labels that represent specific tabs.
+/// Each tab label must be given an Orbit `identifier` that matches a value of the selection binding:
///
/// ```swift
-/// var body: some View {
-/// Tabs(selection: tabIndex) {
-/// Text("one")
-/// .identifier(1)
-/// Text("two")
-/// .identifier(2)
-/// .activeTabStyle(.underlinedGradient(.ink))
-/// Text("three")
-/// .identifier(3)
-/// .activeTabStyle(.underlined(.blueNormal))
-/// }
+/// Tabs(selection: $selectedTab) {
+/// Text("One")
+/// .identifier(1)
+/// Text("Two")
+/// .identifier(2)
+/// .activeTabStyle(.underlinedGradient(.ink))
+/// Text("Three")
+/// .identifier(3)
+/// .activeTabStyle(.underlined(.blueNormal))
+/// }
+///
+/// TabView(selection: $selectedTab) {
+/// tabContentNumberOne
+/// .tag(1)
+/// tabContentNumberTwo
+/// .tag(2)
+/// tabContentNumberThree
+/// .tag(3)
/// }
/// ```
+///
+/// The component can be disabled by ``disabled(_:)`` modifier.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/structure/tabs/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/structure/tabs/)
public struct Tabs: View {
@Environment(\.colorScheme) private var colorScheme
diff --git a/Sources/Orbit/Components/Tag.swift b/Sources/Orbit/Components/Tag.swift
index 6d786806b47..6bb14f7aa8b 100644
--- a/Sources/Orbit/Components/Tag.swift
+++ b/Sources/Orbit/Components/Tag.swift
@@ -1,9 +1,33 @@
import SwiftUI
-/// Offers a label that can optionally be selected and unselected or removed.
+/// Orbit component that displays a control that can be selected, unselected, or removed.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/tag/)
-/// - Important: Component can expand horizontally by using `idealSize` modifier.
+/// A ``Tag`` consists of a label, icon and optional removable action.
+///
+/// ```swift
+/// Tag("Sorting", icon: .sort, isSelected: $isSortingApplied)
+/// Tag("Filters", style: .removable(action: { /* Tap action */ }), isSelected: $isFiltersApplied)
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The label and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+///
+/// ```swift
+/// Tag("Selected", isSelected: $isSelected)
+/// .textColor(.blueLight)
+/// .iconColor(.blueNormal)
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component does not expand horizontally, unless forced by the native ``idealSize()`` modifier with a `false` value.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/tag/)
public struct Tag: View, PotentiallyEmptyView {
@Environment(\.idealSize) private var idealSize
@@ -61,7 +85,7 @@ public struct Tag: View, PotentiallyEmptyView {
// MARK: - Inits
public extension Tag {
- /// Creates Orbit Tag component with custom icon.
+ /// Creates Orbit ``Tag`` component with custom leading icon.
init(
_ label: String = "",
style: TagStyle = .default,
@@ -76,7 +100,7 @@ public extension Tag {
self.icon = icon()
}
- /// Creates Orbit Tag component.
+ /// Creates Orbit ``Tag`` component.
init(
_ label: String = "",
icon: Icon.Symbol? = nil,
@@ -98,6 +122,7 @@ public extension Tag {
// MARK: - Types
+/// Orbit ``Tag`` style.
public enum TagStyle: Equatable {
case `default`
diff --git a/Sources/Orbit/Components/Text.swift b/Sources/Orbit/Components/Text.swift
index 3782c448dc1..cc96c9f2def 100644
--- a/Sources/Orbit/Components/Text.swift
+++ b/Sources/Orbit/Components/Text.swift
@@ -1,12 +1,78 @@
import SwiftUI
-/// Renders text blocks in styles to fit the purpose.
+/// Orbit component that displays one or more lines of read-only text.
+/// A counterpart of the native `SwiftUI.Text` with a support for Orbit markup formatting and ``TextLink``s.
///
-/// A view that displays one or more lines of read-only text. Text content supports html tags ``, ``, `][` for text formatting.
-/// The `` and `` tags support embedding interactive ``TextLink``s withing the text.
+/// A ``Text`` is created using the `String` content that can include html tags ``, ``, `][`, `]
` to customize formatting.
+/// Interactive tags `` and `` can be used to insert ``TextLink``s in the text.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/text/)
-/// - Important: Component has fixed vertical size. When the content is empty, the component results in `EmptyView`.
+/// ```swift
+/// Text("Text with [formatting],
multiline content and TextLink")
+/// ```
+///
+/// The Orbit ``Text`` component consists of up to 3 layers on top of each other:
+///
+/// 1) A base `SwiftUI.Text` layer, either:
+/// - `SwiftUI.Text(verbatim:)` (when the whole text is a plain text with no formatting)
+/// - `SwiftUI.Text(attributedString:)` (when the text contains any Orbit html formatting)
+/// 2) ``TextLink`` overlay (when the text contains ``TextLink``s). The native text modifier support is limited for this layer.
+/// 3) A long tap gesture overlay (when the `textIsCopyable` is `true`)
+///
+/// ### Customizing appearance
+///
+/// Textual properties can be modified in two ways:
+/// - Modifiers applied directly to `Text` that return the same type, such as ``textColor(_:)-7qk2x`` or ``textAccentColor(_:)-xmqw``.
+/// These can also be used for concatenation with other Orbit textual components like ``Heading`` or ``Icon``.
+/// See the `InstanceMethods` section below for full list.
+/// - Modifiers applied to view hierarchy, such as ``textColor(_:)-828ud`` or ``textIsCopyable(_:)``.
+/// See a full list of `View` extensions in documentation.
+///
+/// ```swift
+/// VStack {
+/// // Will result in `inkNormal` color
+/// Text("Override")
+/// .textColor(.inkNormal)
+///
+/// // Will result in `blueDark` color passed from environment
+/// Text("Modified")
+///
+/// // Will result in a default `inkDark` color, ignoring the environment value
+/// Text("Default")
+/// .textColor(nil)
+///
+/// // Will result in mixed `redNormal` and `blueDark` colors
+/// Text("Concatenated")
+/// .textColor(.redNormal)
+/// + Text(" Title")
+/// .bold()
+/// + Icon(.grid)
+/// .iconColor(.redNormal)
+/// }
+/// .textColor(.blueDark)
+/// ```
+///
+/// Formatting and behaviour for ``TextLink``s found in the text can be modified by ``textLinkAction(_:)`` and
+/// ``textLinkColor(_:)`` modifiers.
+///
+/// ```swift
+/// Heading("Information for Passenger", type: .title3)
+/// .textLinkColor(.inkNormal)
+/// .textLinkAction {
+/// // TextLink tap Action
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// Orbit text components use a designated vertical padding that is the same in both single and multiline variant.
+/// This makes it easier to align them consistently next to other Orbit components like ``Icon`` not only based on the baseline,
+/// but also by `top` or `bottom` edges, provided the component text sizes match according to Orbit rules.
+///
+/// Orbit text components have a fixed vertical size.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/text/)
public struct Text: View, FormattedTextBuildable, PotentiallyEmptyView {
@Environment(\.multilineTextAlignment) private var multilineTextAlignment
@@ -35,14 +101,6 @@ public struct Text: View, FormattedTextBuildable, PotentiallyEmptyView {
var isMonospacedDigit: Bool?
var lineHeight: CGFloat?
- // The Orbit Text consists of up to 3 layers:
- //
- // 1) SwiftUI.Text base layer, either:
- // - SwiftUI.Text(verbatim:) (when text is a plain text only)
- // - SwiftUI.Text(attributedString:) (when text contains any Orbit html formatting)
- // 2) TextLink-only overlay (when text contains any TextLink; limited native modifier support)
- // 3) Long-tap-to-copy gesture overlay (when isSelectable == true)
-
public var body: some View {
if isEmpty == false {
text(textRepresentableEnvironment: textRepresentableEnvironment)
@@ -249,19 +307,13 @@ public struct Text: View, FormattedTextBuildable, PotentiallyEmptyView {
// MARK: - Inits
public extension Text {
- /// Creates Orbit Text component that displays a string literal.
- ///
- /// Modifiers like `textAccentColor()`, `textSize()` or `fontWeight()` can be used to further adjust the formatting.
- /// To specify the formatting and behaviour for `TextLink`s found in the text, use `textLinkAction()` and
- /// `textLinkColor()` modifiers.
- ///
- /// Use `textIsCopyable()` to allow text to react on long tap.
+ /// Creates Orbit ``Text`` component that displays a string literal.
///
/// - Parameters:
/// - content: String to display. Supports html formatting tags ``, ``, `[`, `` and ``.
///
- /// - Important: The text concatenation does not support interactive TextLinks. It also does not fully support some global SwiftUI native text formatting view modifiers.
- /// For proper rendering of TextLinks, any required text formatting modifiers must be also called on the Text directly.
+ /// - Important: The text concatenation does not support interactive ``TextLink``s. It also does not fully support some global SwiftUI native text formatting view modifiers.
+ /// For proper rendering of `TextLinks`, any required text formatting modifiers must be also called on the `Text` directly.
init(_ content: String) {
self.content = content
}
@@ -270,7 +322,7 @@ public extension Text {
// MARK: - Types
public extension Text {
- /// Orbit text font size.
+ /// Orbit predefined ``Text`` font size.
enum Size: Equatable {
/// 13 pts.
case small
@@ -291,7 +343,7 @@ public extension Text {
}
}
- /// Text font size value.
+ /// Value of Orbit `Text` ``Text/Size``.
public var value: CGFloat {
switch self {
case .small: return 13
@@ -301,7 +353,7 @@ public extension Text {
}
}
- /// Designated line height.
+ /// Designated line height for Orbit `Text` ``Text/Size``.
public var lineHeight: CGFloat {
switch self {
case .small: return 16
diff --git a/Sources/Orbit/Components/TextLink.swift b/Sources/Orbit/Components/TextLink.swift
index 24530777e70..91405382045 100644
--- a/Sources/Orbit/Components/TextLink.swift
+++ b/Sources/Orbit/Components/TextLink.swift
@@ -1,11 +1,36 @@
import Combine
import SwiftUI
-/// A companion component to ``Text`` that only shows TextLinks, detected in html formatted content.
+/// Orbit component that displays a one or more interactive links detected in html formatted content.
+/// A counterpart of the native `SwiftUI.Link`.
///
-/// The component is created automatically for all `` and `` tags found in a formatted text.
+/// A ``TextLink`` is created using the `NSAttributedString` content that includes html tags `` or `` and an ``TextLink/Action`` provided by ``textLinkAction(_:)`` modifier.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/textlink/)
+/// ```swift
+/// Group {
+/// // A standalone `TextLink` component
+/// TextLink(NSAttributedString("TextLink"))
+///
+/// // Orbit `Text` that contains a `TextLink` as an interactive layer over the text.
+/// Text("Text with ][formatting],
multiline content and TextLink")
+/// }
+/// .textLinkAction { url, label in
+/// // TextLink tap Action
+/// }
+/// ```
+///
+/// ### Customizing appearance
+///
+/// The `TextLink` color can be modified by ``textLinkColor(_:)`` modifier.
+///
+/// ```swift
+/// TextLink(NSAttributedString(htmlText))
+/// .textLinkColor(.blueNormal)
+/// Text(htmlText)
+/// .textLinkColor(.blueNormal)
+/// ```
+/// - Important: Prefer using the Orbit ``Text`` component that automatically includes the `TextLink` as a layer for all detected links.
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/textlink/)
public struct TextLink: UIViewRepresentable {
@Environment(\.textLinkAction) private var textLinkAction
@@ -75,13 +100,12 @@ public struct TextLink: UIViewRepresentable {
}
// MARK: - Inits
-extension TextLink {
+public extension TextLink {
- /// Creates an Orbit TextLink.
- ///
- /// The component has a size of the original text, but it only display detected links, hiding any non-link content.
- /// Use `textLink(color:)` to override the TextLink colors.
- public init(_ content: NSAttributedString) {
+ /// Creates Orbit ``TextLink`` component.
+ ///
+ /// - Important: Prefer using the Orbit ``Text`` component that automatically includes the `TextLink` as a layer for all detected links.
+ init(_ content: NSAttributedString) {
self.content = content
}
}
@@ -89,10 +113,10 @@ extension TextLink {
// MARK: - Types
public extension TextLink {
- /// An action handler for a link tapped inside the ``Text`` or ``TextLink`` component.
+ /// An action handler for links tapped inside the Orbit ``Text`` and ``TextLink`` components.
typealias Action = (URL, String) -> Void
- /// Orbit TextLink color.
+ /// Orbit ``TextLink`` color.
enum Color: Equatable {
case primary
case secondary
diff --git a/Sources/Orbit/Components/Textarea.swift b/Sources/Orbit/Components/Textarea.swift
index a76814d012a..ec3b34d1f70 100644
--- a/Sources/Orbit/Components/Textarea.swift
+++ b/Sources/Orbit/Components/Textarea.swift
@@ -1,9 +1,10 @@
import SwiftUI
import UIKit
-/// Orbit component that offers multiline text input. The component is an equivalent of the native `TextField` component with vertical axis specified.
+/// Orbit input component that offers multiline text input.
+/// A counterpart of the native `SwiftUI.TextField` component with `vertical` axis specified.
///
-/// The Textarea is created with an optional label and a binding to a string value.
+/// The ``Textarea`` is created with an optional label and a binding to a string value.
///
/// ```swift
/// Textarea("Label", value: $text, prompt: "Description")
@@ -18,7 +19,7 @@ import UIKit
///
/// ### Layout
///
-/// The component expands horizontally and vertically, unless limited by a `frame` modifier.
+/// The component expands horizontally and vertically. It would be typically further constrained by a `frame` modifier in vertical axis.
///
/// - Note: [Orbit definition](https://orbit.kiwi/components/input/textarea/)
public struct Textarea: View, TextFieldBuildable {
@@ -54,7 +55,7 @@ public struct Textarea: View, TextFieldBuildable {
}
}
- @ViewBuilder var textView: some View {
+ @ViewBuilder private var textView: some View {
TextView(
value: $value,
prompt: prompt,
diff --git a/Sources/Orbit/Components/Tile.swift b/Sources/Orbit/Components/Tile.swift
index 22d0f6b4d52..465221f3a83 100644
--- a/Sources/Orbit/Components/Tile.swift
+++ b/Sources/Orbit/Components/Tile.swift
@@ -1,11 +1,42 @@
import SwiftUI
-/// Groups actionable content to make it easy to scan.
+/// Orbit component that displays an option to pick from a group.
///
-/// Can be used standalone or wrapped inside a ``TileGroup``.
+/// A ``Tile`` consists of a title, description, icon and content.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/tile/)
-/// - Important: Component expands horizontally unless prevented by `fixedSize` or `idealSize` modifier.
+/// ```swift
+/// Tile("Profile", icon: .account) {
+/// // Tap action
+/// } content: {
+/// // Content
+/// }
+/// ```
+///
+/// A `Tile` can be used standalone or wrapped in a ``TileGroup``.
+///
+/// ### Customizing appearance
+///
+/// The title and icon colors can be modified by ``textColor(_:)`` and ``iconColor(_:)`` modifiers.
+/// The icon size can be modified by ``iconSize(custom:)`` modifier.
+///
+/// The default background can be overridden by ``backgroundStyle(_:)-9odue`` modifier.
+///
+/// A ``Status`` can be modified by ``status(_:)`` modifier:
+///
+/// ```swift
+/// Tile("Not available") {
+/// // Action
+/// }
+/// .status(.critical)
+/// ```
+///
+/// Before the action is triggered, a haptic feedback is fired via ``HapticsProvider/sendHapticFeedback(_:)``.
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` or ``idealSize()`` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/tile/)
public struct Tile: View {
@Environment(\.idealSize) private var idealSize
@@ -40,7 +71,7 @@ public struct Tile: View {
.accessibility(addTraits: .isButton)
}
- @ViewBuilder var buttonContent: some View {
+ @ViewBuilder private var buttonContent: some View {
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: 0) {
header
@@ -61,7 +92,7 @@ public struct Tile: View {
.overlay(separator, alignment: .init(horizontal: .listRowSeparatorLeading, vertical: .bottom))
}
- @ViewBuilder var header: some View {
+ @ViewBuilder private var header: some View {
if isHeaderEmpty == false {
HStack(alignment: .top, spacing: .xSmall) {
icon
@@ -87,14 +118,14 @@ public struct Tile: View {
}
}
- @ViewBuilder var customContentButtonLinkOverlay: some View {
+ @ViewBuilder private var customContentButtonLinkOverlay: some View {
if isHeaderEmpty {
inactiveButtonLink
.padding(.medium)
}
}
- @ViewBuilder var inactiveButtonLink: some View {
+ @ViewBuilder private var inactiveButtonLink: some View {
switch disclosure {
case .none, .icon:
EmptyView()
@@ -108,7 +139,7 @@ public struct Tile: View {
}
}
- @ViewBuilder var disclosureIcon: some View {
+ @ViewBuilder private var disclosureIcon: some View {
switch disclosure {
case .none, .buttonLink:
EmptyView()
@@ -121,17 +152,17 @@ public struct Tile: View {
}
}
- @ViewBuilder var separator: some View {
+ @ViewBuilder private var separator: some View {
if isInsideTileGroup, isTileSeparatorVisible {
Separator()
}
}
- var tileBorderStyle: TileBorderStyle {
+ private var tileBorderStyle: TileBorderStyle {
showBorder && isInsideTileGroup == false ? .default : .none
}
- var isHeaderEmpty: Bool {
+ private var isHeaderEmpty: Bool {
title.isEmpty && description.isEmpty && icon.isEmpty
}
}
@@ -139,7 +170,30 @@ public struct Tile: View {
// MARK: - Inits
public extension Tile {
- /// Creates Orbit Tile component.
+ /// Creates Orbit ``Tile`` component with custom icon.
+ init(
+ _ title: String = "",
+ description: String = "",
+ disclosure: TileDisclosure = .icon(.chevronForward),
+ showBorder: Bool = true,
+ titleStyle: Heading.Style = .title4,
+ descriptionColor: Color = .inkNormal,
+ action: @escaping () -> Void,
+ @ViewBuilder content: () -> Content = { EmptyView() },
+ @ViewBuilder icon: () -> Icon
+ ) {
+ self.title = title
+ self.description = description
+ self.disclosure = disclosure
+ self.showBorder = showBorder
+ self.titleStyle = titleStyle
+ self.descriptionColor = descriptionColor
+ self.action = action
+ self.content = content()
+ self.icon = icon()
+ }
+
+ /// Creates Orbit ``Tile`` component.
init(
_ title: String = "",
description: String = "",
@@ -166,29 +220,6 @@ public extension Tile {
Icon(icon)
}
}
-
- /// Creates Orbit Tile component with custom icon.
- init(
- _ title: String = "",
- description: String = "",
- disclosure: TileDisclosure = .icon(.chevronForward),
- showBorder: Bool = true,
- titleStyle: Heading.Style = .title4,
- descriptionColor: Color = .inkNormal,
- action: @escaping () -> Void,
- @ViewBuilder content: () -> Content = { EmptyView() },
- @ViewBuilder icon: () -> Icon
- ) {
- self.title = title
- self.description = description
- self.disclosure = disclosure
- self.showBorder = showBorder
- self.titleStyle = titleStyle
- self.descriptionColor = descriptionColor
- self.action = action
- self.content = content()
- self.icon = icon()
- }
}
// MARK: - Modifiers
diff --git a/Sources/Orbit/Components/TileGroup.swift b/Sources/Orbit/Components/TileGroup.swift
index 54696854e6f..d17f3af0e80 100644
--- a/Sources/Orbit/Components/TileGroup.swift
+++ b/Sources/Orbit/Components/TileGroup.swift
@@ -1,32 +1,42 @@
import SwiftUI
-/// Wraps tiles to show related interactions.
+/// Orbit component that wraps multiple ``Tile``s to show related interactions.
///
-/// Only ``Tile``s should be used inside of a group.
-///
-/// Tiles in a group show separators by default, except for the last tile,
-/// which is handled automatically and never shows a separator.
+/// A ``TileGroup`` consists of a set of ``Tile`` content:
+///
+/// ```swift
+/// TileGroup {
+/// Tile("Title 1")
+/// Tile("Title 2")
+/// }
+/// ```
///
+/// All tiles in a group include bottom separators by default, except for the last separator.
/// Use ``Tile/tileSeparator(_:)`` to modify separator visibility for a given tile:
///
/// ```swift
/// TileGroup {
-/// Tile("Title")
-/// Tile("No Separator")
+/// Tile("Tile with no Separator")
/// .tileSeparator(false)
-/// Tile("Title")
+/// Tile("Tile 2")
/// }
/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/tilegroup/)
-public struct TileGroup: View, PotentiallyEmptyView {
+/// ### Layout
+///
+/// The component adds a `VStack` over the provided content. Avoid using the component when the content is large and should be embedded in a lazy stack.
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/tilegroup/)
+public struct TileGroup: View, PotentiallyEmptyView {
- @ViewBuilder let content: Content
+ @ViewBuilder private let tiles: Tiles
public var body: some View {
if isEmpty == false {
VStack(alignment: .leading, spacing: 0) {
- content
+ tiles
.environment(\.isInsideTileGroup, true)
}
// hide any last separator automatically by clipping it
@@ -38,12 +48,16 @@ public struct TileGroup: View, PotentiallyEmptyView {
}
var isEmpty: Bool {
- content.isEmpty
+ tiles.isEmpty
}
+}
+
+// MARK: - Inits
+public extension TileGroup {
- /// Creates Orbit TileGroup component as a wrapper for Tile content.
- public init(@ViewBuilder _ content: () -> Content) {
- self.content = content()
+ /// Creates Orbit ``TileGroup`` component.
+ init(@ViewBuilder _ tiles: () -> Tiles) {
+ self.tiles = tiles()
}
}
diff --git a/Sources/Orbit/Components/Timeline.swift b/Sources/Orbit/Components/Timeline.swift
index 5ac6abe5f59..8f287e2c395 100644
--- a/Sources/Orbit/Components/Timeline.swift
+++ b/Sources/Orbit/Components/Timeline.swift
@@ -1,20 +1,31 @@
import SwiftUI
-/// Shows progress on a process over time.
+/// Orbit component that shows progress on a process over time.
///
-/// - Related components
-/// - ``TimelineItem``
+/// A ``Timeline`` consists of a set of ``TimelineItem`` content:
+///
+/// ```swift
+/// Timeline {
+/// TimelineItem("Booked", type: .past)
+/// TimelineItem("Checked in", type: .past)
+/// TimelineItem("Board", type: .present)
+/// }
+/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/progress-indicators/timeline/)
-public struct Timeline: View, PotentiallyEmptyView {
-
- @Environment(\.sizeCategory) var sizeCategory
- @ViewBuilder let content: Content
+/// ### Layout
+///
+/// When the provided content is empty, the component results in `EmptyView` so that it does not take up any space in the layout.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/progress-indicators/timeline/)
+public struct Timeline: View, PotentiallyEmptyView {
+ @Environment(\.sizeCategory) private var sizeCategory
+ @ViewBuilder private let timelineItems: TimelineItems
+
public var body: some View {
if isEmpty == false {
- VStack(alignment: .leading, spacing: Self.spacing) {
- content
+ VStack(alignment: .leading, spacing: .large) {
+ timelineItems
}
.backgroundPreferenceValue(TimelineItemPreferenceKey.self) { preferences in
GeometryReader { geometry in
@@ -35,29 +46,27 @@ public struct Timeline: View, PotentiallyEmptyView {
}
var isEmpty: Bool {
- content.isEmpty
+ timelineItems.isEmpty
}
- func progressLineHeight(
+ private func progressLineHeight(
for index: Int,
in preferences: TimelineItemPreferenceKey.Value,
geometry: GeometryProxy
) -> CGFloat {
guard preferences.indices.contains(index) else { return 0 }
- return geometry[preferences[index].bounds].height + Self.spacing
- }
-
- /// Creates Orbit TimelineItem component.
- public init(@ViewBuilder content: () -> Content) {
- self.content = content()
+ return geometry[preferences[index].bounds].height + .large
}
}
-// MARK: - Constants
+// MARK: - Inits
public extension Timeline {
- static var spacing: CGFloat { .large }
+ /// Creates Orbit ``TimelineItem`` component.
+ init(@ViewBuilder _ timelineItems: () -> TimelineItems) {
+ self.timelineItems = timelineItems()
+ }
}
// MARK: - Previews
@@ -101,7 +110,7 @@ struct TimelinePreviews: PreviewProvider {
TimelineItem(
"Board",
sublabel: "May 4, 8:15",
- type: .present(),
+ type: .present,
description: "Be at your departure gate at least 30 minutes before boarding."
) {
contentPlaceholder
diff --git a/Sources/Orbit/Components/Toast.swift b/Sources/Orbit/Components/Toast.swift
index e2c3668cee8..c2295ab9f2b 100644
--- a/Sources/Orbit/Components/Toast.swift
+++ b/Sources/Orbit/Components/Toast.swift
@@ -1,13 +1,33 @@
import Combine
import SwiftUI
-/// Toast shows a brief message that’s clear & understandable.
+/// Orbit component that shows a brief overlay message on top of the content.
+///
+/// Each displayed ``ToastWrapper`` (an interactive wrapper over ``ToastContent``) can be dismissed by a gesture.
+///
+/// A ``Toast`` queue is managed by a ``ToastQueue`` that resolves what message will be displayed at which time:
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/information/toast/)
-/// - Important: Component expands horizontally to infinity.
+/// ```swift
+/// @State var toastQueue = ToastQueue()
+///
+/// var body: some View {
+/// VStack {
+/// // content over which to display Toasts
+/// }
+/// .overlay(alignment: .top) {
+/// Toast(toastQueue: toastQueue)
+/// }
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// Component expands horizontally unless prevented by the native `fixedSize()` modifier.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/information/toast/)
public struct Toast: View {
- @ObservedObject var toastQueue: ToastQueue
+ @ObservedObject private var toastQueue: ToastQueue
public var body: some View {
if let toast = toastQueue.toast {
@@ -25,40 +45,21 @@ public struct Toast: View {
}
}
- /// Creates Orbit Toast component with queue management and gesture handling.
- ///
- /// Apply ``Toast`` as a `.top` overlay to an existing view.
- /// Provide an instance of ``ToastQueue``, which manages a queue of toasts.
- ///
- /// The following example shows a ``Toast`` applied to a view:
- ///
- /// ```swift
- /// let toastQueue = ToastQueue()
- ///
- /// var body: some View {
- /// VStack {
- /// // content over which to display Toasts
- /// }
- /// .overlay(Toast(toastQueue: toastQueue), alignment: .top)
- /// }
- /// ```
- /// Alternatively:
- /// - ``ToastWrapper`` can be used when gesture handling is needed, but no queue management.
- /// - ``ToastContent`` when neither gesture handling or queue management is needed.
+ /// Creates Orbit ``Toast`` component.
public init(toastQueue: ToastQueue) {
self.toastQueue = toastQueue
}
}
-/// Variant of Orbit `Toast` component with no gesture handling or queue management.
+/// Orbit ``Toast`` with no gesture handling or queue management.
public struct ToastContent: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.textColor) private var textColor
- let description: String
- let icon: Icon.Symbol?
- let progress: CGFloat
+ private let description: String
+ private let icon: Icon.Symbol?
+ private let progress: CGFloat
public var body: some View {
HStack(alignment: .top, spacing: .xSmall) {
@@ -72,14 +73,14 @@ public struct ToastContent: View {
.background(background)
}
- @ViewBuilder var background: some View {
+ @ViewBuilder private var background: some View {
backgroundColor
.overlay(progressIndicator, alignment: .leading)
.clipShape(shape)
.elevation(.level3, shape: .roundedRectangle())
}
- @ViewBuilder var progressIndicator: some View {
+ @ViewBuilder private var progressIndicator: some View {
GeometryReader { geometry in
progressColor
.opacity(max(0, progress * 2 - 0.5) * 0.3)
@@ -89,23 +90,23 @@ public struct ToastContent: View {
}
}
- var foregroundColor: Color {
+ private var foregroundColor: Color {
colorScheme == .light ? .whiteNormal : .inkDark
}
- var backgroundColor: Color {
+ private var backgroundColor: Color {
colorScheme == .light ? .inkDark : .whiteDarker
}
- var progressColor: Color {
+ private var progressColor: Color {
colorScheme == .light ? .inkNormal : .cloudNormal
}
- var shape: some Shape {
+ private var shape: some Shape {
RoundedRectangle(cornerRadius: BorderRadius.default, style: .continuous)
}
- /// Creates Orbit `Toast` component variant with no gesture handling or queue management.
+ /// Creates Orbit ``ToastContent`` component with no gesture handling or queue management.
public init(_ description: String, icon: Icon.Symbol? = nil, progress: CGFloat = 0) {
self.description = description
self.icon = icon
@@ -113,7 +114,7 @@ public struct ToastContent: View {
}
}
-/// Variant of Orbit `Toast` component with gesture handling, but no queue management.
+/// Orbit ``ToastWrapper`` component with gesture handling, but no queue management.
public struct ToastWrapper: View {
static let minOffsetY: CGFloat = -10
@@ -121,12 +122,12 @@ public struct ToastWrapper: View {
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
- let description: String
- let icon: Icon.Symbol?
- let progress: CGFloat
- let pauseAction: () -> Void
- let resumeAction: () -> Void
- let dismissAction: () -> Void
+ private let description: String
+ private let icon: Icon.Symbol?
+ private let progress: CGFloat
+ private let pauseAction: () -> Void
+ private let resumeAction: () -> Void
+ private let dismissAction: () -> Void
@State private var offsetY: CGFloat = 0
@State private var gaveFeedback: Bool = false
@@ -155,23 +156,37 @@ public struct ToastWrapper: View {
)
}
- var isOffsetDismiss: Bool {
+ private var isOffsetDismiss: Bool {
offsetY < Self.minOffsetY
}
- var dismissProgress: CGFloat {
+ private var dismissProgress: CGFloat {
min(0, cappedOffsetY) / Self.minOffsetY
}
- var opacity: CGFloat {
+ private var opacity: CGFloat {
return 1 - dismissProgress * 0.2
}
- var cappedOffsetY: CGFloat {
+ private var cappedOffsetY: CGFloat {
min(Self.maxOffsetY, offsetY)
}
-
- /// Creates Orbit `Toast` component variant with gesture handling.
+
+ private func processDragChanged() {
+ if dismissProgress >= 1, gaveFeedback == false {
+ if isHapticsEnabled {
+ HapticsProvider.sendHapticFeedback(.notification(.warning))
+ }
+
+ gaveFeedback = true
+ }
+
+ if dismissProgress == 0 {
+ gaveFeedback = false
+ }
+ }
+
+ /// Creates Orbit ``ToastWrapper`` component.
public init(
_ description: String,
icon: Icon.Symbol? = nil,
@@ -188,19 +203,6 @@ public struct ToastWrapper: View {
self.dismissAction = dismissAction
}
- private func processDragChanged() {
- if dismissProgress >= 1, gaveFeedback == false {
- if isHapticsEnabled {
- HapticsProvider.sendHapticFeedback(.notification(.warning))
- }
-
- gaveFeedback = true
- }
-
- if dismissProgress == 0 {
- gaveFeedback = false
- }
- }
}
// MARK: - Previews
diff --git a/Sources/Orbit/Foundation/Borders/BorderRadius.swift b/Sources/Orbit/Foundation/Borders/BorderRadius.swift
index 529e1f90c1f..ad7e157144f 100644
--- a/Sources/Orbit/Foundation/Borders/BorderRadius.swift
+++ b/Sources/Orbit/Foundation/Borders/BorderRadius.swift
@@ -1,8 +1,8 @@
import CoreGraphics
-/// Defines Orbit border radiuses.
+/// Orbit predefined border radiuses.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/foundation/border-radiuses/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/foundation/border-radiuses/)
public enum BorderRadius {
/// 3 pts border radius.
public static let desktop: CGFloat = 3
diff --git a/Sources/Orbit/Foundation/Borders/BorderWidth.swift b/Sources/Orbit/Foundation/Borders/BorderWidth.swift
index b0b9a7e53cf..8b5d3d752e3 100644
--- a/Sources/Orbit/Foundation/Borders/BorderWidth.swift
+++ b/Sources/Orbit/Foundation/Borders/BorderWidth.swift
@@ -1,7 +1,7 @@
import CoreGraphics
import UIKit
-/// Defines Orbit border widths.
+/// Predefiend Orbit border widths.
public enum BorderWidth {
/// 1 pixel border width.
public static let hairline: CGFloat = 1.0 / UIScreen.main.scale
diff --git a/Sources/Orbit/Foundation/Colors/Gradients.swift b/Sources/Orbit/Foundation/Colors/Gradients.swift
index 16bc57eb203..6e8f43a2975 100644
--- a/Sources/Orbit/Foundation/Colors/Gradients.swift
+++ b/Sources/Orbit/Foundation/Colors/Gradients.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Defines Orbit gradient styles.
+/// Predefined Orbit gradient styles.
public enum Gradient {
case bundleBasic
diff --git a/Sources/Orbit/Foundation/CountryFlags/CountryFlags+Extensions.swift b/Sources/Orbit/Foundation/CountryFlags/CountryFlags+Extensions.swift
index 2bea0a76477..c10e7fc9158 100644
--- a/Sources/Orbit/Foundation/CountryFlags/CountryFlags+Extensions.swift
+++ b/Sources/Orbit/Foundation/CountryFlags/CountryFlags+Extensions.swift
@@ -1,6 +1,7 @@
public extension CountryFlag.CountryCode {
+ /// Create Orbit ``CountryCode`` from a `String`.
init(_ string: String) {
self = Self(rawValue: string.lowercased()) ?? .unknown
}
diff --git a/Sources/Orbit/Foundation/Elevations/Elevation.swift b/Sources/Orbit/Foundation/Elevations/Elevation.swift
index 9eac50bb7bb..6207c7a798a 100644
--- a/Sources/Orbit/Foundation/Elevations/Elevation.swift
+++ b/Sources/Orbit/Foundation/Elevations/Elevation.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Use elevation to bring content closer to users.
+/// Predefined Orbit elevation that brings content closer to user.
///
/// Elevation levels with higher numbers are usually visually closer to the user.
public enum Elevation {
@@ -11,7 +11,7 @@ public enum Elevation {
case custom(opacity: Double, radius: CGFloat, x: CGFloat = 0, y: CGFloat = 0, padding: CGFloat? = nil)
}
-/// A shape to use as a surface on which `elevation` is applied.
+/// A shape to use as a surface on which Orbit `elevation` is applied.
public enum ElevationShape {
/// Elevation effect shape is based on provided content.
///
@@ -29,7 +29,7 @@ public enum ElevationShape {
public extension View {
- /// Elevates the view to make it more prominent.
+ /// Elevates the Orbit view to make it more prominent.
///
/// Effective only in light mode.
func elevation(
diff --git a/Sources/Orbit/Foundation/Spacing/Spacing.swift b/Sources/Orbit/Foundation/Spacing/Spacing.swift
index 186900f19da..a043f16c3cd 100644
--- a/Sources/Orbit/Foundation/Spacing/Spacing.swift
+++ b/Sources/Orbit/Foundation/Spacing/Spacing.swift
@@ -1,10 +1,8 @@
import SwiftUI
-/// Consistent spacing makes an interface more clear and easy to scan.
+/// Predefined Orbit spacing to help making interface clear and easy to scan.
///
-/// Our spacing is based on a 4-pixel grid.
-///
-/// - Note: [Orbit definition](https://orbit.kiwi/foundation/spacing/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/foundation/spacing/)
public enum Spacing: CGFloat {
/// 2 pts.
case xxxSmall = 2
@@ -29,24 +27,24 @@ public enum Spacing: CGFloat {
}
public extension CGFloat {
- /// 2 pts
+ /// Orbit 2 pts spacing.
static let xxxSmall = Spacing.xxxSmall.rawValue
- /// 4 pts.
+ /// Orbit 4 pts spacing.
static let xxSmall = Spacing.xxSmall.rawValue
- /// 8 pts.
+ /// Orbit 8 pts spacing.
static let xSmall = Spacing.xSmall.rawValue
- /// 12 pts.
+ /// Orbit 12 pts spacing.
static let small = Spacing.small.rawValue
- /// 16 pts.
+ /// Orbit 16 pts spacing.
static let medium = Spacing.medium.rawValue
- /// 20 pts.
+ /// Orbit 20 pts spacing.
static let xMedium = Spacing.xMedium.rawValue
- /// 24 pts.
+ /// Orbit 24 pts spacing.
static let large = Spacing.large.rawValue
- /// 32 pts.
+ /// Orbit 32 pts spacing.
static let xLarge = Spacing.xLarge.rawValue
- /// 44 pts.
+ /// Orbit 44 pts spacing.
static let xxLarge = Spacing.xxLarge.rawValue
- /// 60 pts.
+ /// Orbit 60 pts spacing.
static let xxxLarge = Spacing.xxxLarge.rawValue
}
diff --git a/Sources/Orbit/Foundation/Typography/Font.swift b/Sources/Orbit/Foundation/Typography/Font.swift
index 392ae353453..6be0e356cdb 100644
--- a/Sources/Orbit/Foundation/Typography/Font.swift
+++ b/Sources/Orbit/Foundation/Typography/Font.swift
@@ -7,10 +7,10 @@ public extension Font {
static let orbitIconFontName = "orbit-icons"
- /// Default ratio between font size and desired line height, used for calculating custom text sizes.
+ /// Default ratio between Orbit font size and desired line height, used for calculating custom text sizes.
static var fontSizeToLineHeightRatio: CGFloat = 1.3333
- /// Fonts used for rendering text in Orbit.
+ /// Default Orbit fonts used for rendering text.
static var orbitFonts: [Font.Weight: URL?] = [
.ultraLight: Bundle.orbit.url(forResource: "Circular20-Book", withExtension: "otf"),
.thin: Bundle.orbit.url(forResource: "Circular20-Book", withExtension: "otf"),
@@ -117,7 +117,7 @@ public extension ContentSizeCategory {
}
}
- /// Effective size ratio for controls, based on font size ratio.
+ /// Effective size ratio for Orbit controls, based on font size ratio.
/// The ratio is smaller than font size ratio and should be used for components or indicators that are already large enough.
var controlRatio: CGFloat {
1 + (ratio - 1) * 0.5
diff --git a/Sources/Orbit/Support/Accessibility/AccessibilityID.swift b/Sources/Orbit/Support/Accessibility/AccessibilityID.swift
index 5422584d2ab..4721fc81a60 100644
--- a/Sources/Orbit/Support/Accessibility/AccessibilityID.swift
+++ b/Sources/Orbit/Support/Accessibility/AccessibilityID.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Orbit accessibility identifier for use in wrapper components.
+/// Orbit accessibility identifier that identifies embedded sub-components.
///
/// Can be extended to provide custom accessibility identifiers.
public struct AccessibilityID: RawRepresentable, Equatable, Hashable {
@@ -14,13 +14,13 @@ public struct AccessibilityID: RawRepresentable, Equatable, Hashable {
public extension View {
- /// Uses the specified identifier to identify the view inside a component.
+ /// Uses the specified Orbit identifier to identify the view inside a component.
@available(iOS 14.0, *)
func accessibilityIdentifier(_ accessibilityID: AccessibilityID) -> some View {
self.accessibilityIdentifier(accessibilityID.rawValue)
}
- /// Uses the specified identifier to identify the view inside a component.
+ /// Uses the specified Orbit identifier to identify the view inside a component.
@available(iOS, introduced: 13.0, deprecated: 16.1, renamed: "accessibilityIdentifier(_:)")
func accessibility(_ accessibilityID: AccessibilityID) -> some View {
self.accessibility(identifier: accessibilityID.rawValue)
diff --git a/Sources/Orbit/Support/Builders/AlertButtonsBuilder.swift b/Sources/Orbit/Support/Builders/AlertButtonsBuilder.swift
index 70f9aab3c90..ce8f5baabe4 100644
--- a/Sources/Orbit/Support/Builders/AlertButtonsBuilder.swift
+++ b/Sources/Orbit/Support/Builders/AlertButtonsBuilder.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// A builder that constructs buttons for the ``Alert`` component.
+/// A builder that constructs buttons for the Orbit ``Alert`` component.
@resultBuilder
public enum AlertButtonsBuilder {
diff --git a/Sources/Orbit/Support/Builders/AlertInlineButtonsBuilder.swift b/Sources/Orbit/Support/Builders/AlertInlineButtonsBuilder.swift
index b8f71030067..910b67dc393 100644
--- a/Sources/Orbit/Support/Builders/AlertInlineButtonsBuilder.swift
+++ b/Sources/Orbit/Support/Builders/AlertInlineButtonsBuilder.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// A builder that constructs buttons for the ``AlertInline`` component.
+/// A builder that constructs buttons for the Orbit ``AlertInline`` component.
@resultBuilder
public enum AlertInlineButtonsBuilder {
diff --git a/Sources/Orbit/Support/ButtonStyles/AlertButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/AlertButtonStyle.swift
index 578956121f6..31549141979 100644
--- a/Sources/Orbit/Support/ButtonStyles/AlertButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/AlertButtonStyle.swift
@@ -26,7 +26,7 @@ public struct AlertButtonStyle: PrimitiveButtonStyle {
.backgroundStyle(background, active: backgroundActive)
}
- var textColor: Color {
+ private var textColor: Color {
switch (resolvedPriority, isSubtle) {
case (.primary, _): return .whiteNormal
case (.secondary, true): return .inkDark
@@ -34,7 +34,7 @@ public struct AlertButtonStyle: PrimitiveButtonStyle {
}
}
- var textActiveColor: Color {
+ private var textActiveColor: Color {
switch (resolvedPriority, isSubtle) {
case (.primary, _): return .whiteNormal
case (.secondary, true): return .inkDarkActive
@@ -42,7 +42,7 @@ public struct AlertButtonStyle: PrimitiveButtonStyle {
}
}
- var background: Color {
+ private var background: Color {
switch (resolvedPriority, isSubtle) {
case (.primary, _): return resolvedStatus.color
case (.secondary, true): return .inkDark.opacity(0.1)
@@ -50,7 +50,7 @@ public struct AlertButtonStyle: PrimitiveButtonStyle {
}
}
- var backgroundActive: Color {
+ private var backgroundActive: Color {
switch (resolvedPriority, isSubtle) {
case (.primary, _): return resolvedStatus.activeColor
case (.secondary, true): return .inkDark.opacity(0.2)
@@ -58,15 +58,15 @@ public struct AlertButtonStyle: PrimitiveButtonStyle {
}
}
- var resolvedPriority: ButtonPriority {
+ private var resolvedPriority: ButtonPriority {
buttonPriority ?? .primary
}
- var resolvedStatus: Status {
+ private var resolvedStatus: Status {
status ?? .info
}
- /// Create button style for Orbit ``Alert`` component.
+ /// Creates button style for Orbit ``Alert`` component.
public init() {}
}
diff --git a/Sources/Orbit/Support/ButtonStyles/CheckboxButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/CheckboxButtonStyle.swift
index ae359ae01b6..4e16e16e168 100644
--- a/Sources/Orbit/Support/ButtonStyles/CheckboxButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/CheckboxButtonStyle.swift
@@ -7,7 +7,7 @@ public struct CheckboxButtonStyle: ButtonStyle {
@Environment(\.sizeCategory) private var sizeCategory
@Environment(\.isEnabled) private var isEnabled
- @Environment(\.textColor) var textColor
+ @Environment(\.textColor) private var textColor
private let state: Checkbox.State
private let isChecked: Bool
@@ -20,7 +20,7 @@ public struct CheckboxButtonStyle: ButtonStyle {
.accessibility(addTraits: isChecked ? .isSelected : [])
}
- func indicator(isPressed: Bool) -> some View {
+ private func indicator(isPressed: Bool) -> some View {
shape
.strokeBorder(indicatorStrokeColor(isPressed: isPressed), lineWidth: indicatorStrokeWidth)
.background(
@@ -50,11 +50,11 @@ public struct CheckboxButtonStyle: ButtonStyle {
}
}
- var shape: some InsettableShape {
+ private var shape: some InsettableShape {
RoundedRectangle(cornerRadius: BorderRadius.default * sizeCategory.controlRatio, style: .continuous)
}
- func indicatorStrokeColor(isPressed: Bool) -> some ShapeStyle {
+ private func indicatorStrokeColor(isPressed: Bool) -> some ShapeStyle {
switch (isEnabled, isChecked, isPressed) {
case (true, true, false): return .blueNormal
case (true, true, true): return .blueLightActive
@@ -62,7 +62,7 @@ public struct CheckboxButtonStyle: ButtonStyle {
}
}
- func indicatorBackgroundColor(isPressed: Bool) -> some ShapeStyle {
+ private func indicatorBackgroundColor(isPressed: Bool) -> some ShapeStyle {
switch (isEnabled, isChecked, isPressed) {
case (true, true, false): return .blueNormal
case (true, true, true): return .blueLightActive
@@ -72,7 +72,7 @@ public struct CheckboxButtonStyle: ButtonStyle {
}
}
- func indicatorOverlayStrokeColor(isPressed: Bool) -> some ShapeStyle {
+ private func indicatorOverlayStrokeColor(isPressed: Bool) -> some ShapeStyle {
switch (state, isPressed) {
case (.normal, true): return .blueNormal
case (.error, true): return .redLightActive
@@ -81,31 +81,31 @@ public struct CheckboxButtonStyle: ButtonStyle {
}
}
- var labelColor: Color {
+ private var labelColor: Color {
isEnabled
? textColor ?? .inkDark
: .cloudDarkHover
}
- var descriptionColor: Color {
+ private var descriptionColor: Color {
isEnabled
? .inkNormal
: .cloudDarkHover
}
- var size: CGFloat {
+ private var size: CGFloat {
Self.size * sizeCategory.controlRatio
}
- var inset: CGFloat {
+ private var inset: CGFloat {
0.5 * sizeCategory.controlRatio
}
- var errorStrokeWidth: CGFloat {
+ private var errorStrokeWidth: CGFloat {
3 * sizeCategory.controlRatio
}
- var indicatorStrokeWidth: CGFloat {
+ private var indicatorStrokeWidth: CGFloat {
2 * sizeCategory.controlRatio
}
diff --git a/Sources/Orbit/Support/ButtonStyles/ListChoiceButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/ListChoiceButtonStyle.swift
index e1e75d370fd..1c8547d0317 100644
--- a/Sources/Orbit/Support/ButtonStyles/ListChoiceButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/ListChoiceButtonStyle.swift
@@ -13,7 +13,7 @@ public struct ListChoiceButtonStyle: ButtonStyle {
)
}
- @ViewBuilder func backgroundColor(isPressed: Bool) -> some View {
+ @ViewBuilder private func backgroundColor(isPressed: Bool) -> some View {
if isPressed {
resolvedActiveBackground
} else {
@@ -21,7 +21,7 @@ public struct ListChoiceButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedInactiveBackground: some View {
+ @ViewBuilder private var resolvedInactiveBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -29,7 +29,7 @@ public struct ListChoiceButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedActiveBackground: some View {
+ @ViewBuilder private var resolvedActiveBackground: some View {
if let backgroundShape {
backgroundShape.activeView
} else {
diff --git a/Sources/Orbit/Support/ButtonStyles/OrbitButtonLinkButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/OrbitButtonLinkButtonStyle.swift
index 011d08ea8bb..a3d7e406bc8 100644
--- a/Sources/Orbit/Support/ButtonStyles/OrbitButtonLinkButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/OrbitButtonLinkButtonStyle.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Customized button style for Orbit ``ButtonLink`` component.
+/// Button style for Orbit ``ButtonLink`` component.
public struct OrbitButtonLinkButtonStyle: PrimitiveButtonStyle {
@Environment(\.buttonSize) private var buttonSize
@@ -34,7 +34,7 @@ public struct OrbitButtonLinkButtonStyle:
.idealSize(horizontal: idealSizeHorizontal, vertical: idealSize.vertical)
}
- var backgroundActive: Color {
+ private var backgroundActive: Color {
switch type {
case .primary: return .productLightActive
case .critical: return .redLightActive
@@ -42,17 +42,17 @@ public struct OrbitButtonLinkButtonStyle:
}
}
- var resolvedButtonSize: ButtonSize {
+ private var resolvedButtonSize: ButtonSize {
buttonSize ?? .regular
}
- var idealSizeHorizontal: Bool? {
+ private var idealSizeHorizontal: Bool? {
idealSize.horizontal == false
? idealSize.horizontal
: (resolvedButtonSize == .compact || idealSize.horizontal == true)
}
- var textColor: Color {
+ private var textColor: Color {
switch type {
case .primary: return .productNormal
case .critical: return .redNormal
@@ -60,7 +60,7 @@ public struct OrbitButtonLinkButtonStyle:
}
}
- var textActiveColor: Color {
+ private var textActiveColor: Color {
switch type {
case .primary: return .productDarkActive
case .critical: return .redDarkActive
@@ -68,14 +68,14 @@ public struct OrbitButtonLinkButtonStyle:
}
}
- var resolvedStatus: Status {
+ private var resolvedStatus: Status {
switch type {
case .status(let status): return status ?? self.status ?? .info
default: return .info
}
}
- var hapticFeedback: HapticsProvider.HapticFeedbackType {
+ private var hapticFeedback: HapticsProvider.HapticFeedbackType {
switch type {
case .primary: return .light(1)
case .critical: return .notification(.error)
@@ -83,28 +83,28 @@ public struct OrbitButtonLinkButtonStyle:
}
}
- var horizontalPadding: CGFloat {
+ private var horizontalPadding: CGFloat {
switch resolvedButtonSize {
case .regular: return .small
case .compact: return 0
}
}
- var verticalPadding: CGFloat {
+ private var verticalPadding: CGFloat {
switch resolvedButtonSize {
case .regular: return .small // = 44 height @ normal size
case .compact: return 6 // = 32 height @ normal size
}
}
- var horizontalBackgroundPadding: CGFloat {
+ private var horizontalBackgroundPadding: CGFloat {
switch resolvedButtonSize {
case .regular: return 0
case .compact: return .xSmall
}
}
- var verticalBackgroundPadding: CGFloat {
+ private var verticalBackgroundPadding: CGFloat {
switch resolvedButtonSize {
case .regular: return 0
case .compact: return .xxxSmall
diff --git a/Sources/Orbit/Support/ButtonStyles/OrbitButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/OrbitButtonStyle.swift
index df8df5e7c5f..617a3c42477 100644
--- a/Sources/Orbit/Support/ButtonStyles/OrbitButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/OrbitButtonStyle.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Button style for Orbit ``Button`` component.
+/// Button style for Orbit primary ``Button`` component.
///
/// The style can be further customized by using Orbit environment modifiers.
public struct OrbitButtonStyle: PrimitiveButtonStyle {
@@ -31,7 +31,7 @@ public struct OrbitButtonStyle: Primitive
.backgroundStyle(backgroundShape?.inactive ?? background, active: backgroundShape?.active ?? backgroundActive)
}
- var background: Color {
+ private var background: Color {
switch type {
case .primary: return .productNormal
case .primarySubtle: return .productLight
@@ -43,7 +43,7 @@ public struct OrbitButtonStyle: Primitive
}
}
- var backgroundActive: Color {
+ private var backgroundActive: Color {
switch type {
case .primary: return .productNormalActive
case .primarySubtle: return .productLightActive
@@ -55,7 +55,7 @@ public struct OrbitButtonStyle: Primitive
}
}
- var labelColor: Color {
+ private var labelColor: Color {
switch type {
case .primary: return .whiteNormal
case .primarySubtle: return .productDark
@@ -67,18 +67,18 @@ public struct OrbitButtonStyle: Primitive
}
}
- var resolvedStatus: Status {
+ private var resolvedStatus: Status {
switch type {
case .status(let status, _): return status ?? self.status ?? .info
default: return .info
}
}
- var resolvedButtonSize: ButtonSize {
+ private var resolvedButtonSize: ButtonSize {
buttonSize ?? .regular
}
- var hapticFeedback: HapticsProvider.HapticFeedbackType {
+ private var hapticFeedback: HapticsProvider.HapticFeedbackType {
switch type {
case .primary: return .light(1)
case .primarySubtle, .secondary: return .light(0.5)
@@ -87,14 +87,14 @@ public struct OrbitButtonStyle: Primitive
}
}
- var textSize: Text.Size {
+ private var textSize: Text.Size {
switch resolvedButtonSize {
case .regular: return .normal
case .compact: return .small
}
}
- var padding: CGFloat {
+ private var padding: CGFloat {
switch resolvedButtonSize {
case .regular: return .small // = 44 height @ normal size
case .compact: return .xSmall // = 32 height @ normal size
diff --git a/Sources/Orbit/Support/ButtonStyles/RadioButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/RadioButtonStyle.swift
index 4bf548e9a6c..a44c3ff2e9d 100644
--- a/Sources/Orbit/Support/ButtonStyles/RadioButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/RadioButtonStyle.swift
@@ -19,7 +19,7 @@ public struct RadioButtonStyle: ButtonStyle {
.accessibility(addTraits: isChecked ? .isSelected : [])
}
- func indicator(isPressed: Bool) -> some View {
+ private func indicator(isPressed: Bool) -> some View {
indicatorShape
.strokeBorder(indicatorStrokeColor(isPressed: isPressed), lineWidth: strokeWidth)
.background(
@@ -43,11 +43,11 @@ public struct RadioButtonStyle: ButtonStyle {
}
}
- var indicatorShape: some InsettableShape {
+ private var indicatorShape: some InsettableShape {
Circle()
}
- func indicatorStrokeColor(isPressed: Bool) -> some ShapeStyle {
+ private func indicatorStrokeColor(isPressed: Bool) -> some ShapeStyle {
switch (isEnabled, isChecked, isPressed) {
case (true, true, false): return .blueNormal
case (true, true, true): return .blueLightActive
@@ -55,14 +55,14 @@ public struct RadioButtonStyle: ButtonStyle {
}
}
- var indicatorBackgroundColor: some ShapeStyle {
+ private var indicatorBackgroundColor: some ShapeStyle {
switch (isEnabled, isChecked) {
case (false, false): return .cloudNormal
case (_, _): return .clear
}
}
- func indicatorOverlayStrokeColor(isPressed: Bool) -> some ShapeStyle {
+ private func indicatorOverlayStrokeColor(isPressed: Bool) -> some ShapeStyle {
switch (state, isPressed) {
case (.normal, true): return .blueNormal
case (.error, true): return .redLightActive
@@ -71,19 +71,19 @@ public struct RadioButtonStyle: ButtonStyle {
}
}
- var size: CGFloat {
+ private var size: CGFloat {
Self.size * sizeCategory.controlRatio
}
- var strokeWidth: CGFloat {
+ private var strokeWidth: CGFloat {
(isChecked ? 6 : 2) * sizeCategory.controlRatio
}
- var errorStrokeWidth: CGFloat {
+ private var errorStrokeWidth: CGFloat {
3 * sizeCategory.controlRatio
}
- var indicatorStrokeWidth: CGFloat {
+ private var indicatorStrokeWidth: CGFloat {
2 * sizeCategory.controlRatio
}
diff --git a/Sources/Orbit/Support/ButtonStyles/TagButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/TagButtonStyle.swift
index 19300120e75..30deb05a306 100644
--- a/Sources/Orbit/Support/ButtonStyles/TagButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/TagButtonStyle.swift
@@ -39,7 +39,7 @@ public struct TagButtonStyle: ButtonStyle {
.cornerRadius(BorderRadius.default)
}
- @ViewBuilder func resolvedBackgroundColor(isPressed: Bool) -> some View {
+ @ViewBuilder private func resolvedBackgroundColor(isPressed: Bool) -> some View {
if isPressed {
resolvedActiveBackground
} else {
@@ -47,7 +47,7 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedInactiveBackground: some View {
+ @ViewBuilder private var resolvedInactiveBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -55,7 +55,7 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedActiveBackground: some View {
+ @ViewBuilder private var resolvedActiveBackground: some View {
if let backgroundShape {
backgroundShape.activeView
} else {
@@ -63,7 +63,7 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- var inactiveBackgroundColor: Color {
+ private var inactiveBackgroundColor: Color {
switch (isFocused, isSelected) {
case (true, false): return .blueLight
case (true, true): return .blueNormal
@@ -72,7 +72,7 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- var activeBackgroundColor: Color {
+ private var activeBackgroundColor: Color {
switch (isFocused, isSelected) {
case (true, false): return .blueLightActive
case (true, true): return .blueNormalActive
@@ -81,11 +81,11 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- var resolvedTextColor: Color {
+ private var resolvedTextColor: Color {
textColor ?? labelColor
}
- var labelColor: Color {
+ private var labelColor: Color {
switch (isFocused, isSelected) {
case (_, true): return .whiteNormal
case (true, false): return .blueDarker
@@ -93,11 +93,11 @@ public struct TagButtonStyle: ButtonStyle {
}
}
- func resolvedIconColor(isPressed: Bool) -> Color {
+ private func resolvedIconColor(isPressed: Bool) -> Color {
iconColor ?? iconColor(isPressed: isPressed)
}
- func iconColor(isPressed: Bool) -> Color {
+ private func iconColor(isPressed: Bool) -> Color {
switch (isSelected, isFocused, isPressed) {
case (true, _, _): return .whiteNormal
case (false, true, false): return .blueDarker.opacity(0.3)
diff --git a/Sources/Orbit/Support/ButtonStyles/TileButtonStyle.swift b/Sources/Orbit/Support/ButtonStyles/TileButtonStyle.swift
index e3c22da42b1..0ae9a56e38a 100644
--- a/Sources/Orbit/Support/ButtonStyles/TileButtonStyle.swift
+++ b/Sources/Orbit/Support/ButtonStyles/TileButtonStyle.swift
@@ -16,7 +16,7 @@ public struct TileButtonStyle: ButtonStyle {
.tileBorder(style, isSelected: isSelected)
}
- @ViewBuilder func backgroundColor(isPressed: Bool) -> some View {
+ @ViewBuilder private func backgroundColor(isPressed: Bool) -> some View {
if isPressed {
resolvedActiveBackground
} else {
@@ -24,7 +24,7 @@ public struct TileButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedInactiveBackground: some View {
+ @ViewBuilder private var resolvedInactiveBackground: some View {
if let backgroundShape {
backgroundShape.inactiveView
} else {
@@ -32,7 +32,7 @@ public struct TileButtonStyle: ButtonStyle {
}
}
- @ViewBuilder var resolvedActiveBackground: some View {
+ @ViewBuilder private var resolvedActiveBackground: some View {
if let backgroundShape {
backgroundShape.activeView
} else {
diff --git a/Sources/Orbit/Support/Components/BarButton.swift b/Sources/Orbit/Support/Components/BarButton.swift
index 62da5f04317..f3cf4da328a 100644
--- a/Sources/Orbit/Support/Components/BarButton.swift
+++ b/Sources/Orbit/Support/Components/BarButton.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// An icon-based bar button for suitable for actions inside toolbar or navigation bar.
+/// Orbit support component that displays icon-based button suitable for actions in a toolbar or navigation bar.
public struct BarButton: View {
@Environment(\.iconSize) private var iconSize
@@ -29,11 +29,11 @@ public struct BarButton: View {
.buttonStyle(IconButtonStyle())
}
- var resolvedIconSize: CGFloat {
+ private var resolvedIconSize: CGFloat {
iconSize ?? Orbit.Icon.Size.large.value
}
- var horizontalEdges: Edge.Set {
+ private var horizontalEdges: Edge.Set {
switch alignment {
case .leading: return .trailing
case .trailing: return .leading
@@ -41,7 +41,7 @@ public struct BarButton: View {
}
}
- /// Creates Orbit BarButton component.
+ /// Creates Orbit ``BarButton`` component.
public init(
_ icon: Icon.Symbol,
alignment: HorizontalAlignment = .center,
@@ -54,7 +54,7 @@ public struct BarButton: View {
}
}
- /// Creates Orbit BarButton component with custom icon.
+ /// Creates Orbit ``BarButton`` component with custom icon.
public init(
alignment: HorizontalAlignment = .center,
action: @escaping () -> Void,
diff --git a/Sources/Orbit/Support/Components/IconButton.swift b/Sources/Orbit/Support/Components/IconButton.swift
index 230b3b6ef0a..0c233762223 100644
--- a/Sources/Orbit/Support/Components/IconButton.swift
+++ b/Sources/Orbit/Support/Components/IconButton.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// An icon-based button.
+/// Orbit support component that displays an icon-based button.
public struct IconButton: View {
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
@@ -27,7 +27,7 @@ public struct IconButton: View {
// MARK: - Icons
public extension IconButton {
- /// Creates Orbit IconButton component with custom icon.
+ /// Creates Orbit ``IconButton`` component with custom icon.
init(
action: @escaping () -> Void,
@ViewBuilder icon: () -> Icon
@@ -36,7 +36,7 @@ public extension IconButton {
self.icon = icon()
}
- /// Creates Orbit IconButton component.
+ /// Creates Orbit ``IconButton`` component.
init(
_ icon: Orbit.Icon.Symbol,
action: @escaping () -> Void
diff --git a/Sources/Orbit/Support/Components/ListItem.swift b/Sources/Orbit/Support/Components/ListItem.swift
index 63174972854..5876b98c04d 100644
--- a/Sources/Orbit/Support/Components/ListItem.swift
+++ b/Sources/Orbit/Support/Components/ListItem.swift
@@ -1,11 +1,17 @@
import SwiftUI
-/// One item in Orbit List component.
+/// Orbit component that displays one item in Orbit ``List``.
///
-/// - Related components
-/// - ``List``
+/// A ``ListItem`` consists of a label and icon.
///
-/// - [Orbit](https://orbit.kiwi/components/structure/list/)
+/// ```swift
+/// List {
+/// ListItem("Planes", icon: .airplane)
+/// ListItem("Trains")
+/// }
+/// ```
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/structure/list/)
public struct ListItem: View {
@Environment(\.sizeCategory) private var sizeCategory
@@ -33,7 +39,7 @@ public struct ListItem: View {
// MARK: - Inits
public extension ListItem {
- /// Creates Orbit ListItem component.
+ /// Creates Orbit ``ListItem`` component.
init(
_ text: String = "",
icon: Icon.Symbol? = .circleSmall,
@@ -47,7 +53,7 @@ public extension ListItem {
}
}
- /// Creates Orbit ListItem component.
+ /// Creates Orbit ``ListItem`` component with custom icon.
init(
_ text: String = "",
type: ListItemType = .primary,
@@ -61,6 +67,7 @@ public extension ListItem {
// MARK: - Types
+/// Orbit ``ListItem`` type.
public enum ListItemType {
case primary
diff --git a/Sources/Orbit/Support/Components/NavigationButton.swift b/Sources/Orbit/Support/Components/NavigationButton.swift
index 19b859c5fb1..a747da67d2e 100644
--- a/Sources/Orbit/Support/Components/NavigationButton.swift
+++ b/Sources/Orbit/Support/Components/NavigationButton.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// A special case of ``BarButton`` suitable for main navigation actions inside toolbar or navigation bar.
+/// Orbit support component that is a special case of ``BarButton``, suitable for main navigation actions inside toolbar or navigation bar.
public struct NavigationButton: View {
@Environment(\.isHapticsEnabled) private var isHapticsEnabled
@@ -21,6 +21,7 @@ public struct NavigationButton: View {
.buttonStyle(NavigationButtonStyle())
}
+ /// Creates Orbit ``NavigationButton`` component.
public init(_ state: State, action: @escaping () -> Void) {
self.state = state
self.action = action
@@ -30,6 +31,7 @@ public struct NavigationButton: View {
// MARK: - Types
extension NavigationButton {
+ /// Orbit ``NavigationButton`` state.
public enum State {
case back
case close
diff --git a/Sources/Orbit/Support/Components/PasswordStrengthIndicator.swift b/Sources/Orbit/Support/Components/PasswordStrengthIndicator.swift
index ff00b1fa8af..650862b0bfd 100644
--- a/Sources/Orbit/Support/Components/PasswordStrengthIndicator.swift
+++ b/Sources/Orbit/Support/Components/PasswordStrengthIndicator.swift
@@ -1,9 +1,9 @@
import SwiftUI
-/// Orbit password strength indicator.
+/// Orbit support component that displays password strength indicator.
public struct PasswordStrengthIndicator: View {
- let passwordStrength: PasswordStrength
+ private let passwordStrength: PasswordStrength
public var body: some View {
if text.isEmpty == false {
@@ -20,7 +20,7 @@ public struct PasswordStrengthIndicator: View {
}
}
- var indicator: some View {
+ private var indicator: some View {
Capsule()
.fill(.cloudNormal)
.overlay(bar)
@@ -28,7 +28,7 @@ public struct PasswordStrengthIndicator: View {
.frame(maxWidth: .infinity, alignment: .leading)
}
- var bar: some View {
+ private var bar: some View {
HStack(spacing: 0) {
Capsule()
.fill(color)
@@ -41,7 +41,7 @@ public struct PasswordStrengthIndicator: View {
}
}
- var text: String {
+ private var text: String {
switch passwordStrength {
case .weak(let title): return title
case .medium(let title): return title
@@ -49,7 +49,7 @@ public struct PasswordStrengthIndicator: View {
}
}
- var spacers: Int {
+ private var spacers: Int {
switch passwordStrength {
case .weak: return 3
case .medium: return 1
@@ -57,7 +57,7 @@ public struct PasswordStrengthIndicator: View {
}
}
- var color: Color {
+ private var color: Color {
switch passwordStrength {
case .weak: return .redNormal
case .medium: return .orangeNormal
@@ -65,6 +65,7 @@ public struct PasswordStrengthIndicator: View {
}
}
+ /// Creates Orbit ``PasswordStrengthIndicator`` component.
public init(passwordStrength: PasswordStrengthIndicator.PasswordStrength) {
self.passwordStrength = passwordStrength
}
@@ -73,6 +74,7 @@ public struct PasswordStrengthIndicator: View {
// MARK: - Types
public extension PasswordStrengthIndicator {
+ /// Orbit ``PasswordStrengthIndicator`` strength.
enum PasswordStrength: Equatable {
case weak(title: String)
case medium(title: String)
diff --git a/Sources/Orbit/Support/Components/Progress.swift b/Sources/Orbit/Support/Components/Progress.swift
index bc24ab14ba3..3e9543d8eac 100644
--- a/Sources/Orbit/Support/Components/Progress.swift
+++ b/Sources/Orbit/Support/Components/Progress.swift
@@ -1,5 +1,6 @@
import SwiftUI
+/// Orbit support component that displays progress.
public struct Progress: View {
public static let height: CGFloat = 5
@@ -20,6 +21,7 @@ public struct Progress: View {
)
}
+ /// Creates Orbit ``Progress`` component.
public init(_ progress: CGFloat) {
self.progress = progress
}
diff --git a/Sources/Orbit/Support/Components/SliderThumb.swift b/Sources/Orbit/Support/Components/SliderThumb.swift
index 8833f273fa0..bec41aa0602 100644
--- a/Sources/Orbit/Support/Components/SliderThumb.swift
+++ b/Sources/Orbit/Support/Components/SliderThumb.swift
@@ -7,7 +7,7 @@ struct SliderThumb: View {
public static let circleDiameter: CGFloat = 24
public static let dotDiameter: CGFloat = 8
- public var body: some View {
+ var body: some View {
Circle()
.frame(width: circleDiameter, height: circleDiameter)
.foregroundColor(.white)
diff --git a/Sources/Orbit/Support/Components/StepperButton.swift b/Sources/Orbit/Support/Components/StepperButton.swift
index 5a19539b482..29993f5670e 100644
--- a/Sources/Orbit/Support/Components/StepperButton.swift
+++ b/Sources/Orbit/Support/Components/StepperButton.swift
@@ -1,14 +1,14 @@
import SwiftUI
-/// An icon-based stepper button for suitable for actions inside components like `Stepper`.
+/// Orbit support component that displays icon-based stepper button for suitable for actions inside components like ``Stepper``.
public struct StepperButton: View {
- @Environment(\.isEnabled) var isEnabled
- @Environment(\.sizeCategory) var sizeCategory
+ @Environment(\.isEnabled) private var isEnabled
+ @Environment(\.sizeCategory) private var sizeCategory
- let icon: Icon.Symbol
- let style: Stepper.Style
- let action: () -> Void
+ private let icon: Icon.Symbol
+ private let style: Stepper.Style
+ private let action: () -> Void
public var body: some View {
SwiftUI.Button {
@@ -21,11 +21,11 @@ public struct StepperButton: View {
.buttonStyle(OrbitStyle(style: style))
}
- var color: Color {
+ private var color: Color {
isEnabled ? style.textActiveColor : style.textColor
}
- var size: CGFloat {
+ private var size: CGFloat {
.xxLarge * sizeCategory.controlRatio
}
}
@@ -33,7 +33,7 @@ public struct StepperButton: View {
// MARK: - Inits
extension StepperButton {
- /// Creates Orbit StepperButton component used in a Stepper.
+ /// Creates Orbit ``StepperButton`` component used in a ``Stepper``.
public init(
_ icon: Icon.Symbol,
style: Stepper.Style = .primary,
diff --git a/Sources/Orbit/Support/Components/TabStyle.swift b/Sources/Orbit/Support/Components/TabStyle.swift
index 108482ecd51..ca94b68b4f1 100644
--- a/Sources/Orbit/Support/Components/TabStyle.swift
+++ b/Sources/Orbit/Support/Components/TabStyle.swift
@@ -1,8 +1,8 @@
import SwiftUI
-/// Style applied to the active tab in ``Tabs``.
+/// Orbit ``Tabs`` style applied to the active tab.
///
-/// To apply a style, use the `.activeTabStyle` modifier.
+/// To apply a style, use the `activeTabStyle()` modifier.
public enum TabStyle: Equatable {
case `default`
case underlined(Color)
@@ -30,7 +30,7 @@ public enum TabStyle: Equatable {
public extension View {
- /// Applies the given style to the active tab in ``Tabs``.
+ /// Applies the given style to the active tab in Orbit ``Tabs``.
func activeTabStyle(_ style: TabStyle) -> some View {
modifier(ActiveTabStyleModifier(style: style))
}
diff --git a/Sources/Orbit/Support/Components/TileBorder.swift b/Sources/Orbit/Support/Components/TileBorder.swift
index 781e989d9e4..ab557dbf2f4 100644
--- a/Sources/Orbit/Support/Components/TileBorder.swift
+++ b/Sources/Orbit/Support/Components/TileBorder.swift
@@ -1,5 +1,6 @@
import SwiftUI
+/// Predefined Orbit border styles for ``Tile``-like components.
public enum TileBorderStyle {
case none
case `default`
@@ -9,16 +10,16 @@ public enum TileBorderStyle {
case plain
}
-/// Provides decoration with ``Tile`` appearance.
+/// Provides decoration using Orbit ``Tile`` appearance.
public struct TileBorderModifier: ViewModifier {
static let animation: Animation = .easeIn(duration: 0.15)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
- @Environment(\.status) var status
+ @Environment(\.status) private var status
- let style: TileBorderStyle
- let isSelected: Bool
+ private let style: TileBorderStyle
+ private let isSelected: Bool
public func body(content: Content) -> some View {
content
@@ -28,7 +29,7 @@ public struct TileBorderModifier: ViewModifier {
.overlay(border.animation(Self.animation, value: isSelected))
}
- @ViewBuilder var border: some View {
+ @ViewBuilder private var border: some View {
switch (style, horizontalSizeClass) {
case (.none, _):
EmptyView()
@@ -45,20 +46,20 @@ public struct TileBorderModifier: ViewModifier {
}
}
- @ViewBuilder var compactSeparatorBorder: some View {
+ @ViewBuilder private var compactSeparatorBorder: some View {
borderColor
.frame(height: status == nil ? 1 : BorderWidth.active)
}
- @ViewBuilder var clipShape: some InsettableShape {
+ @ViewBuilder private var clipShape: some InsettableShape {
RoundedRectangle(cornerRadius: cornerRadius)
}
- var isCompact: Bool {
+ private var isCompact: Bool {
(style == .iOS) && horizontalSizeClass == .compact
}
- var cornerRadius: CGFloat {
+ private var cornerRadius: CGFloat {
switch (style, horizontalSizeClass) {
case (.default, _): return BorderRadius.default
case (.plain, _): return BorderRadius.default
@@ -68,7 +69,7 @@ public struct TileBorderModifier: ViewModifier {
}
}
- var elevation: Elevation? {
+ private var elevation: Elevation? {
guard status == .none else {
return nil
}
@@ -81,13 +82,13 @@ public struct TileBorderModifier: ViewModifier {
}
}
- var borderWidth: CGFloat {
+ private var borderWidth: CGFloat {
isSelected || status != nil
? BorderWidth.active
: 1
}
- var borderColor: Color {
+ private var borderColor: Color {
if let status = status {
return status.color
}
@@ -99,17 +100,23 @@ public struct TileBorderModifier: ViewModifier {
return showOuterBorder ? .cloudNormal : .clear
}
- var showOuterBorder: Bool {
+ private var showOuterBorder: Bool {
switch style {
case .iOS, .plain: return true
case .none, .default: return false
}
}
+
+ /// Creates Orbit ``TileBorderModifier``.
+ public init(style: TileBorderStyle, isSelected: Bool) {
+ self.style = style
+ self.isSelected = isSelected
+ }
}
public extension View {
- /// Decorates content with a border similar to ``Tile`` or ``Card`` appearance using specified style.
+ /// Decorates content with Orbit border similar to ``Tile`` or ``Card`` appearance using specified style.
func tileBorder(
_ style: TileBorderStyle = .default,
isSelected: Bool = false
diff --git a/Sources/Orbit/Support/Components/TimelineItem.swift b/Sources/Orbit/Support/Components/TimelineItem.swift
index 00f6cd62966..8316a2edbeb 100644
--- a/Sources/Orbit/Support/Components/TimelineItem.swift
+++ b/Sources/Orbit/Support/Components/TimelineItem.swift
@@ -1,21 +1,28 @@
import SwiftUI
-/// One item of a Timeline.
+/// Orbit component that shows a single item in a ``Timeline``.
///
-/// - Related components
-/// - ``Timeline``
+/// A ``TimelineItem`` consists of a label, description and a type that determines its visual progress:
+///
+/// ```swift
+/// Timeline {
+/// TimelineItem("Booked", type: .past)
+/// TimelineItem("Checked in", type: .past)
+/// TimelineItem("Board", type: .present)
+/// }
+/// ```
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/progress-indicators/timeline/)
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/progress-indicators/timeline/)
public struct TimelineItem: View {
- @Environment(\.sizeCategory) var sizeCategory
- @Environment(\.horizontalSizeClass) var horizontalSizeClass
+ @Environment(\.sizeCategory) private var sizeCategory
+ @Environment(\.horizontalSizeClass) private var horizontalSizeClass
- let label: String
- let sublabel: String
- let description: String
- let type: TimelineItemType
- @ViewBuilder let footer: Footer
+ private let label: String
+ private let sublabel: String
+ private let description: String
+ private let type: TimelineItemType
+ @ViewBuilder private let footer: Footer
public var body: some View {
HStack(alignment: alignment, spacing: .small) {
@@ -36,7 +43,7 @@ public struct TimelineItem: View {
}
}
- @ViewBuilder var header: some View {
+ @ViewBuilder private var header: some View {
if horizontalSizeClass == .compact && sizeCategory.isAccessibilitySize {
VStack(alignment: .leading, spacing: .xSmall) {
headerContent
@@ -48,21 +55,21 @@ public struct TimelineItem: View {
}
}
- @ViewBuilder var headerContent: some View {
+ @ViewBuilder private var headerContent: some View {
Heading(label, style: .title5)
Text(sublabel)
.textSize(.small)
}
- var alignment: VerticalAlignment {
+ private var alignment: VerticalAlignment {
hasHeaderContent || hasDescription ? .firstTextBaseline : .top
}
- var hasHeaderContent: Bool {
+ private var hasHeaderContent: Bool {
label.isEmpty == false || sublabel.isEmpty == false
}
- var hasDescription: Bool {
+ private var hasDescription: Bool {
description.isEmpty == false
}
}
@@ -71,7 +78,7 @@ public struct TimelineItem: View {
public extension TimelineItem {
- /// Creates Orbit TimelineItem component with text details and optional custom content at the bottom.
+ /// Creates Orbit ``TimelineItem`` component.
init(
_ label: String = "",
sublabel: String = "",
@@ -79,7 +86,6 @@ public extension TimelineItem {
description: String = "",
@ViewBuilder footer: () -> Footer = { EmptyView() }
) {
-
self.label = label
self.sublabel = sublabel
self.type = type
@@ -90,8 +96,10 @@ public extension TimelineItem {
// MARK: - Types
+/// Orbit ``TimelineItem`` type.
public enum TimelineItemType: Equatable {
+ /// Orbit ``TimelineItemType`` status.
public enum Status {
case success
case warning
@@ -102,6 +110,8 @@ public enum TimelineItemType: Equatable {
case present(Status? = nil)
case future
+ public static var present: Self { present() }
+
public var icon: Icon.Symbol? {
switch self {
case .past: return .checkCircle
diff --git a/Sources/Orbit/Support/Environment Keys/BackgroundShapeKey.swift b/Sources/Orbit/Support/Environment Keys/BackgroundShapeKey.swift
index c4359f120f6..e1273a8761c 100644
--- a/Sources/Orbit/Support/Environment Keys/BackgroundShapeKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/BackgroundShapeKey.swift
@@ -44,18 +44,18 @@ public extension View {
/// Set the inactive and active background shape styles for supported Orbit components within the view hierarchy.
///
- /// To restore the default background style, set the `backgroundShape` environment value to nil using the environment(_:_:) modifer.
+ /// To restore the default background style, set the `backgroundShape` environment value to nil using the `environment(_:_:)` modifer.
///
/// - Parameters:
/// - shape: A `Color` or a `LinearGradient` that will be used in supported Orbit components such as `Card` or `Badge` as a background style.
- /// - shape: A `Color` or a `LinearGradient` that will be used in supported touchable Orbit components such as `Tile` as inactive and active background style.
+ /// - active: A `Color` or a `LinearGradient` that will be used in supported touchable Orbit components such as `Tile` as active background style.
func backgroundStyle(_ shape: any ShapeStyle, active: any ShapeStyle) -> some View {
environment(\.backgroundShape, .init(inactive: shape, active: active))
}
/// Set the background shape style for supported Orbit components within the view hierarchy.
///
- /// To restore the default background style, set the `backgroundShape` environment value to nil using the environment(_:_:) modifer.
+ /// To restore the default background style, set the `backgroundShape` environment value to nil using the `environment(_:_:)` modifer.
///
/// - Parameters:
/// - shape: A `Color` or a `LinearGradient` that will be used in supported Orbit components such as `Card` or `Badge` as a background style.
diff --git a/Sources/Orbit/Support/Environment Keys/ButtonSizeKey.swift b/Sources/Orbit/Support/Environment Keys/ButtonSizeKey.swift
index 6eb3ebfc62d..54ca4dd8b6c 100644
--- a/Sources/Orbit/Support/Environment Keys/ButtonSizeKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/ButtonSizeKey.swift
@@ -12,7 +12,7 @@ struct ButtonSizeKey: EnvironmentKey {
public extension EnvironmentValues {
- /// An Orbit `ButtonSize` value stored in a view’s environment.
+ /// An Orbit ``ButtonSize`` value stored in a view’s environment.
var buttonSize: ButtonSize? {
get { self[ButtonSizeKey.self] }
set { self[ButtonSizeKey.self] = newValue }
@@ -21,7 +21,7 @@ public extension EnvironmentValues {
public extension View {
- /// Set the button size for this view.
+ /// Set the Orbit ``ButtonSize`` for this view.
///
/// - Parameters:
/// - size: A button size that will be used by all components in the view hierarchy.
diff --git a/Sources/Orbit/Support/Environment Keys/HapticsEnabledKey.swift b/Sources/Orbit/Support/Environment Keys/HapticsEnabledKey.swift
index 23e28a1e850..21f8cf5e067 100644
--- a/Sources/Orbit/Support/Environment Keys/HapticsEnabledKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/HapticsEnabledKey.swift
@@ -6,7 +6,7 @@ struct HapticsEnabledKey: EnvironmentKey {
public extension EnvironmentValues {
- /// Whether haptic feedback on controls is enabled.
+ /// Whether Orbit haptic feedback on controls is enabled.
var isHapticsEnabled: Bool {
get { self[HapticsEnabledKey.self] }
set { self[HapticsEnabledKey.self] = newValue }
@@ -15,7 +15,7 @@ public extension EnvironmentValues {
public extension View {
- /// Disables haptic feedback on controls.
+ /// Disables Orbit haptic feedback on controls.
func hapticsDisabled(_ disabled: Bool = true) -> some View {
environment(\.isHapticsEnabled, disabled == false)
}
diff --git a/Sources/Orbit/Support/Environment Keys/IconColorKey.swift b/Sources/Orbit/Support/Environment Keys/IconColorKey.swift
index a328617ebc0..cc4e78385fb 100644
--- a/Sources/Orbit/Support/Environment Keys/IconColorKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IconColorKey.swift
@@ -6,7 +6,7 @@ struct IconColorKey: EnvironmentKey {
public extension EnvironmentValues {
- /// An icon color stored in a view’s environment, used for Orbit Icon component.
+ /// An icon color stored in a view’s environment, used for Orbit ``Icon`` component.
///
/// This environment value serves as a replacement for non-public `foregroundColor` environment value.
/// This value has a priority over a `textColor`.
@@ -18,7 +18,7 @@ public extension EnvironmentValues {
public extension View {
- /// Set the color for any Orbit `Icon` component within the view hierarchy.
+ /// Set the color for any Orbit ``Icon`` component within the view hierarchy.
///
/// The `iconColor` value has a priority over the `textColor` environment value.
///
diff --git a/Sources/Orbit/Support/Environment Keys/IconSizeKey.swift b/Sources/Orbit/Support/Environment Keys/IconSizeKey.swift
index 6daf2707eb5..70f37b6d7a4 100644
--- a/Sources/Orbit/Support/Environment Keys/IconSizeKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IconSizeKey.swift
@@ -6,7 +6,7 @@ struct IconSizeKey: EnvironmentKey {
public extension EnvironmentValues {
- /// An icon size stored in a view’s environment, used for Orbit Icon component.
+ /// An icon size stored in a view’s environment, used for Orbit ``Icon`` component.
///
/// This value has a priority over a `textSize`.
var iconSize: CGFloat? {
@@ -17,36 +17,36 @@ public extension EnvironmentValues {
public extension View {
- /// Set the size for any Orbit `Icon` component within the view hierarchy.
+ /// Set the size for any Orbit ``Icon`` component within the view hierarchy.
///
/// The `iconSize` value has a priority over the `textSize` environment value that can be used to size Icon to match the text size.
///
/// - Parameters:
- /// - size: A size that will be used in Orbit `Icon` components.
+ /// - size: A size that will be used in Orbit ``Icon`` components.
/// Pass `nil` to ignore environment icon size and to allow the system or the container to provide its own size.
/// If a container-specific override doesn’t exist, the `textSize` or default `.normal` size will be used.
func iconSize(_ size: Icon.Size?) -> some View {
environment(\.iconSize, size?.value)
}
- /// Set the size for any Orbit `Icon` component within the view hierarchy.
+ /// Set the size for any Orbit ``Icon`` component within the view hierarchy.
///
/// The `iconSize` value has a priority over the `textSize` environment value that can be used to size Icon to match the text size.
///
/// - Parameters:
- /// - size: A size that will be used in Orbit `Icon` components.
+ /// - size: A size that will be used in Orbit ``Icon`` components.
/// Pass `nil` to ignore environment icon size and to allow the system or the container to provide its own size.
/// If a container-specific override doesn’t exist, the `textSize` or default `.normal` size will be used.
func iconSize(custom size: CGFloat?) -> some View {
environment(\.iconSize, size)
}
- /// Set the size, matching line height of a provided text size, for any Orbit `Icon` component within the view hierarchy.
+ /// Set the size, matching line height of a provided text size, for any Orbit ``Icon`` component within the view hierarchy.
///
/// The `iconSize` value has a priority over the `textSize` environment value that can be used to size Icon to match the text size.
///
/// - Parameters:
- /// - size: A size that will be used in Orbit `Icon` components.
+ /// - size: A size that will be used in Orbit ``Icon`` components.
/// Pass `nil` to ignore environment icon size and to allow the system or the container to provide its own size.
/// If a container-specific override doesn’t exist, the `textSize` or default `.normal` size will be used.
func iconSize(textSize: Text.Size?) -> some View {
diff --git a/Sources/Orbit/Support/Environment Keys/IdealSizeKey.swift b/Sources/Orbit/Support/Environment Keys/IdealSizeKey.swift
index eee4e2f81d1..8d7dbedf316 100644
--- a/Sources/Orbit/Support/Environment Keys/IdealSizeKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IdealSizeKey.swift
@@ -1,5 +1,6 @@
import SwiftUI
+/// The expanding behaviour of compatible Orbit components in a view relative to their ideal size for each axis.
public struct IdealSizeValue {
public var horizontal: Bool?
public var vertical: Bool?
@@ -11,6 +12,7 @@ struct IdealSizeKey: EnvironmentKey {
public extension EnvironmentValues {
+ /// The expanding behaviour of compatible Orbit components in a view relative to their ideal size.
var idealSize: IdealSizeValue {
get { self[IdealSizeKey.self] }
set { self[IdealSizeKey.self] = newValue }
@@ -19,18 +21,21 @@ public extension EnvironmentValues {
public extension View {
- /// Sets expanding behaviour of view relative to its ideal size in specified direction.
- /// For specified axis, a value of `true` will prevent view from expending beyond its ideal size,
- /// while a value of `false` will force view to expand to infinity.
+ /// Sets the expanding behaviour of compatible Orbit components in a view relative to their ideal size in specified direction.
+ ///
+ /// For specified axis, a value of `true` will prevent component from expending beyond its ideal size,
+ /// while a value of `false` will force component to expand to infinity. A value of `nil` keeps the default behaviour.
///
- /// To fix the view exactly to the ideal size, use `fixedSize` modifier instead.
+ /// - Note: To fix the view exactly to the ideal size, use `fixedSize` modifier instead.
func idealSize(horizontal: Bool? = nil, vertical: Bool? = nil) -> some View {
environment(\.idealSize, .init(horizontal: horizontal, vertical: vertical))
}
- /// Prevents view from additionally expanding beyond its ideal size in both axis.
+ /// Prevents compatible Orbit components in a view from additionally expanding beyond its ideal size in both axis.
///
- /// To fix the view exactly to the ideal size, use `fixedSize` modifier instead.
+ /// To control separate axis and behaviour, use ``idealSize(horizontal:vertical:)`` modifier.
+ ///
+ /// - Note: To fix the view exactly to the ideal size, use `fixedSize` modifier instead.
func idealSize() -> some View {
idealSize(horizontal: true, vertical: true)
}
diff --git a/Sources/Orbit/Support/Environment Keys/IsExpandedKey.swift b/Sources/Orbit/Support/Environment Keys/IsExpandedKey.swift
index ee73b978445..88c6cd14897 100644
--- a/Sources/Orbit/Support/Environment Keys/IsExpandedKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IsExpandedKey.swift
@@ -6,7 +6,7 @@ struct IsExpandedKey: EnvironmentKey {
public extension EnvironmentValues {
- /// Indicates whether the view should be animated as a result of being expanded or collapsed.
+ /// Indicates whether the Orbit view should be animated as a result of being expanded or collapsed.
///
/// Required for proper animations when view is added or removed using transition.
var isExpanded: Bool {
diff --git a/Sources/Orbit/Support/Environment Keys/IsFadeInEnabledKey.swift b/Sources/Orbit/Support/Environment Keys/IsFadeInEnabledKey.swift
index 50e4aaf4256..715604e0981 100644
--- a/Sources/Orbit/Support/Environment Keys/IsFadeInEnabledKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IsFadeInEnabledKey.swift
@@ -6,7 +6,7 @@ struct IsFadeInEnabledKey: EnvironmentKey {
public extension EnvironmentValues {
- /// Indicates whether a fade-in animation is enabled.
+ /// Indicates whether a fade-in animation is enabled in Orbit views.
var isFadeInEnabled: Bool {
get { self[IsFadeInEnabledKey.self] }
set { self[IsFadeInEnabledKey.self] = newValue }
diff --git a/Sources/Orbit/Support/Environment Keys/IsTileSeparatorVisibleKey.swift b/Sources/Orbit/Support/Environment Keys/IsTileSeparatorVisibleKey.swift
index 8c3bc019086..0aa88f8d1b3 100644
--- a/Sources/Orbit/Support/Environment Keys/IsTileSeparatorVisibleKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/IsTileSeparatorVisibleKey.swift
@@ -6,7 +6,7 @@ struct IsTileSeparatorVisibleKey: EnvironmentKey {
public extension EnvironmentValues {
- /// Indicates whether a ``Tile``'s separator should be visible.
+ /// Indicates whether an Orbit ``Tile``'s separator should be visible.
var isTileSeparatorVisible: Bool {
get { self[IsTileSeparatorVisibleKey.self] }
set { self[IsTileSeparatorVisibleKey.self] = newValue }
diff --git a/Sources/Orbit/Support/Environment Keys/ScreenLayoutPaddingKey.swift b/Sources/Orbit/Support/Environment Keys/ScreenLayoutPaddingKey.swift
index 324625344b9..f59d4ee41dd 100644
--- a/Sources/Orbit/Support/Environment Keys/ScreenLayoutPaddingKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/ScreenLayoutPaddingKey.swift
@@ -6,7 +6,7 @@ struct ScreenLayoutPaddingKey: EnvironmentKey {
public extension EnvironmentValues {
- /// Indicates whether the content is inside the `screenLayout` context
+ /// Indicates whether the content is inside the Orbit `screenLayout` context
/// and specifies its padding in case it is.
var screenLayoutPadding: ScreenLayoutPadding? {
get { self[ScreenLayoutPaddingKey.self] }
diff --git a/Sources/Orbit/Support/Environment Keys/StatusKey.swift b/Sources/Orbit/Support/Environment Keys/StatusKey.swift
index c6ef758ef6c..be576e41846 100644
--- a/Sources/Orbit/Support/Environment Keys/StatusKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/StatusKey.swift
@@ -6,7 +6,7 @@ struct StatusKey: EnvironmentKey {
public extension EnvironmentValues {
- /// An Orbit `Status` stored in a view’s environment.
+ /// An Orbit ``Status`` stored in a view’s environment.
var status: Status? {
get { self[StatusKey.self] }
set { self[StatusKey.self] = newValue }
@@ -15,10 +15,10 @@ public extension EnvironmentValues {
public extension View {
- /// Set the `Status` for this view.
+ /// Set the Orbit ``Status`` for this view.
///
/// - Parameters:
- /// - status: A status that will be used by all components in the view hierarchy.
+ /// - status: A status that will be used by components in the view hierarchy.
func status(_ status: Status?) -> some View {
environment(\.status, status)
}
diff --git a/Sources/Orbit/Support/Environment Keys/TextAccentColorKey.swift b/Sources/Orbit/Support/Environment Keys/TextAccentColorKey.swift
index 0b7b37c4a94..202cf1816f8 100644
--- a/Sources/Orbit/Support/Environment Keys/TextAccentColorKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextAccentColorKey.swift
@@ -6,7 +6,7 @@ struct TextAccentColorKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A text accent color stored in a view’s environment.
+ /// An Orbit ``Text`` accent color stored in a view’s environment.
///
/// - Important: The environment value is different from the native deprecated internal `accentColor` value.
var textAccentColor: Color? {
@@ -17,7 +17,7 @@ public extension EnvironmentValues {
public extension View {
- /// Set the text accent color for any Orbit formatted text in this view.
+ /// Set the accent color for any Orbit formatted text in this view.
///
/// - Parameters:
/// - color: A color that will be used in `[` tags in texts within the view hierarchy.
diff --git a/Sources/Orbit/Support/Environment Keys/TextColorKey.swift b/Sources/Orbit/Support/Environment Keys/TextColorKey.swift
index 38bcaa6fe14..6ab1afd8405 100644
--- a/Sources/Orbit/Support/Environment Keys/TextColorKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextColorKey.swift
@@ -6,7 +6,7 @@ struct TextColorKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A text color stored in a view’s environment, used for Orbit text based components, such as `Text`, `Heading` or `Icon`.
+ /// A text color stored in a view’s environment, used for Orbit text based components, such as ``Text``, ``Heading`` or ``Icon``.
///
/// This environment value serves as a replacement for non-public `foregroundColor` environment value.
var textColor: Color? {
@@ -20,7 +20,7 @@ public extension View {
/// Set the text color for any text based Orbit component within the view hierarchy.
///
/// - Parameters:
- /// - color: A color that will be used in text based Orbit components such as `Text`, `Heading` or `Icon`.
+ /// - color: A color that will be used in text based Orbit components such as ``Text``, ``Heading`` or ``Icon``.
/// Pass `nil` to ignore environment text color and to allow the system or the container to provide its own color. If a container-specific override doesn’t exist, the `inkDark` color will be used.
func textColor(_ color: Color?) -> some View {
environment(\.textColor, color)
diff --git a/Sources/Orbit/Support/Environment Keys/TextIsCopyableKey.swift b/Sources/Orbit/Support/Environment Keys/TextIsCopyableKey.swift
index 2b27078af95..141d2e7ee46 100644
--- a/Sources/Orbit/Support/Environment Keys/TextIsCopyableKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextIsCopyableKey.swift
@@ -6,7 +6,7 @@ struct TextIsCopyableKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A text copyable status stored in a view’s environment, used for Orbit text components, such as `Text` or `Heading`.
+ /// A text copyable status stored in a view’s environment, used for Orbit text components, such as ``Text`` or ``Heading``.
var textIsCopyable: Bool {
get { self[TextIsCopyableKey.self] }
set { self[TextIsCopyableKey.self] = newValue }
@@ -15,11 +15,11 @@ public extension EnvironmentValues {
public extension View {
- /// Set the copyable status for any text based Orbit component within the view hierarchy.
+ /// Set the copyable status for any Orbit text based component within the view hierarchy.
///
/// - Parameters:
/// - enabled: A value that will be used to decide whether text based Orbit components
- /// such as `Text` or `Heading` can be copied using long tap gesture.
+ /// such as ``Text`` or ``Heading`` can be copied using long tap gesture.
func textIsCopyable(_ enabled: Bool = true) -> some View {
environment(\.textIsCopyable, enabled)
}
diff --git a/Sources/Orbit/Support/Environment Keys/TextLineHeightKey.swift b/Sources/Orbit/Support/Environment Keys/TextLineHeightKey.swift
index 796e2ce8686..5d6faa26c23 100644
--- a/Sources/Orbit/Support/Environment Keys/TextLineHeightKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextLineHeightKey.swift
@@ -6,7 +6,7 @@ struct TextLineHeightKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A text line height stored in a view’s environment, used for Orbit text based components, such as `Text` or `Heading`.
+ /// A text line height stored in a view’s environment, used for Orbit text based components, such as ``Text`` or ``Heading``.
///
/// This environment value serves as a replacement for native line height.
var textLineHeight: CGFloat? {
@@ -20,7 +20,7 @@ public extension View {
/// Set the custom line height for any text based Orbit component within the view hierarchy.
///
/// - Parameters:
- /// - height: An overall height that will be used in text based Orbit components such as `Text` or `Heading`.
+ /// - height: An overall height that will be used in text based Orbit components such as ``Text`` or ``Heading``.
/// Pass `nil` to ignore environment text size and to allow the system or the container to provide its own height.
/// If a container-specific override doesn’t exist, the line height will be calculated from text size.
func textLineHeight(_ height: CGFloat?) -> some View {
diff --git a/Sources/Orbit/Support/Environment Keys/TextLinkActionKey.swift b/Sources/Orbit/Support/Environment Keys/TextLinkActionKey.swift
index c9136845aa2..7bc6c27f9a2 100644
--- a/Sources/Orbit/Support/Environment Keys/TextLinkActionKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextLinkActionKey.swift
@@ -6,7 +6,7 @@ struct TextLinkActionKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A `TextLink` action stored in a view’s environment.
+ /// Orbit `TextLink` ``TextLink/Action`` stored in a view’s environment.
var textLinkAction: TextLink.Action? {
get { self[TextLinkActionKey.self] }
set { self[TextLinkActionKey.self] = newValue }
@@ -15,10 +15,10 @@ public extension EnvironmentValues {
public extension View {
- /// Set the `TextLink` action for this view.
+ /// Set the `TextLink` ``TextLink/Action`` for text links found in this view.
///
/// - Parameters:
- /// - action: A handler that is executed when the user taps on any `TextLink` inside the view hierarchy.
+ /// - action: A handler that is executed when the user taps on any ``TextLink`` inside the view hierarchy.
func textLinkAction(_ action: @escaping TextLink.Action) -> some View {
environment(\.textLinkAction, action)
}
diff --git a/Sources/Orbit/Support/Environment Keys/TextLinkColorKey.swift b/Sources/Orbit/Support/Environment Keys/TextLinkColorKey.swift
index 5c8030ea34f..6037974d066 100644
--- a/Sources/Orbit/Support/Environment Keys/TextLinkColorKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextLinkColorKey.swift
@@ -6,7 +6,7 @@ struct TextLinkColorKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A `TextLink` color stored in a view’s environment.
+ /// Orbit `TextLink` ``TextLink/Color`` color stored in a view’s environment.
var textLinkColor: TextLink.Color? {
get { self[TextLinkColorKey.self] }
set { self[TextLinkColorKey.self] = newValue }
@@ -15,10 +15,10 @@ public extension EnvironmentValues {
public extension View {
- /// Override the default `TextLink` color for this view.
+ /// Override the default Orbit `TextLink` ``TextLink/Color` for this view.
///
/// - Parameters:
- /// - color: A color that will be used by all `TextLink`s inside the view hierarchy.
+ /// - color: A color that will be used by all ``TextLink``s inside the view hierarchy.
func textLinkColor(_ color: TextLink.Color?) -> some View {
environment(\.textLinkColor, color)
}
diff --git a/Sources/Orbit/Support/Environment Keys/TextSizeKey.swift b/Sources/Orbit/Support/Environment Keys/TextSizeKey.swift
index 39de070708f..69ad3ccd35e 100644
--- a/Sources/Orbit/Support/Environment Keys/TextSizeKey.swift
+++ b/Sources/Orbit/Support/Environment Keys/TextSizeKey.swift
@@ -6,7 +6,7 @@ struct TextSizeKey: EnvironmentKey {
public extension EnvironmentValues {
- /// A text size stored in a view’s environment, used for Orbit text based components, such as `Text`, `Heading` or `Icon`.
+ /// A text size stored in a view’s environment, used for Orbit text based components, such as ``Text``, ``Heading`` or ``Icon``.
///
/// This environment value serves as a replacement for non-public `font` environment value.
var textSize: CGFloat? {
@@ -20,7 +20,7 @@ public extension View {
/// Set the text size for any text based Orbit component within the view hierarchy.
///
/// - Parameters:
- /// - size: A size that will be used in text based Orbit components such as `Text` or `Icon`.
+ /// - size: A size that will be used in text based Orbit components such as ``Text`` or ``Icon``.
/// Pass `nil` to ignore environment text size and to allow the system or the container to provide its own size.
/// If a container-specific override doesn’t exist, the `.normal` size will be used.
func textSize(_ size: Text.Size?) -> some View {
@@ -31,7 +31,7 @@ public extension View {
/// Set the custom text size for any text based Orbit component within the view hierarchy.
///
/// - Parameters:
- /// - size: A size that will be used in text based Orbit components such as `Text` or `Icon`.
+ /// - size: A size that will be used in text based Orbit components such as ``Text`` or ``Icon``.
/// Pass `nil` to ignore environment text size and to allow the system or the container to provide its own size.
/// If a container-specific override doesn’t exist, the `.normal` size will be used.
func textSize(custom size: CGFloat?) -> some View {
diff --git a/Sources/Orbit/Support/Forms/FieldLabel.swift b/Sources/Orbit/Support/Forms/FieldLabel.swift
index 69b7f16bf9f..edfb5e89cd8 100644
--- a/Sources/Orbit/Support/Forms/FieldLabel.swift
+++ b/Sources/Orbit/Support/Forms/FieldLabel.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Orbit label positioned above a form field.
+/// Orbit support component that displays label positioned above a form field.
public struct FieldLabel: View {
private let label: String
@@ -10,7 +10,7 @@ public struct FieldLabel: View {
.fontWeight(.medium)
}
- /// Create Orbit form field label.
+ /// Creates Orbit ``FieldLabel``.
public init(_ label: String) {
self.label = label
}
diff --git a/Sources/Orbit/Support/Forms/FieldMessage.swift b/Sources/Orbit/Support/Forms/FieldMessage.swift
index fafd8571ae1..209c2d26447 100644
--- a/Sources/Orbit/Support/Forms/FieldMessage.swift
+++ b/Sources/Orbit/Support/Forms/FieldMessage.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Orbit message below form fields.
+/// Orbit support component that displays message below form fields.
public struct FieldMessage: View {
@Environment(\.sizeCategory) private var sizeCategory
@@ -28,6 +28,7 @@ public struct FieldMessage: View {
}
}
+ /// Creates Orbit ``FieldMessage``.
public init(_ message: Message?, spacing: CGFloat = .xxSmall) {
self.message = message
self.spacing = spacing
diff --git a/Sources/Orbit/Support/Forms/FieldWrapper.swift b/Sources/Orbit/Support/Forms/FieldWrapper.swift
index d21e49d8a94..e9bfedfd603 100644
--- a/Sources/Orbit/Support/Forms/FieldWrapper.swift
+++ b/Sources/Orbit/Support/Forms/FieldWrapper.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Orbit wrapper around form fields. Provides optional label and message.
+/// Orbit support component that orovides label and message around input field.
public struct FieldWrapper: View {
@Binding private var messageHeight: CGFloat
@@ -35,9 +35,9 @@ public struct FieldWrapper: View {
// MARK: - Inits
public extension FieldWrapper {
- /// Creates Orbit wrapper around form field content with a custom label and an additional message content.
+ /// Creates Orbit ``FieldWrapper`` around form field content with a custom label and an additional message content.
///
- /// `FieldLabel` is a default component for constructing custom label.
+ /// ``FieldLabel`` is a default component for constructing custom label.
init(
message: Message? = nil,
messageHeight: Binding = .constant(0),
@@ -55,7 +55,7 @@ public extension FieldWrapper {
public extension FieldWrapper where Label == FieldLabel {
- /// Creates Orbit wrapper around form field content with an additional message content.
+ /// Creates Orbit ``FieldWrapper`` around form field content with an additional message content.
init(
_ label: String,
message: Message? = nil,
diff --git a/Sources/Orbit/Support/Forms/InputContent.swift b/Sources/Orbit/Support/Forms/InputContent.swift
index 2fc974bc39f..4cbed3c89ff 100644
--- a/Sources/Orbit/Support/Forms/InputContent.swift
+++ b/Sources/Orbit/Support/Forms/InputContent.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Content for Orbit inputs that share common layout with a prefix and suffix.
+/// Orbit support component representing input components that share common layout with a prefix and suffix.
public struct InputContent: View {
@Environment(\.iconColor) private var iconColor
@@ -124,7 +124,7 @@ public struct InputContent: View {
}
}
- /// Create content for Orbit inputs that share common layout with a prefix and suffix.
+ /// Create Orbit ``InputContent``.
public init(
state: InputState = .default,
label: String = "",
diff --git a/Sources/Orbit/Support/Forms/InputState.swift b/Sources/Orbit/Support/Forms/InputState.swift
index 0406a8d7314..d05150e86ad 100644
--- a/Sources/Orbit/Support/Forms/InputState.swift
+++ b/Sources/Orbit/Support/Forms/InputState.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// State of Orbit input.
+/// State of Orbit input components.
public enum InputState {
case `default`
diff --git a/Sources/Orbit/Support/Forms/KeyValueField.swift b/Sources/Orbit/Support/Forms/KeyValueField.swift
index 1ae0a562a8a..7b841211e24 100644
--- a/Sources/Orbit/Support/Forms/KeyValueField.swift
+++ b/Sources/Orbit/Support/Forms/KeyValueField.swift
@@ -1,15 +1,27 @@
import SwiftUI
-/// A `KeyValue` container with generic content.
+/// Orbit support component that displays a pair of label and a content.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/keyvalue/)
+/// A ``KeyValueField`` consists of a label and a content.
+///
+/// ```swift
+/// KeyValueField("First Name") {
+/// Text("Pavel")
+/// }
+/// ```
+///
+/// ### Layout
+///
+/// The text alignment can be modified by ``multilineTextAlignment(_:)``.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/keyvalue/)
public struct KeyValueField: View {
@Environment(\.multilineTextAlignment) private var multilineTextAlignment
- let key: String
- let size: KeyValue.Size
- @ViewBuilder let content: Content
+ private let key: String
+ private let size: KeyValue.Size
+ @ViewBuilder private let content: Content
public var body: some View {
VStack(alignment: .init(multilineTextAlignment), spacing: 0) {
@@ -25,10 +37,10 @@ public struct KeyValueField: View {
}
// MARK: - Inits
-extension KeyValueField {
+public extension KeyValueField {
- /// Creates Orbit KeyValue component.
- public init(
+ /// Creates Orbit ``KeyValueField`` support component.
+ init(
_ key: String = "",
size: KeyValue.Size = .normal,
@ViewBuilder content: () -> Content
@@ -63,6 +75,7 @@ struct KeyValueFieldPreviews: PreviewProvider {
KeyValueField("Multiline and very long key") {
Text("Multiline and very long value")
}
+ .multilineTextAlignment(.trailing)
.frame(width: 100)
.multilineTextAlignment(.trailing)
}
diff --git a/Sources/Orbit/Support/Forms/Message.swift b/Sources/Orbit/Support/Forms/Message.swift
index 3fa86c45afc..1bc7022a3a3 100644
--- a/Sources/Orbit/Support/Forms/Message.swift
+++ b/Sources/Orbit/Support/Forms/Message.swift
@@ -1,5 +1,6 @@
import SwiftUI
+/// Orbit informational message used in forms.
public enum Message: Equatable, Hashable, CustomStringConvertible {
case normal(String, icon: Icon.Symbol? = nil)
diff --git a/Sources/Orbit/Support/HapticsProvider.swift b/Sources/Orbit/Support/HapticsProvider.swift
index 3c6e5dede38..af7fe9253c2 100644
--- a/Sources/Orbit/Support/HapticsProvider.swift
+++ b/Sources/Orbit/Support/HapticsProvider.swift
@@ -1,5 +1,9 @@
import UIKit
+import SwiftUI
+/// Orbit haptics feedback provider.
+///
+/// Can be disabled by ``SwiftUI/View/hapticsDisabled(_:)``.
public enum HapticsProvider {
public enum HapticFeedbackType {
diff --git a/Sources/Orbit/Support/Layout/ContentHeightReader.swift b/Sources/Orbit/Support/Layout/ContentHeightReader.swift
index d6dc5305974..ff1ff6313cf 100644
--- a/Sources/Orbit/Support/Layout/ContentHeightReader.swift
+++ b/Sources/Orbit/Support/Layout/ContentHeightReader.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Invisible wrapper that communicates its current content height.
+/// Invisible Orbit wrapper that communicates its current content height.
public struct ContentHeightReader: View {
@Binding var height: CGFloat
diff --git a/Sources/Orbit/Support/Layout/HorizontalScrollReader.swift b/Sources/Orbit/Support/Layout/HorizontalScrollReader.swift
index 2d3f2022253..8ae36a1b986 100644
--- a/Sources/Orbit/Support/Layout/HorizontalScrollReader.swift
+++ b/Sources/Orbit/Support/Layout/HorizontalScrollReader.swift
@@ -1,5 +1,6 @@
import SwiftUI
+/// A proxy for Orbit ``HorizontalScrollReader``.
@available(iOS 14, *)
public class HorizontalScrollViewProxy: ObservableObject {
@@ -10,14 +11,13 @@ public class HorizontalScrollViewProxy: ObservableObject {
}
}
-/// A view that provides programmatic scrolling of `HorizontalScroll` component,
-/// by working with a proxy to scroll to child views marked by `identifier()`.
+/// Orbit component that provides programmatic scrolling of ``HorizontalScroll`` component,
+/// by working with a ``HorizontalScrollViewProxy`` to scroll to child views marked by Orbit `identifier()` modifier.
@available(iOS 14, *)
public struct HorizontalScrollReader: View {
- @ViewBuilder let content: (HorizontalScrollViewProxy) -> Content
-
@StateObject private var proxy = HorizontalScrollViewProxy()
+ @ViewBuilder private let content: (HorizontalScrollViewProxy) -> Content
public var body: some View {
content(proxy)
@@ -28,6 +28,7 @@ public struct HorizontalScrollReader: View {
.environment(\.scrollTarget, proxy.scrollTarget)
}
+ /// Creates Orbit ``HorizontalScrollReader`` component.
public init(@ViewBuilder content: @escaping (HorizontalScrollViewProxy) -> Content) {
self.content = content
}
diff --git a/Sources/Orbit/Support/Layout/IgnoreScreenLayoutHorizontalPaddingModifier.swift b/Sources/Orbit/Support/Layout/IgnoreScreenLayoutHorizontalPaddingModifier.swift
index 4033a3a9893..f7a8ebf76eb 100644
--- a/Sources/Orbit/Support/Layout/IgnoreScreenLayoutHorizontalPaddingModifier.swift
+++ b/Sources/Orbit/Support/Layout/IgnoreScreenLayoutHorizontalPaddingModifier.swift
@@ -22,9 +22,9 @@ struct IgnoreScreenLayoutHorizontalPaddingModifier: ViewModifier {
public extension View {
- /// Reverts any horizontal padding provided by `screenLayout` context. Can be optionally limited to a specific horizontal size class.
+ /// Reverts any horizontal padding provided by Orbit `screenLayout` context. Can be optionally limited to a specific horizontal size class.
///
- /// A typical usage is to mimic the edge-to-edge appearance of the `Card` component.
+ /// A typical usage is to mimic the edge-to-edge appearance of the ``Card`` component.
func ignoreScreenLayoutHorizontalPadding(limitToSizeClass sizeClass: UserInterfaceSizeClass? = nil) -> some View {
modifier(IgnoreScreenLayoutHorizontalPaddingModifier(limitToSizeClass: sizeClass))
}
diff --git a/Sources/Orbit/Support/Layout/Layout.swift b/Sources/Orbit/Support/Layout/Layout.swift
index c8799b982f0..d8c343d950d 100644
--- a/Sources/Orbit/Support/Layout/Layout.swift
+++ b/Sources/Orbit/Support/Layout/Layout.swift
@@ -2,7 +2,7 @@ import SwiftUI
public enum Layout {
- /// Maximum readable width used for layout in regular width environment.
+ /// Maximum readable width used for Orbit layout in regular width environment.
public static var readableMaxWidth: CGFloat = 672
}
diff --git a/Sources/Orbit/Support/Layout/LazyVStack.swift b/Sources/Orbit/Support/Layout/LazyVStack.swift
index 93b3674303f..d417b705930 100644
--- a/Sources/Orbit/Support/Layout/LazyVStack.swift
+++ b/Sources/Orbit/Support/Layout/LazyVStack.swift
@@ -1,5 +1,6 @@
import SwiftUI
+@available(iOS, deprecated: 14.0, message: "Use native variant")
struct LazyVStack: View {
var alignment: HorizontalAlignment = .center
diff --git a/Sources/Orbit/Support/Layout/PotentiallyEmptyView.swift b/Sources/Orbit/Support/Layout/PotentiallyEmptyView.swift
index e8f07aa7367..c744142dfd6 100644
--- a/Sources/Orbit/Support/Layout/PotentiallyEmptyView.swift
+++ b/Sources/Orbit/Support/Layout/PotentiallyEmptyView.swift
@@ -1,5 +1,5 @@
-/// A type that represents views that can optionally result in `EmptyView`.
+/// A type that represents Orbit components that can optionally result in `EmptyView`.
protocol PotentiallyEmptyView {
var isEmpty: Bool { get }
}
diff --git a/Sources/Orbit/Support/Layout/ScreenLayoutModifier.swift b/Sources/Orbit/Support/Layout/ScreenLayoutModifier.swift
index f73092e4638..0c3ab1ea33a 100644
--- a/Sources/Orbit/Support/Layout/ScreenLayoutModifier.swift
+++ b/Sources/Orbit/Support/Layout/ScreenLayoutModifier.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Padding to apply in a `screenLayout` context.
+/// Padding to apply in Orbit `screenLayout` context.
public enum ScreenLayoutPadding {
/// Padding of `medium` size in compact horizontal size and `xxLarge` size in regular horizontal size.
case `default`
@@ -65,7 +65,7 @@ struct ScreenLayoutModifier: ViewModifier {
public extension View {
- /// Adds unified screen layout for both `regular` and `compact` width environment.
+ /// Adds unified Orbit layout to a screen for both `regular` and `compact` width environment.
///
/// Screen layout adds maximum width and padding behaviour for provided content, horizontally expanding to `infinity`.
///
diff --git a/Sources/Orbit/Support/Resources/AssetNameProviding.swift b/Sources/Orbit/Support/Resources/AssetNameProviding.swift
index ef501b7f085..cd4820b417f 100644
--- a/Sources/Orbit/Support/Resources/AssetNameProviding.swift
+++ b/Sources/Orbit/Support/Resources/AssetNameProviding.swift
@@ -1,4 +1,5 @@
+/// Type that provides asset name for Orbit components.
public protocol AssetNameProviding: RawRepresentable {
var assetName: String { get }
diff --git a/Sources/Orbit/Support/Resources/Bundle.swift b/Sources/Orbit/Support/Resources/Bundle.swift
index 52dea0af50c..a55c156f9cc 100644
--- a/Sources/Orbit/Support/Resources/Bundle.swift
+++ b/Sources/Orbit/Support/Resources/Bundle.swift
@@ -1,5 +1,7 @@
import Foundation
public extension Bundle {
+
+ /// A bundle that defines Orbit resources.
static let orbit = Bundle.module
}
diff --git a/Sources/Orbit/Support/Status.swift b/Sources/Orbit/Support/Status.swift
index 05cd802b214..dc7d8f347fd 100644
--- a/Sources/Orbit/Support/Status.swift
+++ b/Sources/Orbit/Support/Status.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Non-default status of a component.
+/// Non-default status of Orbit components.
public enum Status: Equatable {
case info
case success
diff --git a/Sources/Orbit/Support/Text/TextRepresentable.swift b/Sources/Orbit/Support/Text/TextRepresentable.swift
index 346cc76e074..883d025c597 100644
--- a/Sources/Orbit/Support/Text/TextRepresentable.swift
+++ b/Sources/Orbit/Support/Text/TextRepresentable.swift
@@ -1,10 +1,11 @@
import SwiftUI
-/// A type that can be represented as `SwiftUI.Text`
+/// A type that can be represented as `SwiftUI.Text` and can serve as Orbit concatenable component.
///
-/// Use the `+` operator to concatenate two `TextRepresentable` elements.
+/// Use the `+` operator to concatenate ``TextRepresentable`` elements.
public protocol TextRepresentable {
+ /// Extracts native `SwiftUI.Text` from type that represents textual content.
func swiftUIText(textRepresentableEnvironment: TextRepresentableEnvironment) -> SwiftUI.Text?
}
diff --git a/Sources/Orbit/Support/TextFields/InsetableTextField.swift b/Sources/Orbit/Support/TextFields/InsetableTextField.swift
index b080523f8bf..b878b747da3 100644
--- a/Sources/Orbit/Support/TextFields/InsetableTextField.swift
+++ b/Sources/Orbit/Support/TextFields/InsetableTextField.swift
@@ -1,6 +1,6 @@
import UIKit
-/// Orbit UITextField wrapper with a larger touch area.
+/// Orbit `UITextField` wrapper with a larger touch area.
public class InsetableTextField: UITextField {
// Using .small vertical padding would cause resize issue in secure mode
diff --git a/Sources/Orbit/Support/TextFields/InsetableTextView.swift b/Sources/Orbit/Support/TextFields/InsetableTextView.swift
index d388e685872..a30f93d49fc 100644
--- a/Sources/Orbit/Support/TextFields/InsetableTextView.swift
+++ b/Sources/Orbit/Support/TextFields/InsetableTextView.swift
@@ -1,6 +1,6 @@
import UIKit
-/// Orbit UITextView wrapper with a larger touch area and a prompt.
+/// Orbit `UITextView` wrapper with a larger touch area and a prompt.
public class InsetableTextView: UITextView {
public var insets: UIEdgeInsets = .zero
diff --git a/Sources/Orbit/Support/TextFields/TextField.swift b/Sources/Orbit/Support/TextFields/TextField.swift
index a52c70049a6..bb6eda55f54 100644
--- a/Sources/Orbit/Support/TextFields/TextField.swift
+++ b/Sources/Orbit/Support/TextFields/TextField.swift
@@ -1,7 +1,7 @@
import SwiftUI
import UIKit
-/// Orbit control that displays an editable text interface, a replacement for native `TextField` component.
+/// Orbit control that displays an editable text interface, a replacement for native `SwiftUI.TextField` component.
///
/// The component uses UIKit `UITextField` implementation to support these feature for older iOS versions:
/// - focus changes
diff --git a/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift b/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift
index 064ccd68a1c..5dcdd7d5222 100644
--- a/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift
+++ b/Sources/Orbit/Support/TextFields/TextFieldCoordinator.swift
@@ -1,6 +1,6 @@
import SwiftUI
-/// Coordinator that manages Orbit text input components `InputField` and `Textarea`.
+/// Coordinator that manages Orbit text input components ``InputField`` and ``Textarea``.
public final class TextFieldCoordinator: NSObject, ObservableObject {
static var textFieldToBecomeResponder: UITextInput?
diff --git a/Sources/Orbit/Support/TextFields/TextView.swift b/Sources/Orbit/Support/TextFields/TextView.swift
index bbfb3893a1d..021d63eb667 100644
--- a/Sources/Orbit/Support/TextFields/TextView.swift
+++ b/Sources/Orbit/Support/TextFields/TextView.swift
@@ -1,7 +1,7 @@
import SwiftUI
import UIKit
-/// Orbit control that displays a multiline editable text interface, a replacement for the native multiline `TextField` component.
+/// Orbit control that displays a multiline editable text interface, a replacement for the native multiline `SwiftUI.TextField` component.
///
/// The component uses UIKit `UITextView` implementation to support these feature for older iOS versions:
/// - focus changes
diff --git a/Sources/Orbit/Support/TextLinks/TagAttributedStringBuilder.swift b/Sources/Orbit/Support/TextLinks/TagAttributedStringBuilder.swift
index e36f5087066..014d974333d 100644
--- a/Sources/Orbit/Support/TextLinks/TagAttributedStringBuilder.swift
+++ b/Sources/Orbit/Support/TextLinks/TagAttributedStringBuilder.swift
@@ -1,8 +1,7 @@
import UIKit
import SwiftUI
-// Duplicate of TagAttributedStringBuilder in SharedUI with slight alterations.
-@available(iOS, deprecated: 15.0, message: "Will be replaced with a native markdown-enabled Text component")
+@available(iOS, deprecated: 15.0, message: "Use native markdown-enabled Text component")
final class TagAttributedStringBuilder {
enum Tag: Equatable, CaseIterable {
@@ -172,7 +171,7 @@ struct TagAttributedStringBuilderTagFinder {
}
}
-public extension String {
+extension String {
var containsHtmlFormatting: Bool {
TagAttributedStringBuilder.all.tagFinder.hasMatches(for: self)
diff --git a/Sources/Orbit/Support/TextLinks/Text+AttributedString.swift b/Sources/Orbit/Support/TextLinks/Text+AttributedString.swift
index d3fff89aa71..f47e8ea8b44 100644
--- a/Sources/Orbit/Support/TextLinks/Text+AttributedString.swift
+++ b/Sources/Orbit/Support/TextLinks/Text+AttributedString.swift
@@ -2,6 +2,7 @@ import SwiftUI
public extension SwiftUI.Text {
+ /// Multiplier for Orbit font kerning.
static var kerningMultiplier: CGFloat {
if #available(iOS 16.0, *) {
return 1.0
@@ -10,8 +11,8 @@ public extension SwiftUI.Text {
}
}
- /// Creates a native SwiftUI Text from attributed string.
- @available(iOS, deprecated: 15.0, message: "Will be replaced with a native init")
+ /// Creates a native `SwiftUI.Text` from attributed string.
+ @available(iOS, deprecated: 15.0, message: "Use native initializer", renamed: "init(_:)")
init(_ string: NSAttributedString) {
self.init("")
diff --git a/Sources/Orbit/Support/TextLinks/TextLinkView.swift b/Sources/Orbit/Support/TextLinks/TextLinkView.swift
index c08c174c6b8..3ab25ad09c4 100644
--- a/Sources/Orbit/Support/TextLinks/TextLinkView.swift
+++ b/Sources/Orbit/Support/TextLinks/TextLinkView.swift
@@ -1,7 +1,7 @@
import UIKit
import SwiftUI
-/// A view representing `TextLink` layer.
+/// A view that represents the Orbit ``TextLink`` layer.
public final class TextLinkView: UITextView, UITextViewDelegate {
let action: TextLink.Action
diff --git a/Sources/Orbit/Support/Toast/ToastQueue.swift b/Sources/Orbit/Support/Toast/ToastQueue.swift
index 016fa564255..688bbef4dfd 100644
--- a/Sources/Orbit/Support/Toast/ToastQueue.swift
+++ b/Sources/Orbit/Support/Toast/ToastQueue.swift
@@ -1,9 +1,9 @@
import Combine
import SwiftUI
-/// Serial queue for Orbit Toast component.
+/// Serial queue for Orbit ``Toast`` component.
///
-/// Allows adding new Toasts and dismissing or pausing the currently displayed Toast.
+/// Allows adding new messages and dismissing or pausing the currently displayed message in a ``Toast``.
public final class ToastQueue: ObservableObject {
public static let toastsBufferSize = 5
@@ -18,7 +18,7 @@ public final class ToastQueue: ObservableObject {
case dismiss
}
- /// View model for Orbit Toast component.
+ /// View model for Orbit ``Toast`` component.
public struct Toast: Identifiable {
public let id: UUID
let description: String
@@ -48,6 +48,7 @@ public final class ToastQueue: ObservableObject {
private var toastsSubject = PassthroughSubject()
private var currentToastActionSubject: CurrentValueSubject?
+ /// Creates Orbit ``ToastQueue``.
public init() {
cancellable = toastsSubject
.buffer(size: Self.toastsBufferSize, prefetch: .keepFull, whenFull: .dropOldest)
diff --git a/Sources/OrbitIllustrations/Components/Illustration.swift b/Sources/OrbitIllustrations/Components/Illustration.swift
index c44d801f30e..d071e069f53 100644
--- a/Sources/OrbitIllustrations/Components/Illustration.swift
+++ b/Sources/OrbitIllustrations/Components/Illustration.swift
@@ -1,10 +1,21 @@
import SwiftUI
import Orbit
-/// An illustration matching Orbit name.
+/// Orbit component that displays an illustration.
///
-/// - Note: [Orbit definition](https://orbit.kiwi/components/illustration/)
-/// - Important: The component expands horizontally to infinity in case of `frame` layout, unless prevented by `idealSize` modifier.
+/// An ``Illustration`` is created using Orbit or custom resource.
+///
+/// ```swift
+/// Illustration(.womanWithPhone)
+/// Illustration("my-illustration", layout: .resizeable)
+/// .frame(height: 50)
+/// ```
+///
+/// ### Layout
+///
+/// The component expands horizontally to infinity in case of the default `frame` layout, unless prevented by `idealSize` modifier. A `resizeable` layout makes the illustration size to fit to desired size.
+///
+/// - Note: [Orbit.kiwi documentation](https://orbit.kiwi/components/illustration/)
public struct Illustration: View {
@Environment(\.idealSize) var idealSize
diff --git a/Sources/OrbitIllustrations/Extensions/ChoiceTile+Illustration.swift b/Sources/OrbitIllustrations/Extensions/ChoiceTile+Illustration.swift
index 5a966d52687..9526f7cfef3 100644
--- a/Sources/OrbitIllustrations/Extensions/ChoiceTile+Illustration.swift
+++ b/Sources/OrbitIllustrations/Extensions/ChoiceTile+Illustration.swift
@@ -3,7 +3,7 @@ import Orbit
public extension ChoiceTile {
- /// Creates Orbit ChoiceTile component.
+ /// Creates Orbit ``ChoiceTile`` component with illustration.
///
/// - Parameters:
/// - content: The content shown below the header.
@@ -43,7 +43,7 @@ public extension ChoiceTile {
}
}
- /// Creates Orbit ChoiceTile component.
+ /// Creates Orbit ``ChoiceTile`` component with illustration.
///
/// - Parameters:
/// - content: The content shown below the header.
diff --git a/Sources/OrbitIllustrations/Extensions/Dialog+Illustration.swift b/Sources/OrbitIllustrations/Extensions/Dialog+Illustration.swift
index c3f358e5222..59bd1d4dffe 100644
--- a/Sources/OrbitIllustrations/Extensions/Dialog+Illustration.swift
+++ b/Sources/OrbitIllustrations/Extensions/Dialog+Illustration.swift
@@ -3,7 +3,7 @@ import Orbit
public extension Dialog {
- /// Creates Orbit Dialog component with an illustration.
+ /// Creates Orbit ``Dialog`` component with an illustration.
init(
_ title: String = "",
description: String = "",
diff --git a/Sources/OrbitIllustrations/Extensions/EmptyState+Illustration.swift b/Sources/OrbitIllustrations/Extensions/EmptyState+Illustration.swift
index e6f9dcfbf43..6352a6609c4 100644
--- a/Sources/OrbitIllustrations/Extensions/EmptyState+Illustration.swift
+++ b/Sources/OrbitIllustrations/Extensions/EmptyState+Illustration.swift
@@ -3,7 +3,7 @@ import Orbit
public extension EmptyState {
- /// Creates Orbit EmptyState component with illustration.
+ /// Creates Orbit ``EmptyState`` component with illustration.
init(
_ title: String = "",
description: String = "",
@@ -16,7 +16,7 @@ public extension EmptyState {
}
}
- /// Creates Orbit EmptyState component with illustration and no action.
+ /// Creates Orbit ``EmptyState`` component with illustration and no action.
init(
_ title: String = "",
description: String = "",
]