-
Notifications
You must be signed in to change notification settings - Fork 78
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
Calcite-switch won't switch if not wrapped in <label> #67
Comments
It would be more correct to say that there are currently two sources of truth for state: changes to props or changes to the underlying DOM are both respected and propagated to one another. This is in order to support both the wrapped and non-wrapped syntaxes: <calcite-switch></calcite-switch>
<calcite-switch>
<input type='checkbox' />
</calcite-switch> One solution would be to disambiguate internally between these two fairly distinct use cases: if no checkbox is provided, treat props as the source of truth. If a checkbox is provided, treat the DOM as the source of truth. This would allow the component to maintain a single-direction data flow, preventing a whole class of nasty bugs. |
@patrickarlt this passing in your input approach makes the story for these components kind of complicated and adds a lot to the implementation. We could move a lot faster if we removed this requirement. Wondering if we should go out of our way for this at v1. Maybe bindings for other frameworks are a feature add in the future? |
For posterity I'll post this here in addition to Teams: https://github.com/ionic-team/ionic/tree/master/core/src/components/checkbox#angular Ionic, which uses Stencil internally, is able to support Angular's special attribute syntax, like |
I think Angular and Vue can pretty much use Ionic's web components directly (with some exceptions: Vue's ionic-tabs for some reason, detailed here). React is different. Every component has to be wrapped. Mostly this is done semi-automatically using a helper function called createComponent. |
@vcolavin this depends on what you mean by "use directly" and the level of support we want to provide for each framework. Ionic ships a set of Angular bindings so if by "use directly" you mean: <calcite-switch (switched)="onSwitched(e)" [switched]="isEnabled"></calcite-switch> You can actually do that without the Angular bindings because it just uses the DOM events and attributes directly. But if by "use directly" you mean how you are SUPPOSED to do Angular forms like: <calcite-switch [(ngModel)]="isEnabled"></calcite-switch> Then you need the bindings. For example here are the The reason we do things like: <calcite-switch>
<input type='checkbox' />
</calcite-switch> Is discussed in #24 (comment) but to summarize:
@paulcpederson @vcolavin this honestly just seems like a bug we need to fix and write solid regression tests for which I can do after UC. @paulcpederson we could remove the requirement for this work as per #67 but I think that would be a mistake since it would encourage writing lots of custom additional behavior in the bindings and it would be lots of work the first team that would be implementing these i.e. I have to write Angular binding just to use these in VTSE and then every other team writes their own bindings. I suppose we could already start looking into Stencil DS which is supposed to be able to automatically write the binding for you if we want to have this discussion now. But I honestly feel like this is bug to be solved and not cause us to rethink the whole approach. |
Thanks for the well-thought-out comment @patrickarlt! I agree that this is just a bug that just needs to be fixed. And maybe this isn't the time or place to relitigate the basic approach to writing calcite-components. I did come onto this project when it was already in progress. It sounds like there are serious downsides to the wrapper route. But because this is intended to be a library which is used and maintained across Esri products for a long while, we will want to prioritize maintainability and code quality. Circular updates stand out to me as a maintainability and readability red flag. I want to find some way or pattern that makes them harder to write, in the same way that React and other modern frameworks protect against them. |
* WIP add checkboxes * address #67; switch component won't switch * add more correct handling of values in calcite-switch * refurbish the calcite-switch tests * add a failing test * wip updates to calcite-checkbox * WIP calcite-checkbox indeterminate state * add appropriate styles for calcite-checkbox * Fix issue where keyDown would not toggle indeterminate checkbox * add most of the remaining features and states to calcite-tabs * add new test describing calcite-checkbox behavior * Fix final failing test - The test was relying on a guid implementation which used - window.crypto.getRandomValues(), which is not available in Jest - I replaced it with Math.random() - Which is sufficiently random for generating UUIDs - I also refactored the guid function for fun. * add JSDoc comments * generate JSDoc documentation * add a test ensuring that the custom change event fires * remove browser prefixes * fix tests :) * use a 'size' attr rather than 'small' or 'large' * replace calcite-checkbox hex codes with sass vars * fix bug occurring in changing input state
Closing as I think this was taken care of? |
cc @paulcpederson @patrickarlt @macandcheese
I will include a fix for this in my upcoming PR for #1.
The most basic usage of calcite-switch is broken, probably as a result of PR 48 (which I wrote):
You would expect that clicking on the resulting switch would toggle the value, but it doesn't. It works when wrapped in a label, like this:
This is happening because the component's
switched
prop gets immediately toggled back by theproxyInput
mutation observer.The proximal cause of this bug is in the mutation observer:
More fundamentally however I wrote this bug as a result of a confusing dataflow graph. The DOM is the source of truth, so props are synced to it, but the DOM itself gets updated based on props sometimes:
this.switched
propswitchWatcher
checked
attribute oninputProxy
inputProxy
mutation observerthis.switched
toinputProxy.checked
I don't have a solution for this deeper issue. Does anyone else have thoughts on this?
The text was updated successfully, but these errors were encountered: