Add `TextEditor` implementation (#329)
* Add `TextEditor` implementation Resolves #173. * Clean up and bump requirements in the demo project * Use a single `_tokamak-formcontrol` CSS class * Add missing CSS class to `TextEditor.swift` Co-authored-by: Jed Fox <git@jedfox.com> Co-authored-by: Jed Fox <git@jedfox.com>
This commit is contained in:
parent
302cd3b108
commit
99581929a2
|
@ -43,6 +43,8 @@
|
||||||
B5DBA22C24D509B4003D3347 /* RedactDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBA22A24D509B4003D3347 /* RedactDemo.swift */; };
|
B5DBA22C24D509B4003D3347 /* RedactDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBA22A24D509B4003D3347 /* RedactDemo.swift */; };
|
||||||
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */; };
|
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */; };
|
||||||
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */; };
|
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */; };
|
||||||
|
D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */; };
|
||||||
|
D120FDDC257E7145008FFBAD /* TextEditorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */; };
|
||||||
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
||||||
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
||||||
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */; };
|
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */; };
|
||||||
|
@ -113,6 +115,7 @@
|
||||||
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppStorageDemo.swift; sourceTree = "<group>"; };
|
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppStorageDemo.swift; sourceTree = "<group>"; };
|
||||||
B5DBA22A24D509B4003D3347 /* RedactDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedactDemo.swift; sourceTree = "<group>"; };
|
B5DBA22A24D509B4003D3347 /* RedactDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedactDemo.swift; sourceTree = "<group>"; };
|
||||||
B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceKeyDemo.swift; sourceTree = "<group>"; };
|
B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceKeyDemo.swift; sourceTree = "<group>"; };
|
||||||
|
D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEditorDemo.swift; sourceTree = "<group>"; };
|
||||||
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListDemo.swift; sourceTree = "<group>"; };
|
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListDemo.swift; sourceTree = "<group>"; };
|
||||||
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutlineGroupDemo.swift; sourceTree = "<group>"; };
|
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutlineGroupDemo.swift; sourceTree = "<group>"; };
|
||||||
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonStyleDemo.swift; sourceTree = "<group>"; };
|
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonStyleDemo.swift; sourceTree = "<group>"; };
|
||||||
|
@ -179,6 +182,7 @@
|
||||||
85ED189924AD425E0085DFA0 /* TokamakDemo */ = {
|
85ED189924AD425E0085DFA0 /* TokamakDemo */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */,
|
||||||
D1D6B62224D817350041E1D9 /* GeometryReaderDemo.swift */,
|
D1D6B62224D817350041E1D9 /* GeometryReaderDemo.swift */,
|
||||||
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */,
|
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */,
|
||||||
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */,
|
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */,
|
||||||
|
@ -354,6 +358,7 @@
|
||||||
85ED18A324AD425E0085DFA0 /* SpacerDemo.swift in Sources */,
|
85ED18A324AD425E0085DFA0 /* SpacerDemo.swift in Sources */,
|
||||||
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */,
|
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */,
|
||||||
D1EE7EA724C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
D1EE7EA724C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
||||||
|
D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */,
|
||||||
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
|
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
|
||||||
8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
|
8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
|
||||||
85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
|
85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
|
||||||
|
@ -383,6 +388,7 @@
|
||||||
85ED18B024AD425E0085DFA0 /* EnvironmentDemo.swift in Sources */,
|
85ED18B024AD425E0085DFA0 /* EnvironmentDemo.swift in Sources */,
|
||||||
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */,
|
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */,
|
||||||
D1EE7EA824C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
D1EE7EA824C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
||||||
|
D120FDDC257E7145008FFBAD /* TextEditorDemo.swift in Sources */,
|
||||||
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
|
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
|
||||||
8500294024D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
|
8500294024D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
|
||||||
85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */,
|
85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */,
|
||||||
|
@ -546,7 +552,8 @@
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = "iOS Info.plist";
|
INFOPLIST_FILE = "iOS Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
|
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -572,7 +579,8 @@
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = "iOS Info.plist";
|
INFOPLIST_FILE = "iOS Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
|
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -604,6 +612,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
|
||||||
PRODUCT_NAME = "TokamakDemo Native";
|
PRODUCT_NAME = "TokamakDemo Native";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
@ -630,6 +639,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
|
||||||
PRODUCT_NAME = "TokamakDemo Native";
|
PRODUCT_NAME = "TokamakDemo Native";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|
|
@ -107,7 +107,8 @@ app.
|
||||||
|
|
||||||
## Requirements for app developers
|
## Requirements for app developers
|
||||||
|
|
||||||
- macOS 10.15 and Xcode 11.4 or later.
|
- macOS 10.15 and Xcode 11.4 or later. macOS 11.0 and Xcode 12.0 or later are required if you're
|
||||||
|
building a multi-platform app with Tokamak that also needs to support SwiftUI on macOS.
|
||||||
- [Swift 5.2 or later](https://swift.org/download/) and Ubuntu 18.04 if you'd like to use Linux.
|
- [Swift 5.2 or later](https://swift.org/download/) and Ubuntu 18.04 if you'd like to use Linux.
|
||||||
Other Linux distributions are currently not supported.
|
Other Linux distributions are currently not supported.
|
||||||
|
|
||||||
|
@ -204,7 +205,7 @@ doesn't provide an official build of the extension on the VSCode Marketplace unf
|
||||||
|
|
||||||
### Modular structure
|
### Modular structure
|
||||||
|
|
||||||
Tokamak is built with modularity in mind, providing a cross-platform `TokamakCore` module and
|
Tokamak is built with modularity in mind, providing a multi-platform `TokamakCore` module and
|
||||||
separate modules for platform-specific renderers. Currently, the only available renderer modules are
|
separate modules for platform-specific renderers. Currently, the only available renderer modules are
|
||||||
`TokamakDOM` and `TokamakStaticHTML`, the latter can be used for static websites and server-side
|
`TokamakDOM` and `TokamakStaticHTML`, the latter can be used for static websites and server-side
|
||||||
rendering. If you'd like to implement your own custom renderer, please refer to our [renderers
|
rendering. If you'd like to implement your own custom renderer, please refer to our [renderers
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2020 Tokamak contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
public struct TextEditor: View {
|
||||||
|
let textBinding: Binding<String>
|
||||||
|
|
||||||
|
public init(text: Binding<String>) {
|
||||||
|
textBinding = text
|
||||||
|
}
|
||||||
|
|
||||||
|
public var body: some View {
|
||||||
|
neverBody("TextEditor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct _TextEditorProxy {
|
||||||
|
public let subject: TextEditor
|
||||||
|
|
||||||
|
public init(_ subject: TextEditor) { self.subject = subject }
|
||||||
|
|
||||||
|
public var textBinding: Binding<String> { subject.textBinding }
|
||||||
|
}
|
|
@ -108,6 +108,7 @@ public typealias SecureField = TokamakCore.SecureField
|
||||||
public typealias Slider = TokamakCore.Slider
|
public typealias Slider = TokamakCore.Slider
|
||||||
public typealias Spacer = TokamakCore.Spacer
|
public typealias Spacer = TokamakCore.Spacer
|
||||||
public typealias Text = TokamakCore.Text
|
public typealias Text = TokamakCore.Text
|
||||||
|
public typealias TextEditor = TokamakCore.TextEditor
|
||||||
public typealias TextField = TokamakCore.TextField
|
public typealias TextField = TokamakCore.TextField
|
||||||
public typealias Toggle = TokamakCore.Toggle
|
public typealias Toggle = TokamakCore.Toggle
|
||||||
public typealias VStack = TokamakCore.VStack
|
public typealias VStack = TokamakCore.VStack
|
||||||
|
|
|
@ -21,7 +21,7 @@ extension _PickerContainer: ViewDeferredToRenderer {
|
||||||
AnyView(HTML("label") {
|
AnyView(HTML("label") {
|
||||||
label
|
label
|
||||||
Text(" ")
|
Text(" ")
|
||||||
DynamicHTML("select", ["class": "_tokamak-picker"], listeners: ["change": {
|
DynamicHTML("select", ["class": "_tokamak-formcontrol"], listeners: ["change": {
|
||||||
guard
|
guard
|
||||||
let valueString = $0.target.object!.value.string,
|
let valueString = $0.target.object!.value.string,
|
||||||
let value = Int(valueString) as? SelectionValue
|
let value = Int(valueString) as? SelectionValue
|
||||||
|
|
|
@ -24,7 +24,7 @@ extension SecureField: ViewDeferredToRenderer where Label == Text {
|
||||||
"type": "password",
|
"type": "password",
|
||||||
.value: proxy.textBinding.wrappedValue,
|
.value: proxy.textBinding.wrappedValue,
|
||||||
"placeholder": proxy.label.rawText,
|
"placeholder": proxy.label.rawText,
|
||||||
"class": "_tokamak-securefield",
|
"class": "_tokamak-formcontrol",
|
||||||
], listeners: [
|
], listeners: [
|
||||||
"keypress": { event in if event.key == "Enter" { proxy.onCommit() } },
|
"keypress": { event in if event.key == "Enter" { proxy.onCommit() } },
|
||||||
"input": { event in
|
"input": { event in
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2020 Tokamak contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import TokamakCore
|
||||||
|
|
||||||
|
extension TextEditor: ViewDeferredToRenderer {
|
||||||
|
public var deferredBody: AnyView {
|
||||||
|
let proxy = _TextEditorProxy(self)
|
||||||
|
|
||||||
|
return AnyView(DynamicHTML("textarea", [
|
||||||
|
"class": "_tokamak-formcontrol _tokamak-texteditor",
|
||||||
|
], listeners: [
|
||||||
|
"input": { event in
|
||||||
|
if let newValue = event.target.object?.value.string {
|
||||||
|
proxy.textBinding.wrappedValue = newValue
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,10 +32,8 @@ extension TextField: ViewDeferredToRenderer where Label == Text {
|
||||||
|
|
||||||
func className(for style: TextFieldStyle) -> String {
|
func className(for style: TextFieldStyle) -> String {
|
||||||
switch style {
|
switch style {
|
||||||
case is DefaultTextFieldStyle:
|
case is DefaultTextFieldStyle, is RoundedBorderTextFieldStyle:
|
||||||
return "_tokamak-textfield-default"
|
return "_tokamak-formcontrol"
|
||||||
case is RoundedBorderTextFieldStyle:
|
|
||||||
return "_tokamak-textfield-roundedborder"
|
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
import TokamakShim
|
import TokamakShim
|
||||||
|
|
||||||
@available(OSX 11.0, iOS 14.0, *)
|
|
||||||
struct AppStorageButtons: View {
|
struct AppStorageButtons: View {
|
||||||
@AppStorage("count") var count: Int = 0
|
@AppStorage("count") var count: Int = 0
|
||||||
@SceneStorage("count") var sceneCount: Int = 0
|
@SceneStorage("count") var sceneCount: Int = 0
|
||||||
|
@ -30,7 +29,6 @@ struct AppStorageButtons: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(OSX 11.0, iOS 14.0, *)
|
|
||||||
struct AppStorageDemo: View {
|
struct AppStorageDemo: View {
|
||||||
@AppStorage("count") var count: Int = 0
|
@AppStorage("count") var count: Int = 0
|
||||||
@SceneStorage("count") var sceneCount: Int = 0
|
@SceneStorage("count") var sceneCount: Int = 0
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
import TokamakShim
|
import TokamakShim
|
||||||
|
|
||||||
@available(OSX 10.16, iOS 14.0, *)
|
|
||||||
public struct GridDemo: View {
|
public struct GridDemo: View {
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
Group {
|
Group {
|
||||||
|
|
|
@ -23,7 +23,6 @@ struct File: Identifiable {
|
||||||
let children: [File]?
|
let children: [File]?
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(OSX 10.16, iOS 14.0, *)
|
|
||||||
struct OutlineGroupDemo: View {
|
struct OutlineGroupDemo: View {
|
||||||
let fs: [File] = [
|
let fs: [File] = [
|
||||||
.init(id: 0, name: "Users", children: [
|
.init(id: 0, name: "Users", children: [
|
||||||
|
|
|
@ -24,7 +24,6 @@ struct TestPreferenceKey: PreferenceKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 11, iOS 14, *)
|
|
||||||
struct PreferenceKeyDemo: View {
|
struct PreferenceKeyDemo: View {
|
||||||
@State private var testKeyValue: Color = .yellow
|
@State private var testKeyValue: Color = .yellow
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
@ -144,7 +143,6 @@ struct PreferenceKeyDemo: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 11, iOS 14, *)
|
|
||||||
extension PreferenceKeyDemo.SetColor where Content == EmptyView {
|
extension PreferenceKeyDemo.SetColor where Content == EmptyView {
|
||||||
init(_ level: Int, _ color: Color) {
|
init(_ level: Int, _ color: Color) {
|
||||||
self.init(level, color) { EmptyView() }
|
self.init(level, color) { EmptyView() }
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
import TokamakShim
|
import TokamakShim
|
||||||
|
|
||||||
@available(OSX 11.0, iOS 14.0, *)
|
|
||||||
struct RedactionDemo: View {
|
struct RedactionDemo: View {
|
||||||
func title(_ text: String) -> some View {
|
func title(_ text: String) -> some View {
|
||||||
Group {
|
Group {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2020 Tokamak contributors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import TokamakShim
|
||||||
|
|
||||||
|
struct TextEditorDemo: View {
|
||||||
|
@State var text = ""
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Text("Word count: \(text.split(separator: " ").count)")
|
||||||
|
TextEditor(text: $text)
|
||||||
|
.frame(width: 300, height: 300)
|
||||||
|
}
|
||||||
|
}
|
|
@ -128,6 +128,7 @@ struct TokamakDemoView: View {
|
||||||
Section(header: Text("Text")) {
|
Section(header: Text("Text")) {
|
||||||
NavItem("Text", destination: TextDemo())
|
NavItem("Text", destination: TextDemo())
|
||||||
NavItem("TextField", destination: TextFieldDemo())
|
NavItem("TextField", destination: TextFieldDemo())
|
||||||
|
NavItem("TextEditor", destination: TextEditorDemo())
|
||||||
}
|
}
|
||||||
Section(header: Text("Misc")) {
|
Section(header: Text("Misc")) {
|
||||||
NavItem("Path", destination: PathDemo())
|
NavItem("Path", destination: PathDemo())
|
||||||
|
|
|
@ -96,10 +96,7 @@ public let tokamakStyles = """
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
._tokamak-securefield,
|
._tokamak-formcontrol {
|
||||||
._tokamak-textfield-default,
|
|
||||||
._tokamak-textfield-roundedborder,
|
|
||||||
._tokamak-picker {
|
|
||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +104,11 @@ public let tokamakStyles = """
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
._tokamak-texteditor {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme:dark) {
|
@media (prefers-color-scheme:dark) {
|
||||||
._tokamak-text-redacted::after {
|
._tokamak-text-redacted::after {
|
||||||
background-color: rgb(100, 100, 100);
|
background-color: rgb(100, 100, 100);
|
||||||
|
|
|
@ -19,7 +19,7 @@ Table columns:
|
||||||
| 🚧 | [Text](https://developer.apple.com/documentation/swiftui/text) | |
|
| 🚧 | [Text](https://developer.apple.com/documentation/swiftui/text) | |
|
||||||
| 🚧 | [TextField](https://developer.apple.com/documentation/swiftui/textfield) | |
|
| 🚧 | [TextField](https://developer.apple.com/documentation/swiftui/textfield) | |
|
||||||
| 🚧 | [SecureField](https://developer.apple.com/documentation/swiftui/securefield) | |
|
| 🚧 | [SecureField](https://developer.apple.com/documentation/swiftui/securefield) | |
|
||||||
| | [TextEditor](https://developer.apple.com/documentation/swiftui/texteditor) | |
|
| ✅ | [TextEditor](https://developer.apple.com/documentation/swiftui/texteditor) | |
|
||||||
|
|
||||||
### Images
|
### Images
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ Table columns:
|
||||||
### Grids
|
### Grids
|
||||||
|
|
||||||
| | | |
|
| | | |
|
||||||
| --- | --------------------------------------------------------------------- | :-: |
|
| --- | ------------------------------------------------------------------------ | :-: |
|
||||||
| 🚧 | [LazyHGrid](https://developer.apple.com/documentation/swiftui/lazyhgrid) | |
|
| 🚧 | [LazyHGrid](https://developer.apple.com/documentation/swiftui/lazyhgrid) | |
|
||||||
| 🚧 | [LazyVGrid](https://developer.apple.com/documentation/swiftui/lazyvgrid) | |
|
| 🚧 | [LazyVGrid](https://developer.apple.com/documentation/swiftui/lazyvgrid) | |
|
||||||
| 🚧 | [GridItem](https://developer.apple.com/documentation/swiftui/griditem) | |
|
| 🚧 | [GridItem](https://developer.apple.com/documentation/swiftui/griditem) | |
|
||||||
|
@ -101,7 +101,7 @@ Table columns:
|
||||||
### Hierarchical Views
|
### Hierarchical Views
|
||||||
|
|
||||||
| | | |
|
| | | |
|
||||||
| --- | --------------------------------------------------------------------------------- | :-: |
|
| --- | ------------------------------------------------------------------------------------ | :-: |
|
||||||
| 🚧 | [OutlineGroup](https://developer.apple.com/documentation/swiftui/outlinegroup) | |
|
| 🚧 | [OutlineGroup](https://developer.apple.com/documentation/swiftui/outlinegroup) | |
|
||||||
| 🚧 | [DisclosureGroup](https://developer.apple.com/documentation/swiftui/disclosuregroup) | |
|
| 🚧 | [DisclosureGroup](https://developer.apple.com/documentation/swiftui/disclosuregroup) | |
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue