diff --git a/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj b/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj index dfa1aa227..5acbbc080 100644 --- a/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj +++ b/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 3DCDE44424CA6AD400910F17 /* SidebarDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */; }; 3DCDE44524CA6AD400910F17 /* SidebarDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */; }; + 4550BD5225B642B80088F4EA /* ShadowDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4550BD5125B642B80088F4EA /* ShadowDemo.swift */; }; + 4550BD5325B642B80088F4EA /* ShadowDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4550BD5125B642B80088F4EA /* ShadowDemo.swift */; }; 8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8500293E24D2FF3E001A2E84 /* SliderDemo.swift */; }; 8500294024D2FF3E001A2E84 /* SliderDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8500293E24D2FF3E001A2E84 /* SliderDemo.swift */; }; 854A1A9124B3E3630027BC32 /* ToggleDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */; }; @@ -91,6 +93,7 @@ /* Begin PBXFileReference section */ 3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SidebarDemo.swift; sourceTree = ""; }; + 4550BD5125B642B80088F4EA /* ShadowDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShadowDemo.swift; sourceTree = ""; }; 8500293E24D2FF3E001A2E84 /* SliderDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderDemo.swift; sourceTree = ""; }; 8587DF5524D4B9A40033EF43 /* TokamakDemo Native.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "TokamakDemo Native.entitlements"; sourceTree = ""; }; 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleDemo.swift; sourceTree = ""; }; @@ -204,6 +207,7 @@ 85ED189F24AD425E0085DFA0 /* TextFieldDemo.swift */, 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */, 85ED189D24AD425E0085DFA0 /* TokamakDemo.swift */, + 4550BD5125B642B80088F4EA /* ShadowDemo.swift */, ); name = TokamakDemo; path = ../Sources/TokamakDemo; @@ -361,6 +365,7 @@ D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */, B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */, 8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */, + 4550BD5225B642B80088F4EA /* ShadowDemo.swift in Sources */, 85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */, B5C76E4A24C73ED5003EABB2 /* AppStorageDemo.swift in Sources */, 3DCDE44424CA6AD400910F17 /* SidebarDemo.swift in Sources */, @@ -391,6 +396,7 @@ D120FDDC257E7145008FFBAD /* TextEditorDemo.swift in Sources */, B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */, 8500294024D2FF3E001A2E84 /* SliderDemo.swift in Sources */, + 4550BD5325B642B80088F4EA /* ShadowDemo.swift in Sources */, 85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */, B5C76E4B24C73ED5003EABB2 /* AppStorageDemo.swift in Sources */, 3DCDE44524CA6AD400910F17 /* SidebarDemo.swift in Sources */, diff --git a/Sources/TokamakCore/Modifiers/ShadowLayout.swift b/Sources/TokamakCore/Modifiers/ShadowLayout.swift new file mode 100644 index 000000000..b1de3ea34 --- /dev/null +++ b/Sources/TokamakCore/Modifiers/ShadowLayout.swift @@ -0,0 +1,26 @@ +public struct _ShadowLayout: ViewModifier, EnvironmentReader { + public var color: Color + public var radius: CGFloat + public var x: CGFloat + public var y: CGFloat + public var environment: EnvironmentValues! + + public func body(content: Content) -> some View { + content + } + + mutating func setContent(from values: EnvironmentValues) { + environment = values + } +} + +public extension View { + func shadow( + color: Color = Color(.sRGBLinear, white: 0, opacity: 0.33), + radius: CGFloat, + x: CGFloat = 0, + y: CGFloat = 0 + ) -> some View { + modifier(_ShadowLayout(color: color, radius: radius, x: x, y: y)) + } +} diff --git a/Sources/TokamakDemo/ShadowDemo.swift b/Sources/TokamakDemo/ShadowDemo.swift new file mode 100644 index 000000000..d328a6a33 --- /dev/null +++ b/Sources/TokamakDemo/ShadowDemo.swift @@ -0,0 +1,8 @@ +import TokamakShim + +struct ShadowDemo: View { + var body: some View { + Color.red.frame(width: 60, height: 60, alignment: .center) + .shadow(color: .black, radius: 5, x: 0, y: 10) + } +} diff --git a/Sources/TokamakDemo/TokamakDemo.swift b/Sources/TokamakDemo/TokamakDemo.swift index 6ea741061..2b50d7187 100644 --- a/Sources/TokamakDemo/TokamakDemo.swift +++ b/Sources/TokamakDemo/TokamakDemo.swift @@ -120,6 +120,9 @@ struct TokamakDemoView: View { }.padding(20)) NavItem("GeometryReader", destination: GeometryReaderDemo()) } + Section(header: Text("Modifiers")) { + NavItem("Shadow", destination: ShadowDemo()) + } Section(header: Text("Selectors")) { NavItem("Picker", destination: PickerDemo()) NavItem("Slider", destination: SliderDemo()) diff --git a/Sources/TokamakStaticHTML/Modifiers/LayoutModifiers.swift b/Sources/TokamakStaticHTML/Modifiers/LayoutModifiers.swift index 958efbef5..527d24cf8 100644 --- a/Sources/TokamakStaticHTML/Modifiers/LayoutModifiers.swift +++ b/Sources/TokamakStaticHTML/Modifiers/LayoutModifiers.swift @@ -101,3 +101,11 @@ extension _PaddingLayout: DOMViewModifier { .joined(separator: " ")] } } + +extension _ShadowLayout: DOMViewModifier { + public var attributes: [HTMLAttribute: String] { + ["style": "box-shadow: \(x)px \(y)px \(radius * 2)px 0px \(color.cssValue(environment));"] + } + + public var isOrderDependent: Bool { true } +}