diff --git a/Packages/Sindresorhus_SSPreferences/README.md b/Packages/Sindresorhus_SSPreferences/README.md index a756a4ae..9fd2819d 100644 --- a/Packages/Sindresorhus_SSPreferences/README.md +++ b/Packages/Sindresorhus_SSPreferences/README.md @@ -8,4 +8,4 @@ See its original repository for details: https://github.com/sindresorhus/Preferences/ -Note: In vChewing IME, this module is renamed to SSPreferences due to potential namespace conflicts with InputMethodKit's own method of implementing system preferences pane. +Note: In vChewing IME, this module is renamed to SSPreferences due to potential namespace conflicts with InputMethodKit's own method of implementing system preferences pane. Also, this module has been heavily modded for vChewing-specific necessities. diff --git a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Container.swift b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Container.swift index 960d06d0..7a3b9aa3 100755 --- a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Container.swift +++ b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Container.swift @@ -47,30 +47,28 @@ public extension SSPreferences { public var body: some View { let sections = sectionBuilder() + let labelWidth = max(minimumLabelWidth, maximumLabelWidth) return VStack(alignment: .preferenceSectionLabel) { ForEach(0 ..< sections.count, id: \.self) { index in - viewForSection(sections, index: index) + if sections[index].label != nil { + sections[index].bodyLimited(rightPaneWidth: contentWidth - labelWidth) + } else { + sections[index] + .alignmentGuide(.preferenceSectionLabel) { $0[.leading] + labelWidth } + } + if sections[index].bottomDivider, index < sections.count - 1 { + Divider() + .frame(height: 10) + .alignmentGuide(.preferenceSectionLabel) { $0[.leading] + labelWidth } + } } } .modifier(Section.LabelWidthModifier(maximumWidth: $maximumLabelWidth)) - .frame(width: Double(contentWidth), alignment: .leading) + .frame(width: contentWidth, alignment: .leading) .padding(.vertical, 20) .padding(.horizontal, 30) } - - @ViewBuilder - private func viewForSection(_ sections: [Section], index: Int) -> some View { - sections[index] - if index != sections.count - 1, sections[index].bottomDivider { - Divider() - // Strangely doesn't work without width being specified. Probably because of custom alignment. - .frame(width: Double(contentWidth), height: 20) - .alignmentGuide(.preferenceSectionLabel) { - $0[.leading] + Double(max(minimumLabelWidth, maximumLabelWidth)) - } - } - } } } diff --git a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Pane.swift b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Pane.swift index 3cec6bf5..434afb35 100755 --- a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Pane.swift +++ b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Pane.swift @@ -92,5 +92,6 @@ public extension View { font(.system(size: 11.0)) // TODO: Use `.foregroundStyle` when targeting macOS 12. .foregroundColor(.secondary) + .frame(maxWidth: .infinity, alignment: .leading) } } diff --git a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Section.swift b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Section.swift index f361feee..f236a61c 100755 --- a/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Section.swift +++ b/Packages/Sindresorhus_SSPreferences/Source/SSPreferences/Section.swift @@ -51,11 +51,33 @@ public extension SSPreferences { } } - public let label: AnyView + public private(set) var label: AnyView? public let content: AnyView public let bottomDivider: Bool public let verticalAlignment: VerticalAlignment + /** + A section is responsible for controlling a single preference without Label. + + - Parameters: + - bottomDivider: Whether to place a `Divider` after the section content. Default is `false`. + - verticalAlignement: The vertical alignment of the section content. + - verticalAlignment: + - label: A view describing preference handled by this section. + - content: A content view. + */ + public init( + bottomDivider: Bool = false, + verticalAlignment: VerticalAlignment = .firstTextBaseline, + @ViewBuilder content: @escaping () -> Content + ) { + label = nil + self.bottomDivider = bottomDivider + self.verticalAlignment = verticalAlignment + let stack = VStack(alignment: .leading) { content() } + self.content = stack.eraseToAnyView() + } + /** A section is responsible for controlling a single preference. @@ -92,33 +114,47 @@ public extension SSPreferences { - content: A content view. */ public init( - title: String, + title: String? = nil, bottomDivider: Bool = false, verticalAlignment: VerticalAlignment = .firstTextBaseline, @ViewBuilder content: @escaping () -> Content ) { - let textLabel = { - Text(title) - .font(.system(size: 13.0)) - .overlay(LabelOverlay()) - .eraseToAnyView() + if let title = title { + let textLabel = { + Text(title) + .font(.system(size: 13.0)) + .overlay(LabelOverlay()) + .eraseToAnyView() + } + self.init( + bottomDivider: bottomDivider, + verticalAlignment: verticalAlignment, + label: textLabel, + content: content + ) + return } - self.init( bottomDivider: bottomDivider, verticalAlignment: verticalAlignment, - label: textLabel, content: content ) } - public var body: some View { + public func bodyLimited(rightPaneWidth: CGFloat? = nil) -> some View { HStack(alignment: verticalAlignment) { - label - .alignmentGuide(.preferenceSectionLabel) { $0[.trailing] } - content - Spacer() + if let label = label { + label.alignmentGuide(.preferenceSectionLabel) { $0[.trailing] } + } + HStack { + content + Spacer() + }.frame(maxWidth: rightPaneWidth) } } + + public var body: some View { + bodyLimited() + } } }