diff --git a/examples/js/autocomplete.css b/examples/js/autocomplete.css index 9966477ae..7012d4498 100644 --- a/examples/js/autocomplete.css +++ b/examples/js/autocomplete.css @@ -69,12 +69,6 @@ } .aa-Panel { - background-color: #fff; - border: 1px solid rgba(150, 150, 150, 0.16); - border-radius: 3px; - box-shadow: 0 0 0 1px rgba(35, 38, 59, 0.05), - 0 8px 16px -4px rgba(35, 38, 59, 0.25); - margin-top: 5px; max-width: 480px; position: absolute; width: 100%; @@ -86,12 +80,21 @@ transition: opacity 200ms ease-in; } -.aa-Panel a { +.aa-PanelLayout { + background-color: #fff; + border: 1px solid rgba(150, 150, 150, 0.16); + border-radius: 3px; + box-shadow: 0 0 0 1px rgba(35, 38, 59, 0.05), + 0 8px 16px -4px rgba(35, 38, 59, 0.25); + margin-top: 5px; +} + +.aa-PanelLayout a { color: inherit; text-decoration: none; } -.aa-Panel ul { +.aa-PanelLayout ul { list-style: none; margin: 0; padding: 0; diff --git a/packages/autocomplete-js/src/components/Panel.ts b/packages/autocomplete-js/src/components/Panel.ts index d1f16f74b..71a7d4ab4 100644 --- a/packages/autocomplete-js/src/components/Panel.ts +++ b/packages/autocomplete-js/src/components/Panel.ts @@ -14,7 +14,6 @@ export const Panel: Component = ({ const element = document.createElement('div'); setProperties(element, { ...props, - hidden: true, class: concatClassNames(['aa-Panel', classNames.panel]), }); diff --git a/packages/autocomplete-js/src/components/PanelLayout.ts b/packages/autocomplete-js/src/components/PanelLayout.ts new file mode 100644 index 000000000..6c6289718 --- /dev/null +++ b/packages/autocomplete-js/src/components/PanelLayout.ts @@ -0,0 +1,17 @@ +import { Component, WithClassNames } from '../types/Component'; +import { concatClassNames, setProperties } from '../utils'; + +type PanelLayoutProps = WithClassNames<{}>; + +export const PanelLayout: Component = ({ + classNames, + ...props +}) => { + const element = document.createElement('div'); + setProperties(element, { + ...props, + class: concatClassNames(['aa-PanelLayout', classNames.panelLayout]), + }); + + return element; +}; diff --git a/packages/autocomplete-js/src/components/index.ts b/packages/autocomplete-js/src/components/index.ts index 367376555..73d0e50b4 100644 --- a/packages/autocomplete-js/src/components/index.ts +++ b/packages/autocomplete-js/src/components/index.ts @@ -3,6 +3,7 @@ export * from './Input'; export * from './InputWrapper'; export * from './Label'; export * from './Panel'; +export * from './PanelLayout'; export * from './ResetButton'; export * from './ResetIcon'; export * from './Root'; diff --git a/packages/autocomplete-js/src/createAutocompleteDom.ts b/packages/autocomplete-js/src/createAutocompleteDom.ts index f2e03f5f1..338190021 100644 --- a/packages/autocomplete-js/src/createAutocompleteDom.ts +++ b/packages/autocomplete-js/src/createAutocompleteDom.ts @@ -36,7 +36,6 @@ export function createAutocompleteDom({ inputWrapper.appendChild(resetButton); form.appendChild(inputWrapper); root.appendChild(form); - root.appendChild(panel); return { inputWrapper, diff --git a/packages/autocomplete-js/src/render.ts b/packages/autocomplete-js/src/render.ts index 5c130af50..327bb941e 100644 --- a/packages/autocomplete-js/src/render.ts +++ b/packages/autocomplete-js/src/render.ts @@ -1,6 +1,7 @@ import { AutocompleteApi as AutocompleteCoreApi } from '@algolia/autocomplete-core'; import { + PanelLayout, SourceContainer, SourceFooter, SourceHeader, @@ -14,7 +15,7 @@ import { AutocompleteRenderer, AutocompleteState, } from './types'; -import { setProperties, setPropertiesWithoutEvents } from './utils'; +import { setPropertiesWithoutEvents } from './utils'; type RenderProps = { state: AutocompleteState; @@ -42,11 +43,16 @@ export function render( panel.innerHTML = ''; if (!state.isOpen) { - setProperties(panel, { hidden: true }); + if (root.contains(panel)) { + root.removeChild(panel); + } + return; } - setProperties(panel, { hidden: false }); + if (!root.contains(panel)) { + root.appendChild(panel); + } if (state.status === 'stalled') { panel.classList.add('aa-Panel--stalled'); @@ -106,5 +112,8 @@ export function render( return sectionElement; }); - renderer({ root: panel, sections, state }); + const panelLayoutElement = PanelLayout({ classNames }); + panel.appendChild(panelLayoutElement); + + renderer({ root: panelLayoutElement, sections, state }); } diff --git a/packages/autocomplete-js/src/types/index.ts b/packages/autocomplete-js/src/types/index.ts index 832d68f72..bcfb862fd 100644 --- a/packages/autocomplete-js/src/types/index.ts +++ b/packages/autocomplete-js/src/types/index.ts @@ -73,6 +73,7 @@ export type AutocompleteClassNames = Partial<{ input: string; resetButton: string; panel: string; + panelLayout: string; source: string; sourceHeader: string; list: string; diff --git a/packages/website/docs/autocomplete-js.md b/packages/website/docs/autocomplete-js.md index 538a4578f..4b5a265f5 100644 --- a/packages/website/docs/autocomplete-js.md +++ b/packages/website/docs/autocomplete-js.md @@ -88,20 +88,21 @@ The panel horizontal position. The class names to inject in each created DOM element. It it useful to design with external CSS frameworks. ```ts -type ClassNames = { - root?: string; - form?: string; - label?: string; - inputWrapper?: string; - input?: string; - resetButton?: string; - panel?: string; - source?: string; - sourceHeader?: string; - list?: string; - item?: string; - sourceFooter?: string; -}; +type ClassNames = Partial<{ + root: string; + form: string; + label: string; + inputWrapper: string; + input: string; + resetButton: string; + panel: string; + panelLayout: string; + source: string; + sourceHeader: string; + list: string; + item: string; + sourceFooter: string; +}>; ``` ### `render`