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

How to apply modifier to button? #152

Open
alelordelo opened this issue Feb 29, 2024 · 7 comments
Open

How to apply modifier to button? #152

alelordelo opened this issue Feb 29, 2024 · 7 comments
Labels
discussion Discussions not yet turned into an action

Comments

@alelordelo
Copy link

On the code bellow, I can apply a modifier to the buttonStyle:

.buttonStyle(.plain)

//
//  RichTextActionButton.swift
//  RichTextKit
//
//  Created by Daniel Saidi on 2022-12-08.
//  Copyright © 2022-2024 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextAction {

    /**
     This button can be used to trigger a ``RichTextAction``.

     This renders a plain `Button`, which means that you can
     use and configure it as a normal button.
     */
    struct Button: View {
        /**
         Create a rich text action button.

         - Parameters:
           - action: The action to trigger.
           - context: The context to affect.
           - fillVertically: WhetherP or not fill up vertical space, by default `false`.
         */
        public init(
            action: RichTextAction,
            context: RichTextContext,
            fillVertically: Bool = false
        ) {
            self.action = action
            self._context = ObservedObject(wrappedValue: context)
            self.fillVertically = fillVertically
        }

        private let action: RichTextAction
        private let fillVertically: Bool

        @ObservedObject
        private var context: RichTextCo
<img width="1252" alt="Screenshot 2024-02-29 at 18 12 23" src="https://github.com/danielsaidi/RichTextKit/assets/17708751/5655f55d-a7c0-43ec-b82a-e6d8bf840727">
ntext

        public var body: some View {
            SwiftUI.Button(action: triggerAction) {
                action.label
                    .labelStyle(.iconOnly)
                    .frame(maxHeight: fillVertically ? .infinity : nil)
                    .contentShape(Rectangle())
            }
            .buttonStyle(.plain)

            .keyboardShortcut(for: action)
            .disabled(!context.canHandle(action))
        }
        
    }
}

It gets added to the preview:
Screenshot 2024-02-29 at 18 12 23
Screenshot 2024-02-29 at 18 12 12

But when I build the app, it shows the default button style.
Screenshot 2024-02-29 at 18 17 01

How can I apply a modifier and change the button style?

@DominikBucher12
Copy link
Collaborator

hello @alelordelo

are you sure its the background of the button and not RichTextStyle.ToggleStack? Btw I strongly encourage you not to modify the already existing components, which are made for pure sdk usage but rather use custom buttons and stacks which suits your need.

Snímek obrazovky 2024-02-29 v 23 02 39

For iOS:

Inside RichTextStyle+ToggleStack.swift:

 public var body: some View {
            HStack(spacing: spacing) {
                ForEach(styles) {
                    RichTextStyle.Toggle(
                        style: $0,
                        context: context,
                        fillVertically: true
                    )
                }
            }
           >>>>>>> .background(.green) // This line of code.
            .fixedSize(horizontal: false, vertical: true)
        }

For macOS:

in RichTextStyle+ToggleGroup.swift

 public var body: some View {
            #if macOS
            ControlGroup {
                ForEach(styles) {
                    RichTextStyle.Toggle(
                        style: $0,
                        context: context,
                        fillVertically: true
                    )
                }
            }
          >>>>>>>>>>>  .controlGroupStyle(.navigation) // insert different style.
            .frame(width: groupWidth)
            #else
            RichTextStyle.ToggleStack(
                context: context,
                styles: styles
            )
            #endif
        }
    }

Together with your button change, otherwise this happens:
Snímek obrazovky 2024-02-29 v 23 10 38

Hope this helps and let me know if I can close this issue :)

@DominikBucher12 DominikBucher12 added the misc A little bit of this, a little bit of that label Feb 29, 2024
@danielsaidi
Copy link
Owner

I will introduce a style concept in later versions, where we'll be able to inject library-specific styles into the environment. Button styles won't work consistently, since some component needs to apply specific button styles within the components.

@danielsaidi danielsaidi added discussion Discussions not yet turned into an action and removed misc A little bit of this, a little bit of that labels Mar 1, 2024
@alelordelo
Copy link
Author

alelordelo commented Mar 1, 2024

_Btw I strongly encourage you not to modify the already existing components, which are made for pure sdk usage but rather use custom buttons and stacks which suits your need.__
But is there a way to set a SwiftUI button style (not custom style) at the library level (not modifying library internally)?

__are you sure its the background of the button and not RichTextStyle.ToggleStack?_
I need to set all buttons as .buttonStyle(.plain) (not change its background) to match all the other buttons I have. I am going thought all buttons internally and setting to .buttonStyle(.plain)

All of them change on Xcode preview when I set to .buttonStyle(.plain).
But some change when I build the app, and some not, ex:

Here I changed the Toggle:

        private var toggle: some View {
            SwiftUI.Toggle(isOn: value) {
                style.icon
                    .frame(maxHeight: fillVertically ? .infinity : nil)
            }        .buttonStyle(.plain)

            .keyboardShortcut(for: style)
            .accessibilityLabel(style.title)
        }
Screenshot 2024-03-01 at 10 11 22

Google change is not reflected on the app, while the Font picker is:
Screenshot 2024-03-01 at 10 07 20

@DominikBucher12
Copy link
Collaborator

DominikBucher12 commented Mar 1, 2024

I strongly believe the API of the RichTextKit (at least the core part) is so scalable, that it is easier (and more convenient) for API consumers not to use and try to modify the existing components but to create their own SwiftUI components where they inject just the context as ObservableObject and do the toggling on their own.

In my other project, I created custom toolbar which accept the context and basically observes the context and I can have even progressView or something else which on each value of the slider, can have different attribute for the range.

If you can wait, I will create Demo example and post it in here (or in the project) with description how to use context in order to create Api-Consumer UIViews.

but the basic idea is:

public struct MyCustomRichTextView: View {
    @State private var text: NSAttributedString
    @State private var context: RichTextContext
    private let configuration: RichTextView.Configuration
    private let theme: RichTextView.Theme
    private let subtitle: String?

    public var body: some View {
        VStack {
                RichTextEditor(
                    text: $text,
                    context: context,
                    config: .standard,
                    theme: theme,
                    format: .rtf
                )
                .cornerRadius(8)
                .clipped()
                 MyCustomCommandView(context: context)
        }
    }

where:
MyCustomCommandView(context: context) is your implementation with custom buttons etc reacting to context changes...

ANYWAY!

All possibilities.

  1. Copy the library to be under your control and modify the internals on your own, having 100% control of the library... if you are wanting to change just the simple styles and keep it that way, I see this as a good fit. But the big downside of this is that it might break later because of Library updates + new features, so this seems not scalable for you
  2. Create a PR with changes (injecting viewStyle to SwiftUI Views) as I am currently busy with TextKit/Texkit2 + Bullet points and want really to finish links, I do not have time for supporting this UI, but I am happy to review
  3. Implement your custom UI with context injection as suggested.
  4. Wait for this issue (as clearly I do not see it as priority right no, dunno about @danielsaidi ) to be resolved by us.

Hope this helps!

@alelordelo
Copy link
Author

Thanks again @DominikBucher12 !

1 - this is what I am doing atm. But there are so many layers of abstraction that even applying a simple button modifier is super hard.
The example above worked for some buttons, not not to others. Any idea why?

3- would be super helpful if you can point how to inject a button modifier for ex.

@alelordelo
Copy link
Author

IMG_0882

@danielsaidi
Copy link
Owner

How are we on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Discussions not yet turned into an action
Projects
None yet
Development

No branches or pull requests

3 participants