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

Add TextEditor implementation #329

Merged
merged 4 commits into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
14 changes: 12 additions & 2 deletions NativeDemo/TokamakDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
B5DBA22C24D509B4003D3347 /* RedactDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBA22A24D509B4003D3347 /* RedactDemo.swift */; };
B5F2BE032571443D00FB3653 /* 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 */; };
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */; };
Expand Down Expand Up @@ -113,6 +115,7 @@
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>"; };
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>"; };
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>"; };
Expand Down Expand Up @@ -179,6 +182,7 @@
85ED189924AD425E0085DFA0 /* TokamakDemo */ = {
isa = PBXGroup;
children = (
D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */,
D1D6B62224D817350041E1D9 /* GeometryReaderDemo.swift */,
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */,
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */,
Expand Down Expand Up @@ -354,6 +358,7 @@
85ED18A324AD425E0085DFA0 /* SpacerDemo.swift in Sources */,
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */,
D1EE7EA724C0DD2100C0D127 /* PickerDemo.swift in Sources */,
D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */,
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
Expand Down Expand Up @@ -383,6 +388,7 @@
85ED18B024AD425E0085DFA0 /* EnvironmentDemo.swift in Sources */,
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */,
D1EE7EA824C0DD2100C0D127 /* PickerDemo.swift in Sources */,
D120FDDC257E7145008FFBAD /* TextEditorDemo.swift in Sources */,
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
8500294024D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */,
Expand Down Expand Up @@ -546,7 +552,8 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
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 = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -572,7 +579,8 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
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 = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -604,6 +612,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
PRODUCT_NAME = "TokamakDemo Native";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -630,6 +639,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "dev.tokamak.Tokamak-Native";
PRODUCT_NAME = "TokamakDemo Native";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ app.

## 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.
Other Linux distributions are currently not supported.

Expand Down Expand Up @@ -204,7 +205,7 @@ doesn't provide an official build of the extension on the VSCode Marketplace unf

### 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
`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
Expand Down
33 changes: 33 additions & 0 deletions Sources/TokamakCore/Views/Text/TextEditor.swift
Original file line number Diff line number Diff line change
@@ -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 }
}
1 change: 1 addition & 0 deletions Sources/TokamakDOM/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public typealias SecureField = TokamakCore.SecureField
public typealias Slider = TokamakCore.Slider
public typealias Spacer = TokamakCore.Spacer
public typealias Text = TokamakCore.Text
public typealias TextEditor = TokamakCore.TextEditor
public typealias TextField = TokamakCore.TextField
public typealias Toggle = TokamakCore.Toggle
public typealias VStack = TokamakCore.VStack
Expand Down
2 changes: 1 addition & 1 deletion Sources/TokamakDOM/Views/Selectors/Picker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extension _PickerContainer: ViewDeferredToRenderer {
AnyView(HTML("label") {
label
Text(" ")
DynamicHTML("select", ["class": "_tokamak-picker"], listeners: ["change": {
DynamicHTML("select", ["class": "_tokamak-formcontrol"], listeners: ["change": {
guard
let valueString = $0.target.object!.value.string,
let value = Int(valueString) as? SelectionValue
Expand Down
2 changes: 1 addition & 1 deletion Sources/TokamakDOM/Views/Text/SecureField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension SecureField: ViewDeferredToRenderer where Label == Text {
"type": "password",
.value: proxy.textBinding.wrappedValue,
"placeholder": proxy.label.rawText,
"class": "_tokamak-securefield",
"class": "_tokamak-formcontrol",
], listeners: [
"keypress": { event in if event.key == "Enter" { proxy.onCommit() } },
"input": { event in
Expand Down
31 changes: 31 additions & 0 deletions Sources/TokamakDOM/Views/Text/TextEditor.swift
Original file line number Diff line number Diff line change
@@ -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",
MaxDesiatov marked this conversation as resolved.
Show resolved Hide resolved
], listeners: [
"input": { event in
if let newValue = event.target.object?.value.string {
proxy.textBinding.wrappedValue = newValue
}
},
]))
}
}
6 changes: 2 additions & 4 deletions Sources/TokamakDOM/Views/Text/TextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ extension TextField: ViewDeferredToRenderer where Label == Text {

func className(for style: TextFieldStyle) -> String {
switch style {
case is DefaultTextFieldStyle:
return "_tokamak-textfield-default"
case is RoundedBorderTextFieldStyle:
return "_tokamak-textfield-roundedborder"
case is DefaultTextFieldStyle, is RoundedBorderTextFieldStyle:
return "_tokamak-formcontrol"
default:
return ""
}
Expand Down
2 changes: 0 additions & 2 deletions Sources/TokamakDemo/AppStorageDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import TokamakShim

@available(OSX 11.0, iOS 14.0, *)
struct AppStorageButtons: View {
@AppStorage("count") var count: Int = 0
@SceneStorage("count") var sceneCount: Int = 0
Expand All @@ -30,7 +29,6 @@ struct AppStorageButtons: View {
}
}

@available(OSX 11.0, iOS 14.0, *)
struct AppStorageDemo: View {
@AppStorage("count") var count: Int = 0
@SceneStorage("count") var sceneCount: Int = 0
Expand Down
1 change: 0 additions & 1 deletion Sources/TokamakDemo/GridDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import TokamakShim

@available(OSX 10.16, iOS 14.0, *)
public struct GridDemo: View {
public var body: some View {
Group {
Expand Down
1 change: 0 additions & 1 deletion Sources/TokamakDemo/OutlineGroupDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct File: Identifiable {
let children: [File]?
}

@available(OSX 10.16, iOS 14.0, *)
struct OutlineGroupDemo: View {
let fs: [File] = [
.init(id: 0, name: "Users", children: [
Expand Down
2 changes: 0 additions & 2 deletions Sources/TokamakDemo/PreferenceKeyDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ struct TestPreferenceKey: PreferenceKey {
}
}

@available(macOS 11, iOS 14, *)
struct PreferenceKeyDemo: View {
@State private var testKeyValue: Color = .yellow
@Environment(\.colorScheme) var colorScheme
Expand Down Expand Up @@ -144,7 +143,6 @@ struct PreferenceKeyDemo: View {
}
}

@available(macOS 11, iOS 14, *)
extension PreferenceKeyDemo.SetColor where Content == EmptyView {
init(_ level: Int, _ color: Color) {
self.init(level, color) { EmptyView() }
Expand Down
1 change: 0 additions & 1 deletion Sources/TokamakDemo/RedactDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import TokamakShim

@available(OSX 11.0, iOS 14.0, *)
struct RedactionDemo: View {
func title(_ text: String) -> some View {
Group {
Expand Down
25 changes: 25 additions & 0 deletions Sources/TokamakDemo/TextEditorDemo.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
1 change: 1 addition & 0 deletions Sources/TokamakDemo/TokamakDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct TokamakDemoView: View {
Section(header: Text("Text")) {
NavItem("Text", destination: TextDemo())
NavItem("TextField", destination: TextFieldDemo())
NavItem("TextEditor", destination: TextEditorDemo())
}
Section(header: Text("Misc")) {
NavItem("Path", destination: PathDemo())
Expand Down
10 changes: 6 additions & 4 deletions Sources/TokamakStaticHTML/Resources/TokamakStyles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,19 @@ public let tokamakStyles = """
height: 100%;
}

._tokamak-securefield,
._tokamak-textfield-default,
._tokamak-textfield-roundedborder,
._tokamak-picker {
._tokamak-formcontrol {
color-scheme: light dark;
}

._tokamak-link {
text-decoration: none;
}

._tokamak-texteditor {
width: 100%;
height: 100%;
}

@media (prefers-color-scheme:dark) {
._tokamak-text-redacted::after {
background-color: rgb(100, 100, 100);
Expand Down
34 changes: 17 additions & 17 deletions docs/progress.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Table columns:
| 🚧 | [Text](https://developer.apple.com/documentation/swiftui/text) | |
| 🚧 | [TextField](https://developer.apple.com/documentation/swiftui/textfield) | |
| 🚧 | [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

Expand Down Expand Up @@ -51,12 +51,12 @@ Table columns:

### Value Indicators

| | | |
|--- | ------------------------------------------------------------------------------ | :-: |
| | [ProgressView](https://developer.apple.com/documentation/swiftui/progressview) | |
| | [Gauge](https://developer.apple.com/documentation/swiftui/gauge) | |
| | [Label](https://developer.apple.com/documentation/swiftui/label) | |
| ✅ | [Link](https://developer.apple.com/documentation/swiftui/link) | |
| | | |
| --- | ------------------------------------------------------------------------------ | :-: |
| | [ProgressView](https://developer.apple.com/documentation/swiftui/progressview) | |
| | [Gauge](https://developer.apple.com/documentation/swiftui/gauge) | |
| | [Label](https://developer.apple.com/documentation/swiftui/label) | |
| ✅ | [Link](https://developer.apple.com/documentation/swiftui/link) | |

## View Layout and Presentation

Expand All @@ -72,11 +72,11 @@ Table columns:

### Grids

| | | |
| --- | --------------------------------------------------------------------- | :-: |
|🚧| [LazyHGrid](https://developer.apple.com/documentation/swiftui/lazyhgrid) | |
|🚧| [LazyVGrid](https://developer.apple.com/documentation/swiftui/lazyvgrid) | |
|🚧| [GridItem](https://developer.apple.com/documentation/swiftui/griditem) | |
| | | |
| --- | ------------------------------------------------------------------------ | :-: |
| 🚧 | [LazyHGrid](https://developer.apple.com/documentation/swiftui/lazyhgrid) | |
| 🚧 | [LazyVGrid](https://developer.apple.com/documentation/swiftui/lazyvgrid) | |
| 🚧 | [GridItem](https://developer.apple.com/documentation/swiftui/griditem) | |

### Lists and Scroll Views

Expand All @@ -96,14 +96,14 @@ Table columns:
| | [Form](https://developer.apple.com/documentation/swiftui/form) | |
| ✅ | [Group](https://developer.apple.com/documentation/swiftui/group) | |
| | [GroupBox](https://developer.apple.com/documentation/swiftui/groupbox) | |
| 🚧 | [Section](https://developer.apple.com/documentation/swiftui/section) | |
| 🚧 | [Section](https://developer.apple.com/documentation/swiftui/section) | |

### Hierarchical Views

| | | |
| --- | --------------------------------------------------------------------------------- | :-: |
|🚧| [OutlineGroup](https://developer.apple.com/documentation/swiftui/outlinegroup) | |
|🚧| [DisclosureGroup](https://developer.apple.com/documentation/swiftui/disclosuregroup) | |
| | | |
| --- | ------------------------------------------------------------------------------------ | :-: |
| 🚧 | [OutlineGroup](https://developer.apple.com/documentation/swiftui/outlinegroup) | |
| 🚧 | [DisclosureGroup](https://developer.apple.com/documentation/swiftui/disclosuregroup) | |

### Spacers and Dividers

Expand Down