Skip to content

Commit

Permalink
Merge branch 'main' into fix/autoComplete
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris authored Sep 15, 2023
2 parents 8ae608b + a97c7f0 commit 1ed5c55
Show file tree
Hide file tree
Showing 20 changed files with 369 additions and 226 deletions.
5 changes: 5 additions & 0 deletions .changeset/famous-students-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/fuselage": patch
---

Memory leak in `PaginatedMultiSelect`
9 changes: 9 additions & 0 deletions .changeset/giant-parrots-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@rocket.chat/fuselage": patch
"@rocket.chat/fuselage-hooks": patch
"@rocket.chat/logo": patch
"@rocket.chat/onboarding-ui": patch
"@rocket.chat/ui-kit": patch
---

chore: resolve-workspace-deps to publish pkg versions
5 changes: 5 additions & 0 deletions .changeset/lucky-doors-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/fuselage": patch
---

fix(fuselage): RadioButton a11y best practices improvement
5 changes: 5 additions & 0 deletions .changeset/shaggy-carrots-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/icons": minor
---

feat(icons): Add rocketchat icon
17 changes: 14 additions & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
build-and-test:
name: Build and Test
Expand Down Expand Up @@ -88,13 +90,22 @@ jobs:
- run: yarn install
if: steps.yarn-cache.outputs.cache-hit != 'true'

- uses: changesets/action@v1
with:
publish: yarn release
- name: Create Release Pull Request
id: changesets
uses: changesets/action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Resolve workspace dependencies
if: steps.changesets.outputs.hasChangesets == 'false'
run: yarn resolve-workspace-deps

- name: Publish to npm
if: steps.changesets.outputs.hasChangesets == 'false'
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: yarn release

publish-to-gh-pages:
name: Publish to GitHub Pages
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@rocket.chat/fuselage-root",
"name": "@rocket.chat/fuselage-monorepo",
"private": true,
"version": "0.31.25",
"workspaces": [
"packages/*",
"tools/*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,26 @@ import {
useMutableCallback,
useResizeObserver,
} from '@rocket.chat/fuselage-hooks';
import type {
SyntheticEvent,
ComponentProps,
Ref,
ReactElement,
FormEvent,
import React, {
type ComponentProps,
type ReactElement,
useState,
useRef,
} from 'react';
import React, { useState, useRef, useCallback, forwardRef, memo } from 'react';

import { prevent } from '../../helpers/prevent';
import AnimatedVisibility from '../AnimatedVisibility';
import Box from '../Box';
import Chip from '../Chip';
import Flex from '../Flex';
import { Icon } from '../Icon';
import { InputBox } from '../InputBox';
import Margins from '../Margins';
import { useVisible } from '../Options/useVisible';
import { OptionsPaginated } from '../OptionsPaginated';
import Position from '../Position';
import SelectAddon from '../Select/SelectAddon';
import SelectFocus from '../Select/SelectFocus';

const SelectedOptions = memo<ComponentProps<typeof Chip>>((props) => (
<Chip maxWidth='x150' withTruncatedText {...props} />
));

export type PaginatedMultiSelectOption = {
value: string | number;
label: string;
Expand All @@ -51,7 +44,7 @@ type PaginatedMultiSelectProps = Omit<
anchor?: any;
};

export const PaginatedMultiSelect = ({
const PaginatedMultiSelect = ({
withTitle,
value,
filter,
Expand All @@ -61,7 +54,7 @@ export const PaginatedMultiSelect = ({
anchor: Anchor = SelectFocus,
onChange = () => {},
placeholder,
renderOptions: _Options = OptionsPaginated,
renderOptions: OptionsComponent = OptionsPaginated,
endReached,
...props
}: PaginatedMultiSelectProps) => {
Expand All @@ -73,19 +66,6 @@ export const PaginatedMultiSelect = ({
currentValue.some((opt) => opt.value === option.value)
);

const internalChanged = (option: PaginatedMultiSelectOption) => {
if (currentValue.some((opt) => opt.value === option.value)) {
const newValue = currentValue.filter((opt) => opt.value !== option.value);

setInternalValue(newValue);
return onChange(newValue);
}

const newValue = [...currentValue, option];
setInternalValue(newValue);
return onChange(newValue);
};

const [visible, hide, show] = useVisible();

const ref = useRef<HTMLInputElement>(null);
Expand All @@ -101,13 +81,32 @@ export const PaginatedMultiSelect = ({
}
});

const handleMouseDown = useMutableCallback(
(option: PaginatedMultiSelectOption) => (e: SyntheticEvent) => {
prevent(e);
internalChanged(option);
return false;
const addOption = (value: unknown) => {
const option = options.find((opt) => opt.value === value);
if (!option) {
return;
}
);

const newValue = [...currentValue, option];
setInternalValue(newValue);
onChange(newValue);
};

const removeOption = (value: unknown) => {
const newValue = currentValue.filter((opt) => opt.value !== value);

setInternalValue(newValue);
onChange(newValue);
};

const toggleOption = (value: unknown) => {
if (currentValue.some((opt) => opt.value === value)) {
removeOption(value);
return;
}

addOption(value);
};

return (
<Box
Expand Down Expand Up @@ -143,17 +142,21 @@ export const PaginatedMultiSelect = ({
children={placeholder ?? null}
/>

{selectedOptions.map((option, index: number) => (
<SelectedOptions
{...(withTitle && {
title: option.label,
})}
{selectedOptions.map(({ value, label }, index) => (
<Chip
key={value ?? index}
maxWidth='x150'
withTruncatedText
title={withTitle ? label : undefined}
tabIndex={-1}
role='option'
key={index}
onMouseDown={handleMouseDown(option)}
children={option.label}
/>
onClick={(e) => {
prevent(e);
removeOption(value);
}}
>
{label}
</Chip>
))}
</Margins>
</Box>
Expand All @@ -179,8 +182,7 @@ export const PaginatedMultiSelect = ({
</Flex.Item>
<AnimatedVisibility visibility={visible}>
<Position anchor={containerRef}>
<_Options
withTitle={withTitle}
<OptionsComponent
width={borderBoxSize.inlineSize}
onMouseDown={prevent}
multiple
Expand All @@ -189,65 +191,14 @@ export const PaginatedMultiSelect = ({
options={options}
cursor={-1}
endReached={endReached}
onSelect={([value, label]) =>
internalChanged({ value: value as string, label })
}
onSelect={([value]) => {
toggleOption(value);
}}
/>
</Position>
</AnimatedVisibility>
</Box>
);
};

type PaginatedMultiSelectFilteredProps = Omit<
PaginatedMultiSelectProps,
'filter'
> & {
filter?: string;
setFilter?: (value: string) => void;
};

export const PaginatedMultiSelectFiltered = ({
filter,
setFilter,
options,
placeholder,
...props
}: PaginatedMultiSelectFilteredProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
const anchor = useCallback(
forwardRef(
(
{
children: _children,
filter,
...props
}: ComponentProps<typeof InputBox>,
ref: Ref<HTMLInputElement>
) => (
<Flex.Item grow={1}>
<InputBox.Input
ref={ref}
placeholder={placeholder}
value={filter}
onInput={(e: FormEvent<HTMLInputElement>) =>
setFilter?.(e.currentTarget.value)
}
{...props}
rcx-input-box--undecorated
/>
</Flex.Item>
)
),
[]
);

return (
<PaginatedMultiSelect
filter={filter}
options={options}
{...props}
anchor={anchor}
/>
);
};
export default PaginatedMultiSelect;
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export default {
},
} as ComponentMeta<typeof PaginatedMultiSelectFiltered>;

const Template: ComponentStory<typeof PaginatedMultiSelectFiltered> = (
args
) => <PaginatedMultiSelectFiltered {...args} />;

export const Normal: ComponentStory<typeof PaginatedMultiSelectFiltered> = (
args
) => {
Expand All @@ -33,16 +37,12 @@ export const Normal: ComponentStory<typeof PaginatedMultiSelectFiltered> = (
);
};

export const Errored: ComponentStory<typeof PaginatedMultiSelectFiltered> = (
args
) => <PaginatedMultiSelectFiltered {...args} />;
export const Errored = Template.bind({});
Errored.args = {
error: true,
};

export const Disabled: ComponentStory<typeof PaginatedMultiSelectFiltered> = (
args
) => <PaginatedMultiSelectFiltered {...args} />;
export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
};
Loading

0 comments on commit 1ed5c55

Please sign in to comment.