<https://github.com/Chozzle/compose-macos-theme> J...
# compose-desktop
c
https://github.com/Chozzle/compose-macos-theme Just made this. Useful? I'm imagining doing the same for windows, then desktop UIs could share a lot of code.
šŸ‘ 15
j
IMO, if it is using or not a theme behind the hood, it should be not exposed to the user and the widgets should not use prefixes, because it is strange to mix multiple themes at same time in the same screen (even in the same app) If this is the case, using the import sample that I mentioned above should be the way to distinguish that the fact that we have two themes, and both have a
Button
composable, and in that screen/file both are used. The drawback is that if you have two themes in the app, in one screen you use material theme and in another screen you uses custom theme, you can't know without a Preview or checking the imports what theme you are using. But the fact that Material uses no prefixes indicates that it should be the way to go because they was using prefixes in the no compose Material Library and there must have been a detailed analysis to do this movement.
c
Yeah I think there is could be annoying for devs to keep double checking their imports. Even if I do hide Material components (I think they are in the current state of the library) I think it would be quite common for devs to add it themselves to use certain other features of Material. I used the current naming after reading this blog https://adambennett.dev/2020/12/migrating-your-design-system-to-jetpack-compose-part-2/. I'm also imagining devs importing a WindowsTheme and components, then creating wrappers on that called AcmeButton for example which do further customisation and also switch between components depending on the current platform. Potentially components like that which just handle the switching could be part of this library. Maybe these could be called AdaptiveButton, NativeButton or just Button as you would prefer. I'm really not sure what design to follow in that perspective and I'm open to more input.
Also flutter uses this naming approach for iOS style widgets. https://flutter.dev/docs/development/ui/widgets/cupertino I believe they call their material components Button since the large majority of developer will start with those components. They also probably want to promote their design language as the default.
j
The problem that you mentioned about some components can be incompatible in each platform, I think these components should have a different name, but the common components like could be a simple button should have the same name like material does. What I would expect some day supposing compose supports native platforms without JVM is playing with expect actual so a
Button
looks different if I am on Android, on Windows or on Mac. So a lib could provides a bridge for that three "commonMain" modules (material, macOS and Windows themes). Probably this can be done in JVM desktop apps injecting different themes based on the platform.
c
Yes I agree. I haven't reached the stage of creating common components yet tho. I think common components and more unique components like MacTabSelector would coexist in the same library, so behaviour that doesn't really translate similarly between platforms can be handled separately by the library consumer.
Great thread thanks for the link. Yes it seems like when this library handles switching between platforms, there would be a case for naming compnents simply like
Button
, however that could again interfere with consumers that want to name their components
Button
:/
j
But that problem could exist with foundation and material button too. It is strange than a user creates is custom button (without having a custom design for all the app) and the user names that button as button.
a
Over the years we had our design systems change profoundly at levels that feel fundamental, and that the design team feels are fundamental as well. Text is a great example. We spent many years on the android team serving the conflicting requirements of API compatibility, channeling developers to the intended UX designs by way of API shape, and keeping those API shapes and their behavior understandable
By pushing the "good" names up into the design libraries it offers the opportunity to wipe the slate clean for a new design system and essentially make breaking changes to fundamental APIs by way of namespacing
So yes, if you are writing a design library, take the good names! šŸ™‚
k
In the spirit of Material being a design system instead of the design system in Compose world. On one hand, Compose is a codename for a whole bunch of layers (aka Jake's post) starting from the compiler plugin to the declarative toolkit to a reactive model of propagating data changes to many other things, one of which happens to be the implementation of a specific design system in the
androidx.compose.material
package. It's quite convenient that the default Studio / IDEA project wizard adds the entirety of that as your dependencies without you having to manually list all the packages. It's also convenient that this UI toolkit has a collection of common components such as buttons, checkboxes, sliders and more. But on the other hand, I am not the biggest fan of the naming of these component composeables -
Button
,
Checkbox
etc. They are specific implementation of a design system - Material in this case. I'd rather have these components represent themselves as what they are - Material components. Not generic Compose components. But Material components. So
MaterialButton
instead of
Button
, etc.
The recommendation to app developers that find themselves in need of implementing their own design system should probably be to not wrap material components in their hierarchy, but rather reuse the lower level building blocks to create those components. That would prove the flexibility and the strength of Compose's UI toolkit part and all the layers that are underneath.
Another test of Material as well as other design systems in Compose would be how much work it is to build a component on "top" of them. So for example, if I want to build a date picker in Compose and make it look and feel seamless in my Material app, how much work is that? What can I reuse - components, colors, animation curves, paddings, etc. How much boilerplate do I need to copy from the internal implementation details of various modifiers to make my higher level component work?
Which brings another interesting point. If after some time we have N design systems for Compose, is there a place for cross-system components. For example, if I want to provide a radial menu, a lunar phase picker or a pivot grid, how do I make such a component play well (or at all) with all those N design systems? And if another design system is added, does that mean extra work for all such components?
c
Personally I found the Mac theme to be quite similar to Material, so wrapping Material was a shortcut that saved a lot of effort. I guess the negatives are library size and extra dependencies. On your last point, I'm also wondering if cross-platform components would be actually useful. These days there seems to be a trend to not use the native design system, but rather use the company design system across all platforms. I think if this library added cross-platform components it would stick with the more primitive ones like buttons / check boxes. The good news is Material and Mac theme seem to be converging (for now), so more things like this are possible.
I think for the purpose of this library the prefixes should stay. I think the ā€œtop levelā€ names like Button, Checkbox etc should ideally be used for the company design system, to allow them to switch easily between Material / Native theme / Company brand theme as they please. I realise that then you could be looking at a stack like:
Copy code
// The component actually used in app
Button { 
    NativeButton {
        when (platform) {
            Mac -> MacButton {
                Button // Material button
            }
            Windows -> WindowsButton {
                Button // Material
            }
        }
    }
}
But isn’t that the power of composition?
I also see what @Adam Powell is getting at, that there’s a good reason that material button is called Button. In the future google could switch design system completely to Fuschia for example, and they may want to to re-style the whole OS for API level 35 for example. Then devs just continue using Button, but google switches to the newer design system for them for API 35+. (aside from this being a nightmare to ensure a million app UIs don’t break, maybe this is a possible eventuality, since it happened with kitkat-lollipop)
k
There's an assumption here that all possible design systems are completely interchangeable, including their API signature surfaces.
āž• 1
c
Yeah for sure. That’s why I said it could be a nightmare. I bet no one at google looks forward to switching out Material šŸ˜„. Maybe it’ll never happen
a
It's happened twice already in Android: from the 2.3 theme to Holo, and then again to Material. Each time it was a breaking change where we needed an affirmative opt-in, but the API became a union of the available options by trying to keep the API "compatible" to the letter
Hence why the approach Compose is taking has the API reflect the design intent: a different design system fundamentally redefines what a "button" and its API surface is, and multiple systems must be able to coexist in the same app in an incremental migration
But while coexistence is supported, it's not necessarily the common use case. Usually when you want a button you don't need to see the name of your design system peppered across your source code text