Skip to content
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

v5.0.0 and v6.0.0 Release Target #1302

Open
mlaursen opened this issue Nov 24, 2021 · 0 comments
Open

v5.0.0 and v6.0.0 Release Target #1302

mlaursen opened this issue Nov 24, 2021 · 0 comments
Milestone

Comments

@mlaursen
Copy link
Owner

mlaursen commented Nov 24, 2021

Due to the already large size of the v4.0.0 release, I'm going to move some of the targeted changes for the v5.0.0 release target instead.

v5.0.0 Release Target

Improved @react-md/menu API

A new and improved @react-md/menu API. Instead of passing a list of items, directly use the <MenuItem> components within the children.

 function Example() {
   return (
-    <DropdownMenu
-      id="dropdown-menu-1"
-      items={[
-        'Item 1',
-        null,
-        0,
-        1,
-        'separator',
-        { children: 'Item 2' },
-        { role: 'separator', inset: true },
-        { rightAddon: <HomeSVGIcon />, children: 'Home' },
-        {
-          leftAddon: <InfoOutlineSVGIcon />,
-          children: <span>Custom content</span>,
-        },
-        { href: '#', children: 'Link' },
-        <MenuItem>Custom item</MenuItem>,
-        <MenuItemLink href="#">Link</MenuItemLink>,
-      ]}
-    >
-      Options...
+    <DropdownMenu id="dropdown-menu-1" buttonChildren="Options...">
+      <MenuItem>Item 1</MenuItem>
+      {someBoolean && <MenuItem>Conditional Item</MenuItem>}
+      <MenuItem>0</MenuItem>
+      <MenuItem>1</MenuItem>
+      <Divider />
+      <MenuItem>Item 2</MenuItem>
+      <Divider inset />
+      <MenuItem rightAddon={<HomeSVGIcon />}>Home</MenuItem>
+      <MenuItem leftAddon={<InfoOutlineSVGIcon />}>
+        <span>Custom content</span>
+      </MenuItem>
+      <MenuItemLink href="#">Link</MenuItemLink>
+      <MenuItem>Custom item</MenuItem>
+      <MenuItemLink href="#">Link</MenuItemLink>
     </DropdownMenu>
   );
 }

These changes make it so that you can now create resuable components to handle specific actions. i.e.

function CreateNewFolder(): ReactElement {
  return <MenuItem onClick={() => /* some click behavior */}>Folder</MenuItem>;
}

function Example(): ReactElement {
  return (
    <DropdownMenu id="some-menu-id" buttonChildren="New">
      <CreateNewFolder />
      <AnotherAction />
      <AndAnotherAction />
    </DropdownMenu>
  );
}

Additional changes:

  • There will be some new hooks to handle creating custom menus
  • Support hover mode by default

v6.0.0 Release Target

Improved Select API and Behavior

What I'm mostly trying to accomplish with these changes are:

  • fix the terrible typescript types so that you don't need to do: onChange={(value) => setValue(value as SomeTypeUnion)}
  • Allow the Select to handle validation like the TextField and TextArea components
    • mostly want the required behavior to start working

The Select component will now render an invisible <select> element and all the <option>s instead of using an <input type="hidden" value={CURRENT_VALUE} />. This change makes it so that the Select component can now correctly handle form validation.

I'm still working out the API, but I think it'll mimic the new Menu API since it follows how you'd use a native <select> and allows for elements to be rendered without first creating a list of options:

<Select {...props}>
  {options.map(({ label, value }) => <Option value={value}>{label}</Option>
</Select>
const [value, setValue] = useState("");

<Select {...props}>
  <OptGroup label="A">
   // the `label` might be optional since I can automatically pull the text content via refs
    <Option label="Alabama" value="AL" />
    <Option value="AK"><strong>Alaska</strong></Option>
  </OptGroup>
  <Divider />
  <OptGroup label={<span>C</span>}>
    <Option label="California" value="CA" disabled />
  </OptGroup>
  <Option label="Delaware" value="DE" />
</Select>

Another alternative is something like this (less preferred now):

interface SearchableListboxOption {
  label: string;
  value: string;
  // this would be rendered instead of the `label` if exists. The `label` string is required since this is how the "type to focus" behavior is implemented to mimic the native `<select>` element
  children?: ReactNode;
  disabled?: boolean;

  // Like other places if any of these keys are part of the `ListItemProps`, they will be passed correctly and rendered (like addons, secondaryText, etc)
  [key: string]: unknown;
}
type IgnoredListboxOption = Record<string, unknown> | ReactElement;
type ListboxOption = SearchableListboxOption  | IgnoredListboxOption;

const options: readonly ListboxOption[] = [
  { label: "Some label", value: "a" },
  { label: "Another Label', value: "b" },
  <Divider key="divider-1" />,
  { label: "Final Label", value: "c", disabled: true },
];

const [value, setValue] = useState("");

<Select
  id="some-select-id"
  options={options}
  label="Some label"
  value={value}
  setValue={setValue}
  required
  // this is optional (ha) if the default behavior doesn't work for your use-case. I
  renderOptions={(option) => {
    // this will pretty much be the default implementation
    return <Option {...option}>{option.children ?? option.label}</Option>
  }} 
/>

Quick video example of changes:

Screen.Recording.2021-11-24.at.12.30.20.PM.mov

Remove @react-md/autocomplete package

With all the new Select changes listed above, I think it would be better just to integrate the AutoComplete component into the @react-md/form package with a new useAutoComplete hook and AutoComplete component.

@mlaursen mlaursen added this to the v5.0.0 milestone Nov 24, 2021
@mlaursen mlaursen changed the title v5.0.0 Release Target v5.0.0 and v6.0.0 Release Target Jan 30, 2022
@mlaursen mlaursen modified the milestones: v5.0.0, v6.0.0 Jan 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant