From 26f4e48d8578b606bc0e60071df872af4680a9e5 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Lapersonne Date: Tue, 4 Feb 2025 16:08:53 +0100 Subject: [PATCH] chore: update doc, add icon for demo app, refactor of properties (#264) Signed-off-by: Pierre-Yves Lapersonne --- .../xcdebugger/Breakpoints_v2.xcbkptlist | 34 -------- .../Checkbox/CheckboxConfiguration.swift | 6 +- .../Components/Checkbox/CheckboxPage.swift | 4 +- .../Contents.json | 12 +++ .../il_component_checkbox.svg | 30 +++++++ .../Resources/en.lproj/Localizable.strings | 2 +- .../Sources/Checkbox/OUDSCheckbox.swift | 82 +++++++++++++++---- .../DividerModifier/View+Divider.swift | 8 +- .../_OUDSComponents.docc/OUDSComponents.md | 18 +++- 9 files changed, 132 insertions(+), 64 deletions(-) create mode 100644 DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/Contents.json create mode 100644 DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/il_component_checkbox.svg diff --git a/DesignToolbox/DesignToolbox.xcworkspace/xcuserdata/xhrs0459.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/DesignToolbox/DesignToolbox.xcworkspace/xcuserdata/xhrs0459.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 13fb292f7..48d5dd34f 100644 --- a/DesignToolbox/DesignToolbox.xcworkspace/xcuserdata/xhrs0459.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/DesignToolbox/DesignToolbox.xcworkspace/xcuserdata/xhrs0459.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,38 +3,4 @@ uuid = "B4A15A02-0B7C-4A17-81BE-9CA389B02C0B" type = "0" version = "2.0"> - - - - - - - - - - diff --git a/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxConfiguration.swift b/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxConfiguration.swift index 9d087e85c..b0c2d7d22 100644 --- a/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxConfiguration.swift +++ b/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxConfiguration.swift @@ -49,8 +49,6 @@ final class CheckboxConfigurationModel: ComponentConfiguration { didSet { updateCode() } } - // TODO: #264 - Read only - // MARK: - Internal types enum DesignToolboxCheckboxLayout: CaseIterable, CustomStringConvertible { // OUDSCheckbox.Layouy is not accessible @@ -93,13 +91,13 @@ final class CheckboxConfigurationModel: ComponentConfiguration { if layout == .selectorOnly { code = """ - OUDSCheckbox(selectorState: $state\(isErrorPattern)) + OUDSCheckbox(state: $state\(isErrorPattern)) \(disableCode)) """ } else { code = """ - OUDSCheckbox(selectorState: $state, label: \"Label\"\(helperTextPatern)\(iconPatern)\(isInversedPattern)\(isErrorPattern)\(dividerPatern)) + OUDSCheckbox(state: $state, label: \"Label\"\(helperTextPatern)\(iconPatern)\(isInversedPattern)\(isErrorPattern)\(dividerPatern)) \(disableCode)) """ } diff --git a/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxPage.swift b/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxPage.swift index 0d06d3ebc..6bbd7a794 100644 --- a/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxPage.swift +++ b/DesignToolbox/DesignToolbox/Pages/Components/Checkbox/CheckboxPage.swift @@ -77,12 +77,12 @@ private struct CheckboxDemo: View { if model.layout == .selectorOnly { HStack(alignment: .center) { Spacer() - OUDSCheckbox(selectorState: $model.selectorState) + OUDSCheckbox(state: $model.selectorState) .disabled(!model.isEnabled) Spacer() } } else { - OUDSCheckbox(selectorState: $model.selectorState, + OUDSCheckbox(state: $model.selectorState, label: "app_components_checkbox_label_text", helperText: helperText, icon: icon, diff --git a/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/Contents.json b/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/Contents.json new file mode 100644 index 000000000..d947eed97 --- /dev/null +++ b/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "il_component_checkbox.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/il_component_checkbox.svg b/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/il_component_checkbox.svg new file mode 100644 index 000000000..b365f0c77 --- /dev/null +++ b/DesignToolbox/DesignToolbox/Resources/Assets.xcassets/Components/il_component_checkbox.imageset/il_component_checkbox.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DesignToolbox/DesignToolbox/Resources/en.lproj/Localizable.strings b/DesignToolbox/DesignToolbox/Resources/en.lproj/Localizable.strings index 518854ed5..e90c90242 100644 --- a/DesignToolbox/DesignToolbox/Resources/en.lproj/Localizable.strings +++ b/DesignToolbox/DesignToolbox/Resources/en.lproj/Localizable.strings @@ -147,7 +147,7 @@ // TODO: #264 - Update wording "app_components_checkbox_label" = "Checkbox"; -"app_components_checkbox_description_text" = "A checkbox is a component that allows the user to toggle between two or three states, typically \"on\", \"off\" or \"unknown\". It is often represented as a square whichc an be ticked or not and color to indicate the current state. Checkboxes are used to select things like features, options, or settings in an intuitive and visual manner."; +"app_components_checkbox_description_text" = "A checkbox is a component that allows the user to toggle between two or three states, typically \"on\", \"off\" or \"undeterminate\". It is often represented as a square whichc an be ticked or not and color to indicate the current state. Checkboxes are used to select things like features, options, or settings in an intuitive and visual manner."; "app_components_checkbox_label_text" = "Label"; "app_components_checkbox_switchOnly_label" = "Checkbox only"; "app_components_checkbox_helperText_text" = "Helper Text"; diff --git a/OUDS/Core/Components/Sources/Checkbox/OUDSCheckbox.swift b/OUDS/Core/Components/Sources/Checkbox/OUDSCheckbox.swift index 73073b0f0..786db9438 100644 --- a/OUDS/Core/Components/Sources/Checkbox/OUDSCheckbox.swift +++ b/OUDS/Core/Components/Sources/Checkbox/OUDSCheckbox.swift @@ -16,23 +16,70 @@ import SwiftUI // MARK: - OUDS Checkbox -/// The ``OUDSCheckbox`` proposes a layout as a nested element. -/// It also proposes a more complex layout with text, icon and divider. +/// The ``OUDSCheckbox`` proposes layout to add in your views some checkboxes components, even if this type of component is not iOS-native one. +/// +/// ## Layouts +/// +/// The component can be rendered as three different layouts: +/// +/// - **selector only**: the component is nested, only its selector is displayed and nothing else, a pure checkbox +/// - **default**: the component has a leading selector, a label and optional helper texts, and an optional trailing decorative icon +/// - **inverse**: like the *default* layout but with a trailing checkbox seelctor and a leading optional image +/// +/// These layours cannot be managed as they are by the user, but are defined according to what type of data are given to the component initializers. +/// +/// ## Selector states +/// +/// The checkbox selector has three available states: +/// - **selected**: the checkbox is filled with a tick, the user has made the action to select the checkbox +/// - **unselected**: the checkbox is empty, does not contain a tick, the user has made the action to unselect or did not select yet the checkbox +/// - **undeterminate**: mike a prefilled or preticked checkbox, the user did not do anything on it yet /// /// ## Code samples /// -/// TODO: #254 Add code samples +/// ```swift +/// // Supposing we have an undeterminate state checkbox +/// @Published var state: OUDSCheckbox.SelectorState = .undeterminate +/// +/// // A simple checkbox, nested, selected. +/// // The nested layout will be used here. +/// OUDSCheckbox(state: $state) +/// +/// // A leading checkbox with a label +/// // The default layout will be used here. +/// OUDSCheckbox(state: $state, label: "Hello world") +/// +/// // A leading checkbox with a label, and an helper text. +/// // The default layout will be used here. +/// OUDSCheckbox(state: $state, label: "Bazinga!", helperText: "Doll-Dagga Buzz-Buzz Ziggety-Zag") +/// +/// // A trailing checkbox with a label, an helper text and an icon. +/// // The inverse layout will be used here. +/// OUDSCheckbox(state: $state, +/// label: "We live in a fabled world", +/// helperText: "Of dreaming boys and wide-eyed girls", +/// icon: Image(decorative: "ic_heart")) +/// +/// // A trailing checkbox with a label, an helper text, an icon, a divider and is about an error. +/// // The inverse layout will be used here. +/// OUDSCheckbox(state: $state, +/// label: "Rescue from this world!", +/// helperText: "Put your hand in mine", +/// icon: Image(decorative: "ic_heart"), +/// isError: true, +/// divider: true) +/// ``` /// /// ## Design documentation /// -/// See [#TODO] +/// See [unified-design-system.orange.com/472794e18/p/23f1c1-checkbox](https://unified-design-system.orange.com/472794e18/p/23f1c1-checkbox) /// /// - Since: 0.11.0 public struct OUDSCheckbox: View { // MARK: - Properties - @Binding private var selectorState: SelectorState + @Binding private var state: SelectorState private let layout: Layout // MARK: - State @@ -47,6 +94,7 @@ public struct OUDSCheckbox: View { /// The checkbox is like prefilled, preticked, the user does not select it yet but is not empty case undeterminate // (╯° °)╯︵ ┻━┻ + /// Changes the value to the next one. public mutating func toggle () { switch self { case .selected: @@ -80,31 +128,31 @@ public struct OUDSCheckbox: View { /// Creates a checkbox with no label. /// /// - Parameters: - /// - selectorState: A binding to a property that determines wether the selector is ticked, unticked or preticked. + /// - state: A binding to a property that determines wether the selector is ticked, unticked or preticked. /// - isError: True if the look and feel of the component must reflect an error state, default set to `false` - public init(selectorState: Binding, isError: Bool = false) { - self._selectorState = selectorState + public init(state: Binding, isError: Bool = false) { + self._state = state self.layout = .selectorOnly(isError) } /// Creates a checkbox with label and optional helper text, icon, divider. /// /// - Parameters: - /// - selectorState: A binding to a property that determines wether the selector is ticked, unticker or preticked. + /// - state: A binding to a property that determines wether the selector is ticked, unticker or preticked. /// - label: The main label of the switch. /// - helperText: An additonal helper text. /// - icon: An optional icon /// - isInversed: `True` of the checkbox selector must be in trailing position,` false` otherwise. Default to `false` /// - isError: `True` if the look and feel of the component must reflect an error state, default set to `false` /// - divider: If `true` a divider is added at the bottom of the view. - public init(selectorState: Binding, + public init(state: Binding, label: String, helperText: String? = nil, icon: Image? = nil, isInversed: Bool = false, isError: Bool = false, divider: Bool = false) { - self._selectorState = selectorState + self._state = state if isInversed { self.layout = .inverse(.init(label: label, helperText: helperText, icon: icon, isError: isError, divider: divider)) } else { @@ -118,19 +166,19 @@ public struct OUDSCheckbox: View { switch layout { case .default(let label): Button("") { - $selectorState.wrappedValue.toggle() + $state.wrappedValue.toggle() } - .buttonStyle(OUDSCheckboxLabeledStyle(selectorState: $selectorState.wrappedValue, items: label, isInversed: false)) + .buttonStyle(OUDSCheckboxLabeledStyle(selectorState: $state.wrappedValue, items: label, isInversed: false)) case .inverse(let label): Button("") { - $selectorState.wrappedValue.toggle() + $state.wrappedValue.toggle() } - .buttonStyle(OUDSCheckboxLabeledStyle(selectorState: $selectorState.wrappedValue, items: label, isInversed: true)) + .buttonStyle(OUDSCheckboxLabeledStyle(selectorState: $state.wrappedValue, items: label, isInversed: true)) case .selectorOnly(let isError): Button("") { - $selectorState.wrappedValue.toggle() + $state.wrappedValue.toggle() } - .buttonStyle(OUDSCheckboxNestedStyle(selectorState: $selectorState.wrappedValue, isError: isError)) + .buttonStyle(OUDSCheckboxNestedStyle(selectorState: $state.wrappedValue, isError: isError)) } } } diff --git a/OUDS/Core/Components/Sources/ViewModifiers/DividerModifier/View+Divider.swift b/OUDS/Core/Components/Sources/ViewModifiers/DividerModifier/View+Divider.swift index c519cf11c..fbd41a011 100644 --- a/OUDS/Core/Components/Sources/ViewModifiers/DividerModifier/View+Divider.swift +++ b/OUDS/Core/Components/Sources/ViewModifiers/DividerModifier/View+Divider.swift @@ -21,12 +21,10 @@ extension View { /// ```swift /// var body: some View { /// SomeView() - /// .divider() + /// .oudsDivider(show: true) /// ``` - /// - Parameter: - /// - show: if true the divider is displayed, else there is no divider. - /// - /// - Returns some View: The current `View` but with a divider under. + /// - Parameter show: if `true` the divider is displayed, else there is no divider. + /// - Returns some View: The current `View` but with a divider bellow. public func oudsDivider(show: Bool = true) -> some View { self.modifier(DividerModifier(show: show)) } diff --git a/OUDS/Core/Components/Sources/_OUDSComponents.docc/OUDSComponents.md b/OUDS/Core/Components/Sources/_OUDSComponents.docc/OUDSComponents.md index 03e2931c1..87882a5b0 100644 --- a/OUDS/Core/Components/Sources/_OUDSComponents.docc/OUDSComponents.md +++ b/OUDS/Core/Components/Sources/_OUDSComponents.docc/OUDSComponents.md @@ -56,7 +56,23 @@ if switch is in form it is possible to set it in error state. ### Checkbox -TODO: #264 - Add doc +The ``OUDSCheckbox`` proposes layout to add in your views some checkboxes components, even if this type of component is not iOS-native one. + +```swift + // A simple checkbox, nested, selected + OUDSCheckbox(state: $state) + + // A leading checkbox with a label + OUDSCheckbox(state: $state, label: "Hello world") + + // A trailing checkbox with a label, an helper text, an icon, a divider and is about an error + OUDSCheckbox(state: $state, + label: "We live in a fabled world", + helperText: "Of dreaming boys and wide-eyed girls", + icon: Image(decorative: "ic_heart"), + isError: true, + divider: true) +``` ## Customize components