-
Notifications
You must be signed in to change notification settings - Fork 11
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(horizontal-slider): change renderer implementation to VDOM #28
Conversation
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.
Looks good—love the optional container
pattern!
I've got a concern about the ref compatibility with a future Vue package though.
type Ref<TElement> = { | ||
current: TElement; | ||
}; |
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'm wondering how that will play out with Vue because their refs are strings.
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.
Since we will be in control of the Vue implementation, we could define a fallback type for it
@@ -0,0 +1,36 @@ | |||
export type Pragma = ( |
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.
Next component that we create we might want have a shared/common package for these types.
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.
Yep, I can already see multiple use cases for a shared package!
@@ -1,13 +1,13 @@ | |||
# `@algolia/ui-components-js-horizontal-slider` | |||
# `@algolia/ui-components-horizontal-slider-js` |
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.
much better name, alternative would have been js-ui-components- horizontal-slider
, but this format works well
nextButtonRef, | ||
previousButtonRef, | ||
}); | ||
}); |
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.
should this happen on every change?
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.
Since this call will set update the hidden
boolean to hide/show our arrows, yes. Did you meant to add the concerned refs to the dependencies?
environment = window, | ||
...props | ||
}: HorizontalSliderProps<TObject> & EnvironmentProps) { | ||
const children = <HorizontalSlider {...props} />; |
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.
should this be called children or component (it's only one element, maybe child)?
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.
We choosed children
to keep it consistent with the return of our recommendations
components
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.
component
also makes sense to me. Both are fine IMO.
listRef={listRef} | ||
nextButtonRef={nextButtonRef} | ||
previousButtonRef={previousButtonRef} | ||
sliderIdRef={sliderIdRef} |
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 wonder if this should be a single refs object?
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.
probably not due to the diff annoyances that causes
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 feel like this is easier to understand as single refs, what would your implementation looks like?
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.
refs={{ nextButton: nextButtonRef, previousButton: previousButtonRef, sliderId: sliderIdRef }}
or something similar
let lastHorizontalSliderId = 0; | ||
|
||
export function generateHorizontalSliderId() { | ||
return `uic-horizontal-slider-${lastHorizontalSliderId++}`; |
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.
does this generate stable ids for use in server side rendering?
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.
This is the same logic as we used in autocomplete but I didn't tried it yet with SSR!
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.
For this to be SSR-safe, we need to accept an id
prop in all our components. You would need to generate the id
on the server and pass it to the client. (Autocomplete allows this.)
We've planed to add this later. But as it is now, it's not SSR-safe.
(Other interesting resources could be the new React's useOpaqueIdentifier
.)
<pre> | ||
<code>{JSON.stringify(item)}</code> | ||
</pre> |
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.
can you use it without preact (document.createElement) too, or does that not make sense?
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.
That would be either VDOM or HTML strings (see algolia/ui-components#27 (comment)).
Co-authored-by: Haroen Viaene <hello@haroen.me>
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.
all good for me
Follow up of the previous PR: algolia/ui-components#27
This is a rework of the rendering system of the Horizontal Slider UI components to an agnostic virtual DOM implementation.
Problems
Here's a list of the problems we have with the current architecture:
preact/compat
package which exports the whole React API. (We now only rely onpreact
andpreact/hooks
.)view
prop rendering framework.Architecture
Current
The previous packages main entry point was
react-horizontal-slider
, where the logic and the rendering happened. Thejs-horizontal-slider
package relied onreact-horizontal-slider
with an alias fromreact
topreact/compat
.New
We now have these packages:
horizontal-slider-js
horizontal-slider-js
is an implementation ofhorizontal-slider-vdom
with Preact (similar front-end framework that we use in Autocomplete, InstantSearch and the recommendations-js package). It specifieshorizontal-slider-vdom
with the Preact renderer.API
horizontalSlider
horizontal-slider-react
horizontal-slider-react
is an implementation ofhorizontal-slider-vdom
with React.API
HorizontalSlider
horizontal-slider-theme
Package that hosts the
HorizontalSlider
component default theme.horizontal-slider-vdom
horizontal-slider-vdom
is an agnostic package that allows to build components given a renderer. A renderer is composed of{ createElement, Fragment }
. It's purely the UI part and creates uncontrolled components, lacking any state and lifecycle functionalities.API
createHorizontalSliderComponent
generateHorizontalSliderId
: the function to initialize thesliderIdRef
ref with.updateNavigationButtonsProps
: the function to wrap in an effect, which will update the current value of the refs.Changes
container
The
container
props for therecommendations-js
andhorizontal-slider-js
packages are now optional. Whenundefined
, we will directly return the component instead of rendering it in its container.This allows us to:
view
prop of therecommendations-js
components with theHorizontaSlider
.fallbackComponent
from therecommendations-js
library in the same container as its parent.Usage
Other packages in the future
When the time comes, we'll be able to create
horizontal-slider-vue
with the same strategy ashorizontal-slider-js
andhorizontal-slider-react
. We could also expose this component for React Native in the future.Next steps