WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.51k stars 4.2k forks source link

Add Box Shadow Component #44651

Closed phil-sola closed 5 months ago

phil-sola commented 2 years ago

What problem does this address?

So as of Gutenberg 14.1 and in the upcoming WordPress 6.1 release, there will be support added for themes to register box shadows for specific blocks within the theme.json file.

Similar to padding, margin, typography, etc. I feel like it would be beneficial to actually have a box shadow component either for importing from a package for custom blocks or supported in core blocks which would enable users to create the exact shadow effect they are looking for.

What is your proposed solution?

Adding a box-shadow component within one of the packages which can be imported for custom block development or supported in core blocks which would enable users to create the exact shadow effect they are looking for.

Something like the 'Customize shadows' section on the left in this link: (https://box-shadow.dev/)

Including horizontal, vertical, blur, spread, and colour.

I searched issues for 'box shadow' and 'box-shadow' and couldn't find anything on this, however, I know it might already be something being looked at, apologies if so.

Design

shadows

Tasks

Jabe64 commented 2 years ago

+1 for this 💯 It should be listed in #33447 too.

dkjensen commented 2 years ago

+1

jasmussen commented 1 year ago

Here's a first stab mockup for this, and I would love your feedback. Starting with the work outlined in #45507, I took a look at how this could exist on a per-block basis in Global Styles. I imagine it would exist as a control accessible via Blocks → Blockname:

Managing drop shadows in Global Styles

In the post editor, I would imagine shadows could live in a renamed "Border & Shadows" panel:

Shadows in the inspector

This is the panel that today is called "Border" and also contains "Radius.

From the above, I think putting the configuration of the shadow in a flyout works okay, as it allows space for controls and presets. However I don't particularly like the "Border & Shadow" title, even if conceptually it feels like the right place to put Shadow controls. What's a better name? "Effects"? "Shape"? Any other placements that make sense?

I also quite dislike the appearance of the shadow presets, I'll need to think about that one. Let me know your thoughts!

jasmussen commented 1 year ago

CC: @WordPress/gutenberg-design

paaljoachim commented 1 year ago

Hey Joen. It looks like a good start!

madhusudhand commented 1 year ago

@jasmussen Thanks for the designs. They look great!

I mocked up controls for Angle and Depth instead of X-position and Y-position, as that seems more ergonomic.

I like this idea and I would like to believe, a formula should transform these values to X,Y (apply in CSS) and also reverse transform them without issues. I will work on this transformation (formula) and provide more detailed feedback.

A preset shadow is applied by clicking the plus, this adds an Item on the right

I would like to imagine shadow presets to behave similar to colors. There would be Default Shadows (defined in Gutenberg) and Theme Shadows (defined in theme.json)

And a shadow preset could be a combination of multiple shadows that create a unique effect. e.g.

image

This is a result of two shadows box-shadow: 5px 5px 0px -2px #DDCFFF, 5px 5px #040DE1.

A theme should be able to define them in theme.json as follows.

{
    "settings": {
        "color": {},
        "shadows": [{
            "name": "Double lines",
            "slug": "double-lines",
            "value": "5px 5px 0px -2px #DDCFFF, 5px 5px #040DE1"
        }, {
            ...
        }]
    }
}

Long story short:

Because a preset can have multiple shadows and they become preset variables (based on the given slug), the UI experience for them should slightly be different.

Following are my thoughts:

image

This way, a preset shadow can be applied to any block and changing it in the global settings would effect all the blocks.

Let me know your thoughts.

jasmussen commented 1 year ago

I like this idea and I would like to believe, a formula should transform these values to X,Y (apply in CSS) and also reverse transform them without issues.

Thank you! If it becomes a headache, don't spend too much time on it, we can start simpler if need be. For example it hits me that it might not be possible to represent all box-shadow configurations with this setup, as the angle+depth components assume that the X and Y values will always be the same. We might need a different angle component, one that's more of a map/grid, for this to work 🤔

I would like to imagine shadow presets to behave similar to colors. There would be Default Shadows (defined in Gutenberg) and Theme Shadows (defined in theme.json) A theme should be able to define them in theme.json as follows.

Yes.

When a preset is clicked, it ads a single row (just like custom shadow), but it remains read-only

Thanks for surfacing this shortcoming. I don't think we should make a read-only preset, they should all be editable. But I'll need to think about how to best surface multiple stacked shadows in the panel when applying a preset. Let me return here with some new mockups!

There should be a new section under global styles, Styles -> Shadows (similar to editing the color palette) where they can be edited.

Working on this mockup made me realize a shortcoming of our current global styles. Right now you have Typography, Colors, Layout. Layout includes various values — margin and block spacing for Buttons, and border and border radius for Image. For both Typography and Color, these two blocks (Buttons, Image) have panel counterparts. But there's no counterpart in Global Styles for Dimensions and Border — those are put inside "Layout" instead.

And so I'm not sure we should add a new "Shadows" in Global Styles. I think we should either:

  1. Accept that Global Styles has a trio of Typography, Color, and Layout, and put "Shadows" under Layout.
  2. Change Global Styles so that it gets a new "Border & Shadows" section, as well as a "Dimensions" section, to match the panels present for each block. This would let the "Layout" section continue to exist for things like Group, which have a Layout panel, but it would also make the Layout section not become a junk drawer for things that don't fit in color or typography.

We should probably start with 1, as 2 has some compounding effects. What do you think?

jasmussen commented 1 year ago

Having tinkered a bit with this now, it's clear that approach I had thought of with regards to layered shadows that I was thinking of, inspired by #39427, is unlikely to work for stacked shadows for us. Quite simply, the fact that a preset can contain all stacks, means the UI to control each layer, would need to be surfaced in the flyout. I think I need to explore an entirely different approach to the presets, which as already noted, felt like the weakest aspect. I'll need more time to think on this.

One question — I really like this shadow generator, which creates 3 shadows by default. Would it be possible to have something like that for the default editor? Then perhaps we could put advanced editing of each individual layer behind an toggle, that would let you edit each layer individually? Essentially any non-standard preset, such as the sharp square shadow in your example, would then become an "advanced" shadow.

jasmussen commented 1 year ago

Based on explorations, I have some new concepts to share, that should hopefully be simpler for the first version.

I would imagine we could start with a preset-first design:

Managing drop shadows in Global Styles

A followup would be to enable shadows in the post editor:

Shadows in the inspector

Not for the first effort, but I think there's a fun opportunity tied to the UI for editing drop shadows. It is possible to create beautiful natural-looking shadows by stacking multiple shadows at various depths, and I would love for us to include an algorithm for doing this, which could potentially be controllable like this:

Longer term algo editing of shadows

It's not something for the near term, but once you're in the shadow editing control, we might as well provide excellent shadows by default.

What do you think? CC: @madhusudhand @scruffian

jameskoster commented 1 year ago

This seems to work well. We could even double-down further on the presets, and save the user a click by surfacing them in the + menu:

shadow

This may work best with a dedicated section, similar to Figma's "Effects" panel. Perhaps that's worth considering if we intend to support filters and other similar features in the future.

jasmussen commented 1 year ago

Nice, I can see further simplification work. Though I abandoned the idea of showing a shadow preset in that small 20x20 area in the ItemGroup, it simply didn't have space enough to be legible at that size, and there's a preview above, after all.

I'm not sure about the unlink, though: what what would the main action of the ItemGroup be?

paaljoachim commented 1 year ago

This looks really good!

jameskoster commented 1 year ago

I'm not sure about the unlink, though

I suppose an alternative would be a remove/delete action. But then you couldn't create a custom shadow from a preset base.

what what would the main action of the ItemGroup be?

Do you mean what happens on click? One option would be to just open the shadow menu:

Screenshot 2022-11-16 at 13 05 45
richtabor commented 1 year ago

I like the idea of presets as well — we use them for font sizes, spacing, colors... may as well for shadows. Any reason why we wouldn't reuse the existing stepped range control pattern? And if the icon is pressed, you see a detailed edit view of that preset — basically like how border controls work.

And second, if we wanted to merge some of these panels, we could package them as tool belt items in an "Effects" panel. Border would fit in well for example.

CleanShot 2022-11-16 at 11 23 47@2x

Also it doesn't have to be integer based (maybe the slugs are, but not the label).

jasmussen commented 1 year ago

I tend to think we should stick to the pattern of ItemGroups opening flyout menus, and since there's a preview in the canvas for the post editor, and in the top right of the inspector for global styles, the simple shadow icon feels like a better starting point to me. But perhaps we can follow the PR and see what feels right as we move closer?

And if the icon is pressed, you see a detailed edit view of that preset — basically like how border controls work.

Not sure I understand. Do you mean something like this?

control

While we could have presets inside that flyout, the unique challenge with shadows is that in theme.json you can apply a stacked shadow consisting of multiple separate definitions, and have that be a preset. That's why I ended up thinking the preset-first approach was the simplest way to start. Let me know if I missed a beat here!

Another aspect of the preset-first approach, is to enable the more creative uses of drop shadows like this example Madhu shared:

Any reason why we wouldn't reuse the existing stepped range control pattern?

My instinct would be that we need more finegrained control here. That said, I see where you're coming from — each step of the slider could theoretically represent a predefined elevation. It's the same instinct that led me towards this mockup, where I'm picturing each dot on the grid to be an "elevation slot", and then multiple stacked shadows are calculated based on the elevation, light position, and sliders. So you'd still have these predefined steps, but you'd also have directionality in the mix.

madhusudhand commented 1 year ago

Great designs! 🎆

image image

The dropdown of shadow presets is missing the theme presets. Can you accommodate both default and theme presets with labels may be?

And a question on how it should be invoked. All the style sections use ToolsPanel that comes with options such as reset styles on click of vertical dots

image

Do you suggest to have a + button beside it? or a label like Add shadow as one of the option?

jasmussen commented 1 year ago

@madhusudhand I'm not convinced we should go with the immediate dropdown, I still think it's best to use the ItemGroup with the flyout pattern that shows "Default" and "Theme" presets using the same buttons as are present in the Styles panel. We can omit the "Settings" icon for now though.

That would make the shadow control a single control for now, so not yet any stacked shadows. I'm unsure yet how to best surface such stacked shadows, but I'm leaning towards if we ever do that, it should probably be inside the flyout, because presets themselves can come as stacked definitions.

madhusudhand commented 1 year ago

That would make the shadow control a single control for now, so not yet any stacked shadows.

That will be a good start from UI perspective.

For context, a stacked shadow need not be always from a preset. A theme developer can define stacked shadow for a button only (not a theme preset) in theme.json and it is a custom stacked shadow. In such scenarios, how should we represent that a shadow is applied to the block?

image

In the first step, because edit controls aren't there, UI should somehow indicate that a custom shadow is applied, because setting it from theme.json is already possible.

Eventually, it should work bi-directional. Set a custom or preset shadow (single or stacked) from the UI. Parse a custom or preset shadow from theme.json and show in UI. Let users edit that.

I'm leaning towards if we ever do that, it should probably be inside the flyout, because presets themselves can come as stacked definitions.

I am not sure if it is best to edit the presets (global in nature) from button styles panel. User might think that shadow they are editing is for the button, but because the presets are global, they can effect all other blocks that are using it.

But in other perspective, a user might want to do minor tweaks to the preset shadow, and apply to the button. I guess, on edit, it is best if the preset is copied as custom shadow, and apply to the block.

I am thinking for color, I cannot change default or theme palette colors such as Primary from a button styles panel. I would have to edit them from global styles -> colors only because they effect everything.

jasmussen commented 1 year ago

For context, a stacked shadow need not be always from a preset. A theme developer can define stacked shadow for a button only (not a theme preset) in theme.json and it is a custom stacked shadow. In such scenarios, how should we represent that a shadow is applied to the block?

I'm assuming this shadow definition would come from theme.json directly? Good question. We probably need an interface for this, but for the near future, would it make sense to add a "Default" button to the "Theme" section, which embodied this?

I am not sure if it is best to edit the presets (global in nature) from button styles panel. User might think that shadow they are editing is for the button, but because the presets are global, they can effect all other blocks that are using it.

Oh I'm not talking about editing the presets here, that's probably a separate thing and more related to #44417. Let me know if I misunderstood something here.

So that is to say, I can understand we need to be able to both apply a preset to a block, and add an entirely custom shadow to a block, and that we need to be able to do this both locally on a per-block basis, and globally to apply by default across all buttons, for example. Right?

seothemes commented 1 year ago

This is looking really good. Here's a few important things to consider for box shadows that I haven't seen mentioned:

This a screen recording of how each is handled in the Blockify theme:

https://user-images.githubusercontent.com/24793388/204115242-45e7d3bf-550d-4207-972b-5779930f717c.mov

Changing just one of the values will enable a box shadow and inherit the remaining values from the theme. This also applies to the Hover state which inherits from the Default state for values that are not set.

We should also consider adding support for Inset values from the beginning too, as that could be difficult to add in the future.

madhusudhand commented 1 year ago

So that is to say, I can understand we need to be able to both apply a preset to a block, and add an entirely custom shadow to a block, and that we need to be able to do this both locally on a per-block basis, and globally to apply by default across all buttons, for example. Right?

Thats correct. It would be the final goal.

thongtr-dev commented 1 year ago

Found this issue while searching for something else. Coincidentally, I developed a small card block plugin that enable user to fully customize the box shadow property. The controls for box shadow looks like this:

screenshot-3

I know UI-wise it doesn't look good. But because we're talking about the box shadow component so maybe I can contribute something here.

Here is the plugin link: https://wordpress.org/plugins/card-block-with-box-shadow/.

annezazu commented 1 year ago

@madhusudhand - I see you are assigned here! Do you have a work in progress PR you can share or are you awaiting design based on the "needs design feedback" label? Asking because this is a part of the projects being tracked right now for https://github.com/WordPress/gutenberg/issues/33094 work and I wanted to see how best to update this issue.

madhusudhand commented 1 year ago

@annezazu created a first draft version of PR here #46502. It addresses the suggested design for presets. Once it lands, can iterate on adding support for custom shadows (needs further design discussion). For now turned the PR #45507 to draft state.

jasmussen commented 1 year ago

Thank you @madhusudhand, PR looks great. I left some feedback, but wasn't able to get the presets to show up. I'm happy to provide you with some default shadows for the presets as soon as I can get the branch to a testable state for me.

richtabor commented 1 year ago

We could leverage the existing color palette pattern; i.e. a palette of shadows (similar to @jameskoster's approach). And we may not need to separate the distinction from default and theme as well, similar to how spacing works.

Proposal

Of note: we'd need to clip the shadow, to reduce the likelihood of funky shadows bleeding far into the rest of the UI.

CleanShot 2023-01-19 at 15 25 32@2x

Other ideas

If the control could reference a background color applied to the block:

CleanShot 2023-01-19 at 15 27 01@2x
jameskoster commented 1 year ago

I think you still need the name to be visible somewhere. When the preview adopts the block background color (good idea btw) it's difficult to tell the difference between the first and third swatches.

Did you have any thoughts about how to detach from a present / create a custom shadow?

richtabor commented 1 year ago

it's difficult to tell the difference between the first and third swatches.

I think they're actually the same in this mockup. These shadows (https://github.com/WordPress/gutenberg/pull/46502#issuecomment-1397163520) are leading defaults imo. 😅

Did you have any thoughts about how to detach from a present / create a custom shadow?

I think explorations like suggested here: https://github.com/WordPress/gutenberg/issues/44651#issuecomment-1318277408

jasmussen commented 1 year ago

Thanks for all the explorations! Keep it going, this is getting better for it.

I do want to note a couple of important aspects to always keep in mind:

  1. eventually we will provide an editing interface for shadows, and those will likely be able to edit whatever shadows are surfaced as presets.
  2. eventually we will likely have more "effects" than just shadows. Not just counting inset shadows, but also things like backdrop filter, blur, etc.

And so it's important to not zoom in too closely on just the shadow aspects, and use all the available space in the inspector that is currently available. But think of this as the first of a series of effects that are likely to come.

richtabor commented 1 year ago

And so it's important to not zoom in too closely on just the shadow aspects, and use all the available space in the inspector that is currently available.

Perhaps there's merit in placing presets in the inspector (like suggested here), having a popover to further edit/extend the selected preset?

jasmussen commented 1 year ago

With the right UI, it could work, so long as it also affords a way to add a shadow in the future without starting first with a preset.

SaxonF commented 1 year ago

It's important we start to establish some consistent patterns when it comes to toggling between presets or custom, saving custom as a preset, and when to use a fly-out/popover vs adding inline controls.

A few examples:

Typography

image

Padding Same as typography

image

Colour

image

Shadow Ive seen two approaches presented in this thread.

The first is to allow preset selection inline via various methods (e.g. dropdown, radio group) and toggling to custom is also inline but triggers a fly-out.

image

The second is to include everything in fly-out much like colours.

image

There is a third option which might work for shadows and colour and that is to include toggle between preset/custom inline like other options but details are in fly-out.

image

image

It's worth deciding on and documenting some standards when it comes to

jasmussen commented 1 year ago

Definitely. In general, the flyouts can be useful when the control itself has the ability to become pretty complex, i.e. a gradient control or even color picker. For things like font size or line height, the slider has room to fit in the inspector and be ergonomic in that way.

As a sidenote, the Figma library recently had all its unpublished components published, meaning it's in a good place for a visual push. We have a lot of different components spread across a number of files exploring browse mode and otherwise, it might be good to collect them all and update the core library so we can use the same vernacular. There are some in this file that would be good to canonize.

aristath commented 1 year ago

An alternative suggestion for the UI: A few years ago, I built a customizer control for box-shadow. The x/y coordinates can be set using a draggable area, which will also give a more visual representation and feedback on what the user is doing:

https://user-images.githubusercontent.com/588688/214772756-51b96eb0-9fa5-4f32-a1c0-098b644941b9.mov

Instructions on how to test the implementation yourself:

  1. Download, install & activate this repo as a plugin: https://github.com/kirki-framework/control-box-shadow
  2. Add this code in a wp-content/mu-plugins/customizer.php file:

add_action( 'customize_register', function( $wp_customize ) { $wp_customize->add_setting( 'box_shadow_test', array( 'type' => 'theme_mod', // or 'option' 'capability' => 'edit_theme_options', 'sanitize_callback' => function( $val ) { return $val; }, 'default' => '0px 0px 0px 0px #000000', ) );

$wp_customize->add_control( new Kirki_Box_Shadow_Control( $wp_customize, 'box_shadow_test', array(
    'label'   => __( 'Box shadow test', 'theme_textdomain' ),
    'section' => 'title_tagline',
    'title'   => 'asddasd',
) ) );

}, 999 );

add_filter( 'kirki_box_shadow_control_url', function( $url ) { return 'http://localhost:8889/wp-content/plugins/control-box-shadow'; } );

jasmussen commented 1 year ago

Agreed, Ari, it would be nice with a visual dragging area, I had some similar ideas here. I tend to think we might want to start with less just to keep things simple, and then can upgrade to that.

@jameskoster I found in one of your Figma files a nice design for shadows, mind sharing it here?

jameskoster commented 1 year ago

Totally, here we go:

Shadow i2

The + button adds a shadow and opens a popover containing the preset options.

The selected option appears as a row in the Shadow panel. Clicking the row will toggle the visibility of the options popover. It also has two secondary actions:

When a custom shadow is used, it's possible to add more shadows, IE create box-shadow: <props>, <props>;. Each <props> instance appears in its own row, and on-click reveals the individual property controls in a popover.

One thing that's missing here is an affordance to create a new preset from a custom shadow definition. But I suspect that's okay to look at separately.

jasmussen commented 1 year ago

I'd love to see if the ItemGroup could be leveraged for the layers in the inspector, but that's a smaller thing. I like it.

jameskoster commented 1 year ago

It increases the footprint a bit, and breaks the alignment of the icons, but it can work 👍

Screenshot 2023-01-31 at 10 36 33
jasmussen commented 1 year ago

You're right, it's a bit tricky:

Mockup of options for including a minus button

Mainly without the boundaries it feels a bit like it's just noisy and sitting there. Especially in this color example. So the feedback is mainly about whether the control is conceptually similar to the ItemGroup, and if it is, maybe it should be one.

The minus on hover I don't hate.

jameskoster commented 1 year ago

Yes I think it should be an itemgroup. The Appearance is secondary and can be addressed holistically later. Showing the tools on hover could help reduce noise 👍

SaxonF commented 1 year ago

@jameskoster @jasmussen Mentioned here but is the unlink button a pattern we want to start using vs the existing toggle pattern?

image

If we wanted to stay consistent we could include toggle in shadow popover.

image

I don't feel too strongly either way but would be nice to form a consistent pattern when switching from preset -> custom and vice versa.

jasmussen commented 1 year ago

Mentioned https://github.com/WordPress/gutenberg/issues/44651#issuecomment-1399838132 but is the unlink button a pattern we want to start using vs the existing toggle pattern?

A big maybe to that one. I feel like for the typography, the settings icon still makes sense. Plus if we do explore "typography presets" in the future (i.e. a single preset that includes font, style, size, letter spacing, globally edited, etc.) I suspect that will be a new control, perhaps item-group-like, which could then benefit from the unlink control.

jameskoster commented 1 year ago

If we wanted to stay consistent we could include toggle in shadow popover.

The challenge with this approach is that the popover really struggles to accommodate multiple shadows (box-shadow: <props>, <props>).

The settings-icon-pattern is generally used as a two way toggle. IE click once to disable the preset then click again to re-enable. That's not really the flow here, instead of toggling it's more about total detachment from the preset. The unlink icon may not be the best, but I feel we need something other than the Settings icon because of the slightly different UX.

SaxonF commented 1 year ago

The challenge with this approach is that the popover really struggles to accommodate multiple shadows

You'd still be able to stack shadows like in your example. The only change really is adding toggle to the popup. Asking partly because there isn't a way to change back to a preset with the detach pattern. Figma has a "style" button after detaching to "reattach" if needed. Maybe that isn't a concern in this case though since you can remove then re-add.

jameskoster commented 1 year ago

Perhaps I'm missing something obvious, but in your suggestion, what does the popover display when you click the settings icon to detach from the preset, when the preset itself contains multiple props?

madhusudhand commented 1 year ago

The + button adds a shadow and opens a popover containing the preset options.

Following is the existing behaviour of the tools panel when the attribute hasMenuItems={false} is set.

tools-panel

Unlike the suggested UX, there is an additional click required to add an item. On click of + it invokes menu because the panel supports multiple items. This can be changed to directly add the item when there is only single item to avoid additional click.

Please share your thoughts.

jameskoster commented 1 year ago

This can be changed to directly add the item when there is only single item to avoid additional click.

That seems sensible, and probably worth a try.

annezazu commented 1 year ago

Reading through this thread and in trying to get an update for the phase 2 issue, I'm trying to get a sense of where we're at with this work. For 6.2, it's clear we've added support via theme.json along with four default box shadow options in Styles for the button block. However, the general component seems to need more finalized design efforts as mainly explorations have been shared here but I'm still seeing the "needs design feedback label" and am not seeing an update to the issue indicating a finalized design for a dev to dive in. What remains is bringing this out of an isolated Styles experience and into a more true "component" style interaction, like padding.

Is that correct? If not, please let me know so we can ensure work continues as expected.

annezazu commented 1 year ago

@jasmussen I can't seem to add this to the 6.3 Design board: https://github.com/orgs/WordPress/projects/82/views/1 Mind adding it? It's unclear where this work stands but it seems like a design review is needed at the least to confirm where devs can dive in next.

ndiego commented 1 year ago

Hey team, just checking in as this issue is on the 6.3 Project Board, and I do not see any recent activity. Are we still aiming for 6.3 with this? Beta 1 is in two weeks. If not, I will remove it from the board. Thanks!