-
Notifications
You must be signed in to change notification settings - Fork 331
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(layout): introduce Layout API #499
base: next
Are you sure you want to change the base?
Conversation
Co-authored-by: Kevin Granger <[email protected]>
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit dad554b:
|
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 have other use cases in mind for the Layout API? For example, would we imagine packaging the templates from the classic theme, or providing an out-of-the-box preview panel layout?
I'm asking because the current API only exports two components and I'm trying to reason about what's the higher-level usage we imagine for it.
|
||
> `(type: any, props: Record<string, any> | null, ...children: ComponentChildren[]) => VNode` | ||
|
||
The function that create virtual nodes. |
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.
The function that create virtual nodes. | |
The function to create virtual nodes. |
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 have other use cases in mind for the Layout API? For example, would we imagine packaging the templates from the classic theme, or providing an out-of-the-box preview panel layout?
I'm asking because the current API only exports two components and I'm trying to reason about what's the higher-level usage we imagine for it.
Ideally we provide everything that could impact the navigation or accessibility. Although we don't provide anything to style inside the preview (not even the simplest display) from there it's clear that there is nothing more to learn or take advantage in autocomplete. Eventually we could provide some utility class for very common patterns.
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 e4e43ca.
|
||
.aa-NavigationCommandLabel, | ||
.aa-SearchByAlgoliaLabel { | ||
color: #969faf; |
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.
Not customizable?
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 need to support dark mode as well.
I would prefer an api where the layouts would infer the createElement based on the renderer that would also be used for autocomplete, something like: import {
createNavigationCommandsLayout,
createSearchByAlgoliaLayout,
} from 'layouts';
const NavigationCommandsLayout = createNavigationCommandsLayout({
createElement,
Fragment,
});
const SearchByAlgoliaLayout = createSearchByAlgoliaLayout({
createElement,
Fragment,
});
autocomplete({
// ...
renderer: { createElement, Fragment },
render({ sections }, root) {
render(
<Fragment>
<div className="aa-PanelLayout">{sections}</div>
<footer className="aa-PanelFooter">
<NavigationCommandsLayout
translations={{
toClose: 'pour fermer',
toNavigate: 'pour naviguer',
toSelect: 'pour sélectionner',
}}
/>
<SearchByAlgoliaLayout />
</footer>
</Fragment>,
root
);
},
}); The main criticism I have here & as well for the highlight functions is that passing createElement & Fragment is noisy. If we register the helpers / components somehow to the autocomplete instance, I think those could be inferred. Alternative: import { NavigationCommandsLayout, SearchByAlgoliaLayout } from 'layouts';
autocomplete({
// ...
renderer: { createElement, Fragment },
components: { SearchByAlgoliaLayout, NavigationCommandsLayout },
render({ sections, components }, root) {
render(
<Fragment>
<div className="aa-PanelLayout">{sections}</div>
<footer className="aa-PanelFooter">
<components.NavigationCommandsLayout
translations={{
toClose: 'pour fermer',
toNavigate: 'pour naviguer',
toSelect: 'pour sélectionner',
}}
/>
<components.SearchByAlgoliaLayout />
</footer>
</Fragment>,
root
);
},
}); (in the second option you could instantiate the component using the createElement & Fragment passed to autocomplete as well without bundling the layouts with autocomplete) |
@sarahdayan We originally wanted to export components like Once we're settled on great default templates for items, preview panels, etc., it can become part of this package. |
I updated the API to use our new Component API: /** @jsx h */
import { autocomplete } from '@algolia/autocomplete-js';
import {
NavigationCommands,
SearchByAlgolia,
} from '@algolia/autocomplete-layout-classic';
import { h, render } from 'preact';
import '@algolia/autocomplete-theme-classic';
autocomplete({
// ...
components: {
NavigationCommands,
SearchByAlgolia,
},
render({ sections, Fragment, components }, root) {
render(
<Fragment>
<div className="aa-PanelLayout aa-Panel--scrollable">{sections}</div>
<footer className="aa-PanelFooter">
<components.NavigationCommands />
<components.SearchByAlgolia />
</footer>
</Fragment>,
root
);
},
}); |
<Fragment> | ||
<div className="aa-PanelLayout aa-Panel--scrollable">{sections}</div> | ||
<footer className="aa-PanelFooter"> | ||
<components.NavigationCommands |
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.
could you in this case not use it directly, without passing to 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.
my linter doesn't detect that components
variable is used in the code. I guess because it struggles to detect the html tag and make the relation? but it's not great.
// ... | ||
renderer, | ||
components: { | ||
NavigationCommands: createNavigationCommandsComponent(renderer), |
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.
what if we call the components with renderer
ourselves before setting it to 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.
this looks very sleek!
Putting "On Hold" because we de-prioritized the Layout API. |
This introduces the Layout API via a new package:
@algolia/autocomplete-layout-classic
. The styles are included in the Autocomplete Classic Theme, which is required for these layouts.Goal
Layouts aim at providing minimal UI elements that are common in Autocomplete experiences.
What's included
Preview
Usage
Basic
With translations
Documentation
You can read the documentation written in this PR.
What's next
There are still a few styling issues that need to be handled:
Feedback
I'm open to feedback about this API. If you have any suggestions on how to make this usage easier, let me know!