-
Notifications
You must be signed in to change notification settings - Fork 95
feat: add NcFormGroup #7689
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
feat: add NcFormGroup #7689
Conversation
|
@kra-mo Currently the heading (legend, description) has 12px inline padding as per design. To be inline with elements having 8px border radius. So we can call it "Radius + 1 grid baseline". Is that correct and what is intended by the design? In thi case, we'll also adjust the field label paddings. |
a3b5a89 to
60a4400
Compare
|
I think it would be better to make the prop called either name or label and not introduce a third variant for the label of the element here ("legend") |
|
Unlike But I wouldn't call the Open for others' opinions. |
|
Nice, I'm really happy to see this :)
Do you mean to adjust the input fields' leading padding to match? Then yes, it should just be aligned.
Yes, I thought about this too, it makes total sense :)
Just so I understand: where would the PS: Not to encroach on your territory, but shouldn't the S in |
No, the question wasn't "should they be aligned" but is the margin supposed to be border radius + 1 grid baseline. I can see that it is 8 + 4 = 12px from the |
Okay, yes. 12px came from "it looked the best for fields both with and without a description" :) Border radius + 1 grid baseline makes sense for me to describe it if you think it does as well. |
This comment was marked as resolved.
This comment was marked as resolved.
And what I was mainly trying to say here was just that "it is not my territory, as long as it is aligned, I am happy" :) |
|
/backport to stable8 |
|
I think But I mean yes its technically a |
| legend = undefined, | ||
| description = undefined, | ||
| hideLegend = false, | ||
| hideDescription = false, | ||
| noGap = false, | ||
| } = defineProps<{ | ||
| /** | ||
| * Fieldset legend. #legend slot can be used for custom legend content | ||
| */ | ||
| legend?: string | ||
| /** | ||
| * Optional fieldset description. #description slot can be used for custom description content | ||
| */ | ||
| description?: string | ||
| /** | ||
| * Hide the legend visually but keep it accessible for screen readers | ||
| */ | ||
| hideLegend?: boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| legend = undefined, | |
| description = undefined, | |
| hideLegend = false, | |
| hideDescription = false, | |
| noGap = false, | |
| } = defineProps<{ | |
| /** | |
| * Fieldset legend. #legend slot can be used for custom legend content | |
| */ | |
| legend?: string | |
| /** | |
| * Optional fieldset description. #description slot can be used for custom description content | |
| */ | |
| description?: string | |
| /** | |
| * Hide the legend visually but keep it accessible for screen readers | |
| */ | |
| hideLegend?: boolean | |
| label = undefined, | |
| description = undefined, | |
| hideLabel = false, | |
| hideDescription = false, | |
| noGap = false, | |
| } = defineProps<{ | |
| /** | |
| * Label of the field set. `#label` slot can be used for custom formatted label content. | |
| */ | |
| label?: string | |
| /** | |
| * Optional fieldset description. #description slot can be used for custom description content | |
| */ | |
| description?: string | |
| /** | |
| * Hide the label visually but keep it accessible for screen readers | |
| */ | |
| hideLabel?: boolean |
| /** | ||
| * Disable default fieldset content gap between content elements | ||
| */ | ||
| noGap?: boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whats the use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General good practice for UI components — if a component has not only its own styles but also its position/content (its margin, slots styles) - it should be optional.
It could be a list of checkboxes without a gap, or some custom set of elements.
Alternative - ask to wrap content in a div.
| /** | ||
| * Custom legend content | ||
| */ | ||
| legend?: Slot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See other comment
| /** | |
| * Custom legend content | |
| */ | |
| legend?: Slot | |
| /** | |
| * Custom label content | |
| */ | |
| label?: Slot |
| <slot name="legend"> | ||
| {{ legend || '⚠️ Missing legend' }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
| <slot name="legend"> | |
| {{ legend || '⚠️ Missing legend' }} | |
| <slot name="label"> | |
| {{ label || '⚠️ Missing label' }} |
| <fieldset | ||
| :class="[$style.fieldset, { [$style.fieldset_noGap]: noGap }]" | ||
| :aria-describedby="getDescriptionId()"> | ||
| <legend :id="labelId" :class="[$style.fieldset__legend, { 'hidden-visually': hideLegend }]"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <legend :id="labelId" :class="[$style.fieldset__legend, { 'hidden-visually': hideLegend }]"> | |
| <legend :id="labelId" :class="[$style.fieldset__legend, { 'hidden-visually': hideLabel }]"> |
This comment was marked as resolved.
This comment was marked as resolved.
But the prop isn't for the end user, it is for the developers, and it represents If we consider |
This comment was marked as resolved.
This comment was marked as resolved.
End user is the developer in that case and API wise it makes sense to have a consistent way of naming instead of forcing the developer to think about that component is used behind and what special cases it has. We always use |
What about the second paragraph of the quoted comment? :) |
You mean:
Do you have a better name? I think Fieldset is quite easy to understand as a set of fields. |
I used If we consider |
As said its more about consistency, as a developer I expect API to be consistent. If other naming-elements are called The name of the component I do not really case as long as the use case is clear. |
also for #7690 : I am not sure the naming is good. Because its not really a group as a group would semantically require a name. I expected this component here ( I do not care about the actual name of the component, but they should be connected and represent their use case :) |
Me too. But "consistency" doesn't mean that the same world should be used everywhere. Here for consistency the prop was named |
b51138a to
5dae268
Compare
|
Rebased to have clean CI, no changes in the code |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #7689 +/- ##
==========================================
- Coverage 43.38% 43.32% -0.07%
==========================================
Files 277 279 +2
Lines 17990 18018 +28
Branches 1009 1011 +2
==========================================
+ Hits 7805 7806 +1
- Misses 10134 10160 +26
- Partials 51 52 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
But its basically a |
A reason — to not give one thing a name of another thing when having a component directly representing an existing element. Otherwise let's not call it a fieldset to not confuse with an existing element. |
I have no problem with a different component name, not as this is a quite generic component what do you think? |
I didn't understand what you mean here...
As was proposed - |
| :aria-describedby="getDescriptionId()"> | ||
| <legend :id="labelId" :class="[$style.fieldset__legend, { 'hidden-visually': hideLabel }]"> | ||
| <slot name="label"> | ||
| {{ label || '⚠️ Missing label' }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to always have a label? I can imagine a use-case like having a Fieldset inside a Modal which already has a title. I feel something might eventually come up where you would want to just not have a label, and having it show "Missing label" would be uncomfortable.
If we want to always have a standard label as a design decision though, I could understand it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to ask again:
Just so I understand: where would the FormGroup sit in the tree relative to individual fields and the Fieldset itself?
But from what I understand right now, from a design POV, there is definitely a case where there is no label, including in the mockups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to always have a label?
If its a fieldset we must. Its obligatory for wcag. If its only visually then its the form box not a real group.
GVodyanov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave design decisions to the team, but code-wise this looks really good!
As said I am 💯 for that name. Meaning form group and form box. |
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
5dae268 to
45c11ec
Compare
|
kra-mo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good :)
|
/backport to stable8 |


☑️ Resolves
<NcFieldset>component #7122<NcAppSettingsSection>NcFormBoxcomponentThe current solution has some
TODOs.🖼️ Screenshots
🏁 Checklist
stable8for maintained Vue 2 version or not applicable