How to use spectrum web components in React starter template in UXP Photoshop plugin?

Hey, guys! Hope someone can give me some help with this issue…

I am developing Photoshop UXP plugin using ReactJS. I want to use some of the spectrum web components like search, tags, switch, etc. in React starter template plugin. How can I achieve this? Any sample with such spectrum web components will be appreciated.

Thanks in advance…

I think it was already answered to you :confused:

it seems that the link “it was already answered to you” is not working : any help ? Thanks
:

Short answer - neither React Spectrum nor Spectrum Web Components is supported in UXP. Only Spectrum UXP (which is an implementation of Spectrum Web Components) is supported.

Here’s @kerrishotts answer 1,5 years ago (maybe there’s some update?)

Thanks, so…no easy way to have an accordion in UXP plugin I suppose …

Depends on what’s easy for you :slight_smile: I would say accordion is quite easy to implement manually :slight_smile: You just gave me an idea for one of my plugins :smiley:

1 Like

Easy is almost nothing to me because I’m still learning the basics …

There are several ways to build an accordion – I think the one that requires the least amount of JS code is to use a checkbox that’s positioned off screen, which then controls the visibility of the content in the panel. You do all of that purely w/ CSS.

The Kitchen Sink in the uxp-6.0 branch of the plugin samples repo has an accordion example that uses this pattern.

  • CSS (You’ll probably need to adjust lines 1-7 & 45-50 to fit w/ your design & layout)
  • HTML

No JS required.

1 Like

Thanks a lot @kerrishotts I’ll have a look to it !

Thanks @kerrishotts it works perfectly and it was easy to add it to my code. The only problem is that i need the accordion-content NOT to be shown/hidden when the accordion-content itself is clicked. I need the accordion-content to be shown/hidden ONLY when the accordion itself is clicked . Referring to your Kitchen-Sink code (see example image below) i DON’T need the 3 buttons to be shown/hidden when the same area of the buttons is clicked. I need them to be shown/hidden only when the ‘detail’ row with the text ‘code’ or the arrows on the same line are clicked. Any suggestion ?

First, double check your HTML & CSS. The up/down chevrons should not be visible simultaneously. (These lines control this, but are dependent upon your HTML structure.)

image

Second, you’re going to have to get into a little bit of JS if you don’t want the content area to collapse the accordion. This should get you work for most cases:

document.querySelector(".accordion-content").addEventListener("click", evt => {
  evt.preventDefault();
});
1 Like

Thanks @kerrishotts. this solution works (in my code) only after the second time the .accordion-content is clicked, but the first time then the accordion.content is clicked the accordion content hidden

This make sense because the first time the .accordion-content is clicked the default has not yet been prevented through the querySelector, but it is not what I need. There is no way to prevent the default since the begining ?

Thanks
Daniele

The above evt.preventDefault() happens on the same event that’s triggering the closure – that is, it’s not setting a future preference, but applying only to the currently processing event.

Where are you executing the above code? It needs to be run after the DOM has the above accordion (otherwise querySelector() will return undefined, and an error throws), and before the user is going to start interacting with the panel. (It also only needs to happen once for that particular instance of accordion)

So – sequence:

  1. div.accordion-content is created in the DOM (in index.html is fine)
  2. above JS is executed (immediately after #1 above – so you probably want to wait for DOMContentLoaded or similar event – or just put the JS at the bottom of index.html)
  3. #1 and #2 have to happen before the user is going to start interacting with the element.

Thanks again @kerrishotts . I don’t want to bore you too much with specific issues of my code, however I have tried to implement the solution you suggested and it works but only on the first accordion of the series. In fact my panel contains a few containers with an accordion inside each container (see image) . The querySelector affects only the first accordion of the first container. I work in the React environment and I have inserted the code with the querySelector inside a UseEffect so that it is executed the first time the interface (containing all the containers) is rendered. I also tried to change the UseEffect so that it is executed everytime the interface is rendered but the result doesn’t change : the first accordion has the default properly prevented from the beginning, before the user interacts, but the second accordion doesn’t

querySelector only selects the first element that matches the selector. You can use querySelectorAll which will give you a NodeList. There might be a better way of doing this though, here are some thoughts:

  • If you want to access DOM elements in React, RefObjects (or RefCallbacks) are usually the better way and you don’t have to worry that much about whether the element has been created yet or not. Since you have a list of elements, here are examples of how to assign an array of Refs:javascript - How can I use multiple refs for an array of elements with hooks? - Stack Overflow
  • Since you’re using React, why not simply do <div onClick={e => e.preventDefault()}/> ?
  • In some cases, event propagation / bubbling between parent and child elements can also be prevented using just CSS via pointer-events: none. A consequence of that would be that the text inside the accordion can’t be highlighted anymore (or buttons not clicked etc.)
1 Like

thanks @simonhenke & @kerrishotts for helping me find the easiest solution :boom: :boom: :boom:, perhaps easy, but alone I would not have succeeded !

1 Like

Trying to implement accordion myself and once again headbanging into the limitations of UXP that even IE6 didn’t have IIRC.

Why can’t label and checkbox play properly together with for?

<input type="checkbox" id="check" />
<label htmlFor="check">Label</label>

Normally clicking on label should check the input:checkbox, but nothing happens :exploding_head:

Wrapping input elements inside label works:

<label>
  <input type="checkbox" />
  Label
</label>

I know this, but, to properly implement accordion without JS, this is not an option :frowning: Or, as you suggested previously, some workarounds with JS need to be done (again)

I assume the CSS selector is the issue due to nesting? What’s your HTML structure?