Skip to content

Commit 7fd9fc4

Browse files
authored
Implements simple LabeledContent (#416)
1 parent 624f900 commit 7fd9fc4

3 files changed

Lines changed: 109 additions & 44 deletions

File tree

Sources/SkipUI/SkipUI/Environment/EnvironmentValues.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,11 @@ extension EnvironmentValues {
688688
get { builtinValue(key: "_labelStyle", defaultValue: { nil }) as! LabelStyle? }
689689
set { setBuiltinValue(key: "_labelStyle", value: newValue, defaultValue: { nil }) }
690690
}
691+
692+
var _labeledContentStyle: LabeledContentStyle? {
693+
get { builtinValue(key: "_labeledContentStyle", defaultValue: { nil }) as! LabeledContentStyle? }
694+
set { setBuiltinValue(key: "_labeledContentStyle", value: newValue, defaultValue: { nil }) }
695+
}
691696

692697
var _layoutAxis: Axis? {
693698
get { builtinValue(key: "_layoutAxis", defaultValue: { nil }) as! Axis? }

Sources/SkipUI/SkipUI/Text/Label.swift

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -145,46 +145,6 @@ public struct LabelStyle: RawRepresentable, Equatable {
145145
public static let titleAndIcon = LabelStyle(rawValue: 3) // For bridging
146146
}
147147

148-
public struct LabeledContent {
149-
@available(*, unavailable)
150-
public init(@ViewBuilder content: () -> any View, @ViewBuilder label: () -> any View) {
151-
}
152-
153-
@available(*, unavailable)
154-
public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> any View) {
155-
}
156-
157-
@available(*, unavailable)
158-
public init(_ titleResource: LocalizedStringResource, @ViewBuilder content: () -> any View) {
159-
}
160-
161-
@available(*, unavailable)
162-
public init(_ title: String, @ViewBuilder content: () -> any View) {
163-
}
164-
165-
@available(*, unavailable)
166-
public init(_ titleKey: LocalizedStringKey, value: String) {
167-
}
168-
169-
@available(*, unavailable)
170-
public init(_ titleResource: LocalizedStringResource, value: String) {
171-
}
172-
173-
@available(*, unavailable)
174-
public init(_ title: String, value: String) {
175-
}
176-
}
177-
178-
public struct LabeledContentStyle: RawRepresentable, Equatable {
179-
public let rawValue: Int
180-
181-
public init(rawValue: Int) {
182-
self.rawValue = rawValue
183-
}
184-
185-
public static let automatic = LabeledContentStyle(rawValue: 0)
186-
}
187-
188148
extension View {
189149
public func labelStyle(_ style: LabelStyle) -> some View {
190150
#if SKIP
@@ -199,10 +159,6 @@ extension View {
199159
return labelStyle(LabelStyle(rawValue: bridgedStyle))
200160
}
201161

202-
public func labeledContentStyle(_ style: LabeledContentStyle) -> some View {
203-
return self
204-
}
205-
206162
@available(*, unavailable)
207163
public func labelReservedIconWidth(_ value: CGFloat) -> some View {
208164
return self
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2023–2026 Skip
2+
// SPDX-License-Identifier: MPL-2.0
3+
#if !SKIP_BRIDGE
4+
import Foundation
5+
#if SKIP
6+
import androidx.compose.foundation.layout.Arrangement
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.draw.scale
11+
import androidx.compose.ui.unit.dp
12+
#endif
13+
14+
// SKIP @bridge
15+
public struct LabeledContent : View, Renderable {
16+
let content: ComposeBuilder
17+
let label: ComposeBuilder
18+
19+
public init(@ViewBuilder content: () -> any View, @ViewBuilder label: () -> any View) {
20+
self.content = ComposeBuilder.from(content)
21+
self.label = ComposeBuilder.from(label)
22+
}
23+
24+
// SKIP @bridge
25+
public init(bridgedContent: any View, bridgedLabel: any View) {
26+
self.content = ComposeBuilder.from { bridgedContent }
27+
self.label = ComposeBuilder.from { bridgedLabel }
28+
}
29+
30+
public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> any View) {
31+
self.init(content: content) { Text(titleKey) }
32+
}
33+
public init(_ title: String, @ViewBuilder content: () -> any View) {
34+
self.init(content: content) { Text(verbatim: title) }
35+
}
36+
public init(_ titleResource: LocalizedStringResource, @ViewBuilder content: () -> any View) {
37+
self.init(content: content) { Text(titleResource) }
38+
}
39+
40+
public init(_ titleKey: LocalizedStringKey, value: String) {
41+
self.init { Text(verbatim: value) } label: { Text(titleKey) }
42+
}
43+
public init(_ title: String, value: String) {
44+
self.init { Text(verbatim: value) } label: { Text(verbatim: title) }
45+
}
46+
47+
#if SKIP
48+
@Composable override func Render(context: ComposeContext) {
49+
var style = EnvironmentValues.shared._labeledContentStyle ?? LabeledContentStyle.automatic
50+
RenderLabeleledContent(context: context)
51+
}
52+
53+
@Composable private func RenderLabeleledContent(context: ComposeContext) {
54+
Row(modifier: context.modifier.fillWidth(), horizontalArrangement: Arrangement.SpaceBetween, verticalAlignment: androidx.compose.ui.Alignment.CenterVertically) {
55+
RenderLabel(context: context.content())
56+
RenderContent(context: context.content())
57+
}
58+
}
59+
60+
/// Render only the label of this labeled content.
61+
@Composable func RenderLabel(context: ComposeContext, labelColor: Color? = nil) {
62+
if let labelColor {
63+
EnvironmentValues.shared.setValues {
64+
$0.set_foregroundStyle(labelColor)
65+
return ComposeResult.ok
66+
} in: {
67+
label.Compose(context: context)
68+
}
69+
} else {
70+
label.Compose(context: context)
71+
}
72+
}
73+
74+
/// Render only the content of this labeled content.
75+
@Composable func RenderContent(context: ComposeContext) {
76+
content.Compose(context: context)
77+
}
78+
#else
79+
public var body: some View {
80+
stubView()
81+
}
82+
#endif
83+
}
84+
85+
public struct LabeledContentStyle: RawRepresentable, Equatable {
86+
public let rawValue: Int
87+
88+
public init(rawValue: Int) {
89+
self.rawValue = rawValue
90+
}
91+
92+
public static let automatic = LabeledContentStyle(rawValue: 0) // For bridging
93+
}
94+
95+
extension View {
96+
public func labeledContentStyle(_ style: LabeledContentStyle) -> some View {
97+
#if SKIP
98+
return environment(\._labeledContentStyle, style, affectsEvaluate: false)
99+
#else
100+
return self
101+
#endif
102+
}
103+
}
104+
#endif

0 commit comments

Comments
 (0)