naturalcrit / homebrewery

Create authentic looking D&D homebrews using only markdown
https://homebrewery.naturalcrit.com
MIT License
1.03k stars 316 forks source link

StringArrayEditor revision and update #3469

Open Gazook89 opened 1 month ago

Gazook89 commented 1 month ago

This is basically an implementation of what I wrote in #3466. It restructures the DOM of the StringArrayEditor and adds more functionality, such as better keyboard interaction. It removes what I consider "extra buttons" which I don't see used in many other tag editors/inputs. The styling is yet unfinished, but even at this stage is more inline with existing HB styling.

image

Keyboard

context action result
new text in new-tag-input, or editing existing tag , | Enter submits text as tag and focus new-tag-input
focus within tag-container (unless in input) ArrowLeft | ArrowRight moves focus left/right through tags and new-tag-input, within tagContainer
focus on existing tag Enter | Space open tag and focus input for editing
focus within input in tag or new-tag-input Escape blur/exit input without submitting, move focus to tag
focus on existing tag Delete delete existing tag
focus on element prior to tag-container Tab | Shift + Tab move focus to new-tag-input, skipping existing tags (instead, use arrow keys to navigate thru individual tags)

Things I want to hammer out:

Things I might want to do in this PR, but maybe not:

Things I might do if this PR is merged:

Related Issues:

 

Relevant PR:

https://github.com/naturalcrit/homebrewery/pull/3469

Gazook89 commented 1 month ago

It seems like most of the issue you have is with the datalist (justifiably). Rather than respond to each comment in the review, I'm just going to respond here.

I pretty much just went with what was outlined in #2335, particularly in terms of what options should be in the datalist but also the tiny bit of discussion about how such a long list should be handled. I agree the list is too long, and that such a long list can imply "choose one of these options" particularly without any prompt.

I like the suggestions above but have to think about them a little more.

In the meantime, I had another idea: what if we just used simple tags that aren't "compounds" of "meta:" + "blah" for the input, instead just using different tag input fields for those categories and then turn them into compound tags after entry...so the UI would look something like this:

image

Is this more intuitive, that there are categories of tags? And from this, each input area could have a datalist specific to that category. In our system, the tags would be stored as we have them now, meta:theme etc, and everywhere else that tags are displayed they would show like meta:theme, but in this particular UI where users are editing their tags it would be more structured.


Also mentioned in the linked Discussion is the tag input component from Mantine.dev which might save some hassle. Another one I was looking at is accessible-components/tag-input, preview here. Unfortunately Radix doesn't have a pre-made tag input nor do they really have a pre-made combobox.


I'll knock out a couple of the easy things you mentioned, push them up here, and by then hopefully have more thoughts on how to do the things asked above (or more ideas).

calculuschild commented 1 month ago

Is this more intuitive...

I see what you mean but I think the added clutter negates most of the benefit.

Gazook89 commented 1 month ago

yeah, and it would be a problem if for some reason more 'special' categories were added...you'd have to keep adding more inputs.

Another idea is to make each tag two inputs-- a dropdown for the tag scheme (meta, type, etc) and then a scheme-specific combobox. The left button throws a dropdown, and the chosen value determines which datalist is presented in the right-hand side combo input.

image

Further, it could still allow typing meta:theme in the right hand side for convenience, and on 'submission' would split the tag scheme portion to the left hand side (if valid). My example above should have a 'blank' option, as well. For regular tags, just type in the right-hand side.

The Author's StringArrayEditor/TagInput would still need to be more basic, so I'm not sure if the proposal above would just be a different component, or a configuration of the same component. But just throwing ideas out.

ericscheid commented 1 month ago

In the meantime, I had another idea: what if we just used simple tags that aren't "compounds" of "meta:" + "blah" for the input, instead just using different tag input fields for those categories and then turn them into compound tags after entry...so the UI would look something like this:

Additional to the clutter aspect, this creates the risk that a user will enter a tag into the wrong field. Compare the combo field, where typing "ad" filters the droplist to type:Adventure and also system:AD&D in the same droplist.

calculuschild commented 1 month ago

Another idea is to make each tag two inputs-- a dropdown for the tag scheme (meta, type, etc) and then a scheme-specific combobox. The left button throws a dropdown, and the chosen value determines which datalist is presented in the right-hand side combo input.

This is kind of along the lines of what I was thinking when I wrote "Is there any way to trim it [the datalist] down initially with just the major categories or something, and then transition to the full list once the user starts typing?" I.e. make the datalist a two-step process, first picking the scheme and second filling out the tag name. Though I only pictured it as one single textbox.

I am intrigued by this "dual-tag" approach. I say we give it a shot.

Gazook89 commented 1 month ago

Discussed briefly in gitter: going to move forward with working on something like the below. Likely I will use a library like FloatingUI to handle the anchor positioning of menus (skipping CSS Anchor API for now since it is only available in Chrome and I don't want broken menus in firefox). Likely I will be working on improving the Combobox.jsx component first, possibly splitting out the "datalist" portion as it's own thing which is then imported to combobox, and add a few props.

image

Styling isn't locked down at this point.