GAUD-10044: Create FormElementContainerMixin mixin#7016
Conversation
- Handles the use case for nested form container components that are not also a form controller - Adds unit test - Updates the demo page to demonstrate this new behavior
|
Thanks for the PR! 🎉 We've deployed an automatic preview for this PR - you can see your changes here:
Note The build needs to finish before your changes are deployed. |
There was a problem hiding this comment.
This change in combination with the changes at components/form/form-helper.js is how now the form is able to "find" these custom form element containers
…data section, reuses the input and input label styles
| @@ -1,9 +1,11 @@ | |||
| import './form-element.js'; | |||
| import '../../inputs/input-text.js'; | |||
There was a problem hiding this comment.
This is needed because the class defined using defineCE uses it within its render method.
| required | ||
| class="d2l-input"> | ||
| </div> | ||
| <d2l-input-text label="Middle Name" name="middle-name" minlength="4" maxlength="8"></d2l-input-text> |
There was a problem hiding this comment.
Should have an import for input-text.js and input-number.js, which can be removed from form-panel-demo.js.
| required | ||
| > | ||
| <d2l-input-text | ||
| id="nested-telephone-input" |
bearfriend
left a comment
There was a problem hiding this comment.
Mostly a bunch of nits
| <d2l-input-group> | ||
| <div> | ||
| <label for="native-input" class="d2l-input-label d2l-input-label-required">First Name</label> | ||
| <input id="native-input" |
There was a problem hiding this comment.
| <input id="native-input" | |
| <input | |
| id="native-input" |
| render() { | ||
| return html` | ||
| <label for="nested-native-input">Name</label> | ||
| <input id="nested-native-input" |
There was a problem hiding this comment.
| <input id="nested-native-input" | |
| <input | |
| id="nested-native-input" |
| get isCustomFormElementContainer() { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Sort of blanking on how this might work. Is there a reason this can't just be a static property?
There was a problem hiding this comment.
Static as in not a dynamic getter. Not static.
|
|
||
| export const isCustomFormElement = (node) => isCustomElement(node) && !!node.formAssociated; | ||
|
|
||
| export const isCustomFormElementContainer = (node) => isCustomElement(node) && !!node.isCustomFormElementContainer; |
There was a problem hiding this comment.
| export const isCustomFormElementContainer = (node) => isCustomElement(node) && !!node.isCustomFormElementContainer; | |
| export const isCustomFormElementContainer = node => isCustomElement(node) && Boolean(node.isCustomFormElementContainer); |
| const getElementChildren = (ele) => { | ||
| if (isCustomFormElementContainer(ele)) { | ||
| return ele.shadowRoot.children; | ||
| } | ||
|
|
||
| return ele.tagName === 'SLOT' && ['primary', 'secondary'].includes(ele.name) ? ele.assignedNodes() : ele.children; | ||
| }; |
There was a problem hiding this comment.
Typical convention is just el, or maybe elem for more public-facing API stuff I guess. Sort of a nit, but sort of not, for consistency.
| const getElementChildren = (ele) => { | |
| if (isCustomFormElementContainer(ele)) { | |
| return ele.shadowRoot.children; | |
| } | |
| return ele.tagName === 'SLOT' && ['primary', 'secondary'].includes(ele.name) ? ele.assignedNodes() : ele.children; | |
| }; | |
| const getElementChildren = el => { | |
| if (isCustomFormElementContainer(el)) { | |
| return el.shadowRoot.children; | |
| } | |
| return el.tagName === 'SLOT' && ['primary', 'secondary'].includes(el.name) ? el.assignedNodes() : el.children; | |
| }; |
| const _findFormElementsHelper = (ele, eles, isFormElementPredicate, visitChildrenPredicate) => { | ||
| if (isNativeFormElement(ele) || isCustomFormElement(ele) || isFormElementPredicate(ele)) { | ||
| eles.push(ele); | ||
| } | ||
| if (visitChildrenPredicate(ele)) { | ||
| const children = ele.tagName === 'SLOT' && ['primary', 'secondary'].includes(ele.name) ? ele.assignedNodes() : ele.children; | ||
| const children = getElementChildren(ele); | ||
| for (const child of children) { | ||
| _findFormElementsHelper(child, eles, isFormElementPredicate, visitChildrenPredicate); |
There was a problem hiding this comment.
It won't let me make a suggestion here, but same thing with el. Maybe elems for the plural?
Jira
GAUD-10044
Description
Currently the
d2l-formcomponent is able to find nested forms, native form controllers and d2l custom form controllers (through theFormElementMixin)there is still 1 use case where we just want to group the form controllers logically in a custom web component -- let's call it form form element container. this is because the form is big enough so we want to encapsulate portions of it in logically and semantically groups of controller. In this case, the form has no chance to find those nested form controllers within the form element container.
Solution
To address this we decided to implement the
FormElementContainerMixinwhich accomplishes that.