Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#264] Add checkbox component #445

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5e9fc86
First version of switch without tokens for now
ludovic35 Jan 28, 2025
691f169
Add screen for switch component
ludovic35 Jan 28, 2025
a018eee
Use first verion of tokens
ludovic35 Jan 28, 2025
770cdad
Set ListItem as Button
ludovic35 Jan 30, 2025
49b80ee
Add wordings keys, code example and update changelog file
ludovic35 Feb 3, 2025
a9b285d
Add documentation
ludovic35 Feb 3, 2025
aa12111
Adjust the position of the switch and the icon at the top
ludovic35 Feb 4, 2025
0c0542a
Add orientation
ludovic35 Feb 4, 2025
0c3e7f0
Add two texfields to get text for label and helper text
ludovic35 Feb 4, 2025
703d865
update wording and apply same rules on key naming
ludovic35 Feb 5, 2025
dc7ccdf
review fix typo and remarks
ludovic35 Feb 5, 2025
637c45a
review: rename Label to LabelText
ludovic35 Feb 5, 2025
f9176c3
Set ListItem as Button
ludovic35 Jan 30, 2025
9b87398
Add wordings keys, code example and update changelog file
ludovic35 Feb 3, 2025
6e2d887
chore: duplicate implementation of switch for checkbox component (#264)
pylapp Feb 4, 2025
7bc80a7
chore: duplicate presentation of switch for checkbox in design toolbo…
pylapp Feb 4, 2025
3f04419
feat: management of three states of checkbox component (#264)
pylapp Feb 4, 2025
eb28ef5
chore: add fake tokens, refactor names, improve styles of selector (#…
pylapp Feb 4, 2025
60373c2
chore: update design toolbox, manage states and init (#264)
pylapp Feb 4, 2025
c7f8427
chore: better manage of state object for checkbox VM
pylapp Feb 4, 2025
c50e258
chore: update doc, add icon for demo app, refactor of properties (#264)
pylapp Feb 4, 2025
83ae943
feat: add in design toolbox text fields for checkbox demo (#264)
pylapp Feb 4, 2025
46a8ff7
chore: stack items to top for long texts dispay (#264)
pylapp Feb 4, 2025
7c917c4
chore: add tick and dash images for selector (#264)
pylapp Feb 5, 2025
2b9a42f
chore(🤖): update `CheckRadioComponentTokens`
pylapp Feb 4, 2025
71a3961
chore: apply tokens for selector (#264)
pylapp Feb 5, 2025
904d824
chore: manage centering of items in label (#264)
pylapp Feb 5, 2025
ef65a8d
feat: add read only status (#264)
pylapp Feb 5, 2025
c9089ce
chore: more management of colors (#264)
pylapp Feb 5, 2025
a122ee8
chore: rename label to labelText (#264)
pylapp Feb 5, 2025
9c52d20
chore: add more spacing token (#264)
pylapp Feb 6, 2025
28a7654
chore: update configuration of checkbox (#264)
pylapp Feb 6, 2025
1afb398
chore: update card ind esign toolbox (#264)
pylapp Feb 6, 2025
87055f9
feat: vocalization of component (#264)
pylapp Feb 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- [DesignToolbox] Add text field in component configuration to customize text ([#436](https://github.com/Orange-OpenSource/ouds-ios/issues/436))
- [Library] Checkbox component ([#264](https://github.com/Orange-OpenSource/ouds-ios/issues/264))
- [Library] Switch component ([#405](https://github.com/Orange-OpenSource/ouds-ios/issues/405))
- [DesignToolbox] Add text field in component configuration to customize text ([#436](https://github.com/Orange-OpenSource/ouds-ios/issues/436))
- [Library] Link component ([#400](https://github.com/Orange-OpenSource/ouds-ios/issues/400))

### Changed

- [Library] Checkbox and radio button component tokens (tokens library v0.5.0)

## [0.10.0](https://github.com/Orange-OpenSource/ouds-ios/compare/0.9.0...0.10.0) - 2025-01-30

### Added
Expand Down
69 changes: 66 additions & 3 deletions DesignToolbox/DesignToolbox.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
<<<<<<< HEAD
"originHash" : "4958997d028ec0467bfc12b899aa509b9b9301311c84850262a1935095ba73d5",
=======
"originHash" : "2607da8610cd896469838f47a63558192b1b0c03641b836042ba28782dedbab2",
>>>>>>> 48c1a0756 (chore: stack items to top for long texts dispay (#264))
"pins" : [
{
"identity" : "accessibility-statement-lib-ios",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ struct ButtonConfiguration: View {
}

if model.layout == .iconAndText || model.layout == .textOnly {
DesignToolboxTextField(text: $model.text, prompt: "app_component_common_userText_prompt")
DesignToolboxTextField(text: $model.text, prompt: "app_components_common_userText_prompt")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
//
// Software Name: OUDS iOS
// SPDX-FileCopyrightText: Copyright (c) Orange SA
// SPDX-License-Identifier: MIT
//
// This software is distributed under the MIT license,
// the text of which is available at https://opensource.org/license/MIT/
// or see the "LICENSE" file for more details.
//
// Authors: See CONTRIBUTORS.txt
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
//

import OUDSComponents
import SwiftUI

// MARK: - Checkbox Configuration Model

/// The model shared between `CheckboxPageConfiguration` view and `SwitchPageComponent` view.
final class CheckboxConfigurationModel: ComponentConfiguration {

// MARK: - Properties

@Published var status: DesignToolboxCheckboxStatus {
didSet { updateCode() }
}

@Published var selectorState: OUDSCheckbox.SelectorState {
didSet { updateCode() }
}

@Published var layout: DesignToolboxCheckboxLayout {
didSet { updateCode() }
}

@Published var helperText: Bool {
didSet { updateCode() }
}

@Published var icon: Bool {
didSet { updateCode() }
}

@Published var isError: Bool {
didSet { updateCode() }
}

@Published var divider: Bool {
didSet { updateCode() }
}

@Published var labelContent: String

@Published var helperTextContent: String

private var isReadOnly: Bool {
status == .readOnly
}

// MARK: - Internal types

enum DesignToolboxCheckboxStatus: CaseIterable, CustomStringConvertible { // CheckboxInternalState is not accessible
case enabled
case disabled
case readOnly

// No l10n, tehchnical names
var description: String {
switch self {
case .enabled:
"Enabled"
case .disabled:
"Disabled"
case .readOnly:
"Read only"
}
}

var id: String { description }
}

enum DesignToolboxCheckboxLayout: CaseIterable, CustomStringConvertible { // OUDSCheckbox.Layout is not accessible
case selectorOnly
case `default`
case inverse

// No l10n, tehchnical names
var description: String {
switch self {
case .selectorOnly:
"Checkbox only"
case .default:
"Left action"
case .inverse:
"Right action"
}
}

var id: String { description }
}

// MARK: - Initializer

override init() {
status = .enabled
selectorState = .selected
layout = .selectorOnly
helperText = true
icon = true
isError = false
divider = true
labelContent = String(localized: "app_components_checkbox_label_text")
helperTextContent = String(localized: "app_components_checkbox_helperText_text")
}

deinit { }

// MARK: - Component Configuration

override func updateCode() {
if layout == .selectorOnly {
code =
"""
OUDSCheckbox(state: $state\(isErrorPattern))
\(disableCode))
"""
} else {
code =
"""
OUDSCheckbox(state: $state, labelText: \"Label\"\(helperTextPatern)\(iconPatern)\(isInversedPattern)\(isErrorPattern)\(isReadOnlyPattern)\(dividerPatern))
\(disableCode))
"""
}
}

private var disableCode: String {
".disable(\(status != .enabled ? "false" : "true"))"
}

private var helperTextPatern: String {
if helperText {
return ", helperText: \"\(String(localized: "app_components_checkbox_helperText_text"))\""
} else {
return ""
}
}

private var iconPatern: String {
if icon {
return ", icon: Image(decorative: \"ic_heart\")"
} else {
return ""
}
}

private var isInversedPattern: String {
layout == .inverse ? ", isInversed: true" : ""
}

private var isErrorPattern: String {
if isError && status == .enabled && !isReadOnly {
return ", isError: true"
} else {
return ""
}
}

private var isReadOnlyPattern: String {
if isReadOnly && !isError {
return ", isReadOnly: true"
} else {
return ""
}
}

private var dividerPatern: String {
divider ? ", divider: true" : ""
}
}

// MARK: - Checkbox Configuration View

struct CheckboxConfiguration: View {

@ObservedObject var model: CheckboxConfigurationModel

@Environment(\.theme) private var theme
@Environment(\.colorScheme) private var colorScheme

var body: some View {
VStack(alignment: .leading, spacing: theme.spaces.spaceFixedMedium) {
DesignToolboxChoicePicker(title: "app_common_enabled_label", selection: $model.status) {
ForEach(CheckboxConfigurationModel.DesignToolboxCheckboxStatus.allCases, id: \.id) { state in
Text(LocalizedStringKey(state.description)).tag(state)
}
}

DesignToolboxChoicePicker(title: "app_components_checkbox_selection_label", selection: $model.selectorState) {
ForEach(OUDSCheckbox.SelectorState.allCases, id: \.id) { state in
Text(LocalizedStringKey(state.description)).tag(state)
}
}

DesignToolboxChoicePicker(title: "app_components_checkbox_layout_label", selection: $model.layout) {
ForEach(CheckboxConfigurationModel.DesignToolboxCheckboxLayout.allCases, id: \.id) { layout in
Text(LocalizedStringKey(layout.description)).tag(layout)
}
}

if model.layout != .selectorOnly {
Toggle("app_components_common_icon_label", isOn: $model.icon)
.typeHeadingMedium(theme)
.foregroundStyle(theme.colors.colorContentDefault.color(for: colorScheme))

Toggle("app_components_common_divider_label", isOn: $model.divider)
.typeHeadingMedium(theme)
.foregroundStyle(theme.colors.colorContentDefault.color(for: colorScheme))

Toggle("app_components_checkbox_helperText_label", isOn: $model.helperText)
.typeHeadingMedium(theme)
.foregroundStyle(theme.colors.colorContentDefault.color(for: colorScheme))
}

Toggle("app_components_common_onError_label", isOn: $model.isError)
.typeHeadingMedium(theme)
.foregroundStyle(theme.colors.colorContentDefault.color(for: colorScheme))
.disabled(model.status != .enabled)

DisclosureGroup("app_components_common_editContent_label") {
DesignToolboxTextField(text: $model.labelContent,
prompt: "app_component_common_userText_prompt",
title: "app_components_common_labelText_label")
if model.helperText {
DesignToolboxTextField(text: $model.helperTextContent,
prompt: "app_component_common_userText_prompt",
title: "app_components_common_helperText_label")
}
}
}
}
}

// MARK: - Checkbox selector state extension

extension OUDSCheckbox.SelectorState: @retroactive CaseIterable, @retroactive CustomStringConvertible {
nonisolated(unsafe) public static var allCases: [OUDSCheckbox.SelectorState] = [.selected, .unselected, .undeterminate]

// No l10n, tehchnical names
public var description: String {
switch self {
case .selected:
"Selected"
case .unselected:
"Unselected"
case .undeterminate:
"Undeterminate"
}
}

var id: String { description }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Software Name: OUDS iOS
// SPDX-FileCopyrightText: Copyright (c) Orange SA
// SPDX-License-Identifier: MIT
//
// This software is distributed under the MIT license,
// the text of which is available at https://opensource.org/license/MIT/
// or see the "LICENSE" file for more details.
//
// Authors: See CONTRIBUTORS.txt
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
//

import SwiftUI

struct CheckboxElement: DesignToolboxElement {
let name: String
let image: Image
let pageDescription: AnyView

init() {
name = "app_components_checkbox_label"
image = Image(decorative: "il_component_checkbox").renderingMode(.original)
pageDescription = AnyView(DesignToolboxElementPage(
name: name,
image: nil,
description: "app_components_checkbox_description_text",
illustration: AnyView(CheckboxPage())
)
)
}
}
Loading