Skip to content

Commit

Permalink
feat(js): add loading indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Dec 2, 2020
1 parent 9983c64 commit 59dc31b
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 10 deletions.
3 changes: 3 additions & 0 deletions packages/autocomplete-js/src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export function autocomplete<TItem extends BaseItem>({
input,
submitButton,
resetButton,
loadingIndicator,
root,
panel,
} = createAutocompleteDom({
Expand Down Expand Up @@ -114,6 +115,7 @@ export function autocomplete<TItem extends BaseItem>({
panel,
submitButton,
resetButton,
loadingIndicator,
});

return () => {};
Expand Down Expand Up @@ -145,6 +147,7 @@ export function autocomplete<TItem extends BaseItem>({
panel,
submitButton,
resetButton,
loadingIndicator,
});
}, 0);

Expand Down
2 changes: 1 addition & 1 deletion packages/autocomplete-js/src/components/LoadingIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const LoadingIcon: Component<{}, SVGSVGElement> = () => {
r="35"
stroke="currentColor"
stroke-dasharray="164.93361431346415 56.97787143782138"
stroke-width="4"
stroke-width="6"
>
<animateTransform
attributeName="transform"
Expand Down
23 changes: 23 additions & 0 deletions packages/autocomplete-js/src/components/LoadingIndicator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Component, WithClassNames } from '../types/Component';
import { concatClassNames, setProperties } from '../utils';

import { LoadingIcon } from './LoadingIcon';

type LoadingIndicatorProps = WithClassNames<{}>;

export const LoadingIndicator: Component<
LoadingIndicatorProps,
HTMLDivElement
> = ({ classNames }) => {
const element = document.createElement('div');
setProperties(element, {
class: concatClassNames([
'aa-LoadingIndicator',
classNames.loadingIndicator,
]),
});

element.appendChild(LoadingIcon({}));

return element;
};
1 change: 1 addition & 0 deletions packages/autocomplete-js/src/components/ResetIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component } from '../types/Component';

export const ResetIcon: Component<{}, SVGSVGElement> = () => {
const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
element.setAttribute('class', 'aa-ResetIcon');
element.setAttribute('viewBox', '0 0 20 20');
element.setAttribute('width', '20');
element.setAttribute('height', '20');
Expand Down
1 change: 1 addition & 0 deletions packages/autocomplete-js/src/components/SearchIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component } from '../types/Component';

export const SearchIcon: Component<{}, SVGSVGElement> = () => {
const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
element.setAttribute('class', 'aa-SubmitIcon');
element.setAttribute('viewBox', '0 0 20 20');
element.setAttribute('width', '20');
element.setAttribute('height', '20');
Expand Down
2 changes: 2 additions & 0 deletions packages/autocomplete-js/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export * from './Form';
export * from './Input';
export * from './InputWrapper';
export * from './Label';
export * from './LoadingIcon';
export * from './LoadingIndicator';
export * from './Panel';
export * from './PanelLayout';
export * from './ResetButton';
Expand Down
4 changes: 4 additions & 0 deletions packages/autocomplete-js/src/createAutocompleteDom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Input,
InputWrapper,
Label,
LoadingIndicator,
Panel,
ResetButton,
Root,
Expand All @@ -33,13 +34,15 @@ export function createAutocompleteDom<TItem extends BaseItem>({
const input = Input({ classNames, getInputProps });
const submitButton = SubmitButton({ classNames });
const resetButton = ResetButton({ classNames });
const loadingIndicator = LoadingIndicator({ classNames });
const form = Form({ classNames, ...getFormProps({ inputElement: input }) });
const panel = Panel({ classNames, ...getPanelProps({}) });

label.appendChild(submitButton);
inputWrapper.appendChild(input);
inputWrapper.appendChild(label);
inputWrapper.appendChild(resetButton);
inputWrapper.appendChild(loadingIndicator);
form.appendChild(inputWrapper);
root.appendChild(form);

Expand All @@ -51,6 +54,7 @@ export function createAutocompleteDom<TItem extends BaseItem>({
label,
submitButton,
resetButton,
loadingIndicator,
panel,
};
}
14 changes: 7 additions & 7 deletions packages/autocomplete-js/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
AutocompleteRenderer,
AutocompleteState,
} from './types';
import { setPropertiesWithoutEvents } from './utils';
import { setProperties, setPropertiesWithoutEvents } from './utils';

type RenderProps<TItem extends BaseItem> = {
state: AutocompleteState<TItem>;
Expand All @@ -38,12 +38,16 @@ export function render<TItem extends BaseItem>(
root,
input,
resetButton,
submitButton,
loadingIndicator,
panel,
}: RenderProps<TItem>
): () => void {
setPropertiesWithoutEvents(root, getRootProps({}));
setPropertiesWithoutEvents(resetButton, { hidden: !state.query });
setPropertiesWithoutEvents(input, getInputProps({ inputElement: input }));
setPropertiesWithoutEvents(resetButton, { hidden: !state.query });
setProperties(submitButton, { hidden: state.status === 'stalled' });
setProperties(loadingIndicator, { hidden: state.status !== 'stalled' });

panel.innerHTML = '';

Expand All @@ -59,11 +63,7 @@ export function render<TItem extends BaseItem>(
panelRoot.appendChild(panel);
}

if (state.status === 'stalled') {
panel.classList.add('aa-Panel--stalled');
} else {
panel.classList.remove('aa-Panel--stalled');
}
panel.classList.toggle('aa-Panel--stalled', state.status === 'stalled');

const sections = state.collections.map(({ source, items }) => {
const sectionElement = SourceContainer({ classNames });
Expand Down
2 changes: 2 additions & 0 deletions packages/autocomplete-js/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export type AutocompleteClassNames = Partial<{
input: string;
submitButton: string;
resetButton: string;
loadingIndicator: string;
panel: string;
panelLayout: string;
source: string;
Expand All @@ -95,6 +96,7 @@ export type AutocompleteDom = {
label: HTMLLabelElement;
submitButton: HTMLButtonElement;
resetButton: HTMLButtonElement;
loadingIndicator: HTMLDivElement;
panel: HTMLDivElement;
};

Expand Down
18 changes: 16 additions & 2 deletions packages/autocomplete-theme-classic/src/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,18 @@
}
}

.aa-SubmitButton,
.aa-ResetButton,
.aa-LoadingIndicator {
height: 100%;
padding: 0 0.5rem;
}

.aa-SubmitButton,
.aa-ResetButton {
background: none;
border: 0;
cursor: pointer;
height: 100%;
padding: 0 0.5rem;
}

.aa-ResetButton {
Expand All @@ -68,6 +73,15 @@
z-index: 2;
}

.aa-LoadingIndicator {
position: absolute;
z-index: 2;
}

.aa-LoadingIcon {
height: 100%;
}

.aa-Panel {
max-width: 480px;
position: absolute;
Expand Down
2 changes: 2 additions & 0 deletions packages/website/docs/autocomplete-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ type ClassNames = Partial<{
inputWrapper: string;
input: string;
resetButton: string;
submitButton: string;
loadingIndicator: string;
panel: string;
panelLayout: string;
source: string;
Expand Down

0 comments on commit 59dc31b

Please sign in to comment.