Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/melfore/mosaic into beta
Browse files Browse the repository at this point in the history
  • Loading branch information
luciob committed May 3, 2022
2 parents 6ee8fa2 + 587c21c commit e3a2666
Show file tree
Hide file tree
Showing 11 changed files with 404 additions and 147 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# [7.0.0](https://github.com/melfore/mosaic/compare/v6.4.1...v7.0.0) (2022-05-02)


### Features

* 🎸 [Select] Display checkbox only when multiple=true ([7d3d961](https://github.com/melfore/mosaic/commit/7d3d9616700bc3e72d0052eee699e65a024113df))
* 🎸 [Select] Wrapped each option in a div with dataCy ([13172e5](https://github.com/melfore/mosaic/commit/13172e547b2f0d6622339142ec610b51c9657468))


### BREAKING CHANGES

* 🧨 Potential breaking: style should be preserved via display: 'contents'

✅ Closes: 249

# [6.5.0-beta.1](https://github.com/melfore/mosaic/compare/v6.4.1...v6.5.0-beta.1) (2022-04-11)


Expand Down
2 changes: 1 addition & 1 deletion docs/latest/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,4 @@



window['STORIES'] = [{"titlePrefix":"","directory":"./src/components","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:src\\/components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./src/components","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:src\\/components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"}];</script><script src="runtime~main.ace93caa.iframe.bundle.js"></script><script src="vendors~main.44ee7de1.iframe.bundle.js"></script><script src="main.61e52be8.iframe.bundle.js"></script></body></html>
window['STORIES'] = [{"titlePrefix":"","directory":"./src/components","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:src\\/components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./src/components","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:src\\/components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"}];</script><script src="runtime~main.ace93caa.iframe.bundle.js"></script><script src="vendors~main.44ee7de1.iframe.bundle.js"></script><script src="main.29c252a0.iframe.bundle.js"></script></body></html>

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@melfore/mosaic",
"version": "6.5.0-beta.1",
"version": "7.0.0",
"homepage": "https://github.com/melfore/mosaic#readme",
"description": "Melfore's UI kit library based on `@material-ui`",
"repository": {
Expand Down
44 changes: 44 additions & 0 deletions src/components/Select/components/Group/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { FC, Fragment, useMemo } from "react";
import {
AutocompleteRenderGroupParams as MUIAutocompleteRenderGroupParams,
ListSubheader as MUIListSubheader,
useTheme,
} from "@mui/material";

import { IBase } from "../../../../types/Base";
import { getComposedDataCy, ISubpart } from "../../../../utils";

interface ISelectGroup extends IBase {
forwarded: MUIAutocompleteRenderGroupParams;
getGroupLabel?: (groupName: string) => string;
}

export const SELECT_GROUP_SUBPART: ISubpart = {
label: "Option Group (with label)",
value: (label = "{label}") => `option-group-${label}`,
};

const SelectGroup: FC<ISelectGroup> = ({
dataCy = "select-group",
forwarded: { children, group, key },
getGroupLabel,
}) => {
const theme = useTheme();

const groupLabel = useMemo(() => (getGroupLabel ? getGroupLabel(group) : group), [getGroupLabel, group]);

const groupDataCy = useMemo(() => getComposedDataCy(dataCy, SELECT_GROUP_SUBPART, groupLabel), [dataCy, groupLabel]);

const style = useMemo(() => ({ backgroundColor: theme.palette.background.default }), [theme]);

return (
<Fragment key={`group-${key}`}>
<MUIListSubheader data-cy={groupDataCy} style={style}>
{groupLabel}
</MUIListSubheader>
{children}
</Fragment>
);
};

export default SelectGroup;
80 changes: 80 additions & 0 deletions src/components/Select/components/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { CSSProperties, FC, useMemo } from "react";
import {
AutocompleteRenderInputParams as MUIAutocompleteRenderInputParams,
Skeleton as MUISkeleton,
TextField as MUITextField,
} from "@mui/material";

import { ILoadable } from "../../../../types/Base";
import { IInputField } from "../../../../types/Input";
import { getComposedDataCy, ISubpart } from "../../../../utils";

type ISelectInputField = Pick<IInputField, "dataCy" | "label" | "placeholder"> &
Required<Pick<IInputField, "required" | "size" | "type" | "variant">>;

interface ISelectInput extends ISelectInputField, ILoadable {
forwarded: MUIAutocompleteRenderInputParams;
}

export const SELECT_LOADING_SUBPART: ISubpart = {
label: "Loading",
};

const SelectInput: FC<ISelectInput> = ({
dataCy = "select-input",
forwarded,
label,
loading,
placeholder,
required,
size,
style: externalStyle,
type,
variant,
}) => {
const {
inputProps: forwardedInputProps,
InputProps: { ref: forwardedRef },
} = forwarded;

const style = useMemo((): CSSProperties => ({ ...externalStyle, width: "100%" }), [externalStyle]);

const inputDataCy = useMemo(
() => (!loading ? dataCy : getComposedDataCy(dataCy, SELECT_LOADING_SUBPART)),
[dataCy, loading]
);

const inputProps = useMemo(
() => ({
...forwardedInputProps,
"data-cy": inputDataCy,
style,
}),
[forwardedInputProps, inputDataCy, style]
);

if (loading) {
return (
<MUISkeleton ref={forwardedRef} width="100%">
<MUITextField inputProps={inputProps} margin="normal" size={size} variant={variant} style={style} />
</MUISkeleton>
);
}

return (
<MUITextField
inputProps={inputProps}
label={label}
margin="normal"
placeholder={placeholder}
ref={forwardedRef}
required={required}
size={size}
style={style}
type={type}
variant={variant}
/>
);
};

export default SelectInput;
83 changes: 83 additions & 0 deletions src/components/Select/components/Option/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { Fragment, HTMLAttributes, ReactNode, useMemo } from "react";

import { IBase } from "../../../../types/Base";
import { getComposedDataCy, ISubpart } from "../../../../utils";
import Checkbox from "../../../Checkbox";
import Typography from "../../../Typography";

interface ISelectOption<T> extends IBase {
customRenderer?: (option: T, selected: boolean) => ReactNode;
forwarded: HTMLAttributes<HTMLLIElement>;
getOptionLabel: (option: T) => string;
multiple: boolean;
option: T;
selected: boolean;
}

export const SELECT_OPTION_SUBPART: ISubpart = {
label: "Option (with label)",
value: (label = "{label}") => `option-${label}`,
};

export const SELECT_OPTION_CHECKBOX_SUBPART: ISubpart = {
label: "Option Checkbox (with label)",
value: (label = "{label}") => `option-${label}-checkbox`,
};

export const SELECT_OPTION_LABEL_SUBPART: ISubpart = {
label: "Option Label (with label)",
value: (label = "{label}") => `option-${label}-label`,
};

const SelectOption = <T extends any>({
customRenderer,
dataCy = "select-option",
forwarded,
getOptionLabel,
multiple,
option,
selected,
}: ISelectOption<T>) => {
const optionLabel = useMemo(() => getOptionLabel(option), [getOptionLabel, option]);

const checkboxDataCy = useMemo(
() => getComposedDataCy(dataCy, SELECT_OPTION_CHECKBOX_SUBPART, optionLabel),
[dataCy, optionLabel]
);

const labelDataCy = useMemo(
() => getComposedDataCy(dataCy, SELECT_OPTION_LABEL_SUBPART, optionLabel),
[dataCy, optionLabel]
);

const optionDataCy = useMemo(
() => getComposedDataCy(dataCy, SELECT_OPTION_SUBPART, optionLabel),
[dataCy, optionLabel]
);

const customContent = useMemo(
() => (customRenderer ? customRenderer(option, selected) : undefined),
[customRenderer, option, selected]
);

const content = useMemo(() => {
if (customContent) {
return customContent;
}

return (
<Fragment>
{multiple && <Checkbox dataCy={checkboxDataCy} disabled labelPlacement="end" value={selected} />}
<Typography dataCy={labelDataCy}>{optionLabel}</Typography>
</Fragment>
);
}, [checkboxDataCy, customContent, labelDataCy, optionLabel, multiple, selected]);

return (
<li key={optionDataCy} data-cy={optionDataCy} {...forwarded}>
{content}
</li>
);
};

export default SelectOption;
21 changes: 21 additions & 0 deletions src/components/Select/components/Popper/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { FC, useMemo } from "react";
import { Popper as MUIPopper, PopperProps as MUIPopperProps } from "@mui/material";

interface ISelectPopper {
forwarded: MUIPopperProps;
popperWidth: any;
}

const SelectPopper: FC<ISelectPopper> = ({ forwarded, popperWidth }) => {
const { anchorEl } = forwarded;

const width = useMemo(() => {
const anchorElRef = anchorEl as any;
const anchorElWidth = anchorElRef ? anchorElRef.clientWidth : null;
return !!popperWidth && popperWidth > anchorElWidth ? popperWidth : anchorElWidth;
}, [popperWidth, anchorEl]);

return <MUIPopper {...forwarded} placement="bottom-start" style={{ width }} />;
};

export default SelectPopper;
Loading

0 comments on commit e3a2666

Please sign in to comment.