on clicking customize fields of specific object, it doesn't lead to descriptions of that object.
Description:
When we click on customize fields, it should go to the description of that object; currently, it is leading to a list of all objects.
https://github.com/user-attachments/assets/e1c05782-2083-43e6-a994-f90c1506712f
Expected behaviour:
Customize fields should lead to a description of that object, meaning where all its fields are listed.
I posted this in our Discord with respect to avoiding a monolithic Menu, and it made me think of more things we can split out as "feature components".
Some of the benefits of splitting components include:
- Better tree-shaking: if a component handles everything via props, it can't be treeshaken by your bundler compared to a separate component
- Props/types can be easier: ContextMenu for example doesn't support a bunch of the props that Menu does (modal, openOnHover, delay, etc.) So if you try to configure both simultaneously, it can be confusing. (We have this problem in a couple places currently, namely with the Select positioning.) It can be easier to type MultiSelect value to always be an array; same with RangeSlider
Here are some other possible ones — features as components:
Since the regular anchoring props don't apply when alignItemWithTrigger=true (except in fallback/touch mode), it could make more sense to split it out, removing the cost of it when you don't use it.
<Select.AlignItemWithTrigger>
</Select.AlignItemWithTrigger>
Menu, Popover openOnHover and related delay features. Since delay doesn't work without openOnHover it again might make more sense to split it out, also removing the cost of it if unused.
<Popover.OpenOnHover delay={500}>
</Popover.OpenOnHover>
This API reminds me a bit of composable chart libraries where features are added as component parts separately.
@atomiks this feature is a very good idea!
I would like to add patterns on how to solve this problem:
- Props that represent treeshakeable features take their implementation as value:
<Select.Positioner
alignItemWithTrigger={Select.alignItemWithTrigger(options)}
/>
<Popover.Root
openOnHover={Popover.openOnHover({ delay: 500 })}
/>
This is similar to the features prop but it adds a bit more clarity as its used directly on the component this affects. If the alignItemWithTrigger feature has any additional options which customize the feature, they can also be passed here.
This would also "group" properties that are bound to a certain feature.
A cool side effect of this pattern would be that features could have different implementations and all of them could be treeshakeable.
- Treeshakeable features could be added globally:
Select.features([
Select.alignItemWithTriggerFeature,
]);
Popover.features([
Popover.openOnHoverFeature,
]);
With this pattern one can add features globally to certain components. Each of the features represents the whole implementation of the features, additional options for each feature are provided directly via component props. If a prop is used and the underlying feature is not provided the prop would do nothing and a warning / error could be printed.
An extension to such an API could also be to have lazy features. This would be "nice to have" features that don't influence the core functionality of a component but are costly in implementation. Something like Select.alignItemWithTrigger would be a good example. This approach would use promises, so any lazy feature would only be available if the promise is resolved.
An unwanted side effect of that would be that the component would change its behavior depending on whether the feature is available or not. (In the case of alignItemWithTrigger the first opening of the select wouldn't have the feature applied, but subsequent opening could have the feature)