diff --git a/.eslintrc b/.eslintrc index ae0e21c16..d9041ccd5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,6 @@ { "parser": "@babel/eslint-parser", - "extends": ["standard", "standard-react", "standard-jsx", "prettier"], + "extends": ["standard", "standard-react", "standard-jsx", "prettier", "plugin:react-hooks/recommended"], "plugins": ["babel", "react", "promise", "prettier"], "env": { "browser": true diff --git a/.github/workflows/reviewer-lottery.yaml b/.github/workflows/reviewer-lottery.yaml index a01abeb36..34c820edb 100644 --- a/.github/workflows/reviewer-lottery.yaml +++ b/.github/workflows/reviewer-lottery.yaml @@ -9,6 +9,6 @@ jobs: if: ${{ github.actor == 'dependabot[bot]' }} steps: - uses: actions/checkout@v3 - - uses: uesteibar/reviewer-lottery@v2 + - uses: uesteibar/reviewer-lottery@v3 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b1c97cb5..fc981fcd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,16 @@ ### Dependency updates +## [22.2.0] - 2023-07-11 + +### Added + +- `Toggle`: Props `labelPosition` and `fullWidth`. ([@qubis741](https://github.com/qubis741) in [#2710](https://github.com/teamleadercrm/ui/pull/2710)) + +### Changed + +- `Popover`: Aligned the popover shadows with our design spec. ([@lowiebenoot](https://https://github.com/lowiebenoot) in [#2708](https://github.com/teamleadercrm/ui/pull/2708)) + ## [22.1.1] - 2023-06-14 ### Fixed diff --git a/package.json b/package.json index 9e732f85d..a17478532 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@teamleader/ui", "description": "Teamleader UI library", - "version": "22.1.1", + "version": "22.2.0", "author": "Teamleader ", "bugs": { "url": "https://github.com/teamleadercrm/ui/issues" @@ -35,7 +35,7 @@ "@teamleader/ui-icons": "^2.1.0", "@teamleader/ui-illustrations": "^1.10.0", "@teamleader/ui-typography": "^2.0.2", - "@teamleader/ui-utilities": "^0.2.0", + "@teamleader/ui-utilities": "^0.2.2", "classnames": "^2.2.5", "draft-js": "0.11.7", "lodash.omit": "^4.5.0", @@ -117,6 +117,7 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-promise": "^6.0.0", "eslint-plugin-react": "^7.30.1", + "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-standard": "^5.0.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^6.0.0", @@ -134,7 +135,7 @@ "postcss-import": "^15.0.0", "postcss-loader": "^7.0.1", "postcss-nested": "^6.0.0", - "postcss-preset-env": "8.3.1", + "postcss-preset-env": "9.0.0", "postcss-pseudoelements": "^5.0.0", "postcss-reporter": "^7.0.5", "prettier": "2.8.0", diff --git a/src/components/buttonGroup/buttonGroup.stories.tsx b/src/components/buttonGroup/buttonGroup.stories.tsx index d7ea271e7..2004dba6d 100644 --- a/src/components/buttonGroup/buttonGroup.stories.tsx +++ b/src/components/buttonGroup/buttonGroup.stories.tsx @@ -18,7 +18,7 @@ export const Normal: ComponentStory = (args) => ( ); -export const withActive = () => { +export const WithActive = () => { const [value, setValue] = useState('option2'); const handleChange = (value: string) => { @@ -34,4 +34,4 @@ export const withActive = () => { ); }; -withActive.storyName = 'With active'; +WithActive.storyName = 'With active'; diff --git a/src/components/datagrid/DataGrid.tsx b/src/components/datagrid/DataGrid.tsx index e4f9e88ec..f2c064991 100644 --- a/src/components/datagrid/DataGrid.tsx +++ b/src/components/datagrid/DataGrid.tsx @@ -74,6 +74,7 @@ export const DataGrid: DatagridComponent = ({ .reduce((accumulatedChildWidth, currentChildWidth) => accumulatedChildWidth + currentChildWidth, 0), ) .reduce((maxRowWidth, currentRowWidth) => (currentRowWidth > maxRowWidth ? currentRowWidth : maxRowWidth), 0), + // eslint-disable-next-line react-hooks/exhaustive-deps [rowNodes, rowNodes.size], ); const childrenArray: (ReactElement | ReactElement[])[] = !Array.isArray(children) ? [children] : children; @@ -139,6 +140,7 @@ export const DataGrid: DatagridComponent = ({ useEffect(() => { setSelectedRows([]); handleSelectionChange([]); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [comparableId]); const classNames = cx( diff --git a/src/components/datepicker/DatePickerInput.tsx b/src/components/datepicker/DatePickerInput.tsx index e4252c7bc..70d9632d3 100644 --- a/src/components/datepicker/DatePickerInput.tsx +++ b/src/components/datepicker/DatePickerInput.tsx @@ -143,6 +143,7 @@ function DatePickerInput({ } } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [inputValue, selectedDate], ); useEffect(() => { @@ -159,6 +160,7 @@ function DatePickerInput({ } else { setSelectedDate(undefined); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [preselectedDate]); const handleInputFocus = (event: React.FocusEvent) => { diff --git a/src/components/datepicker/MonthPicker.tsx b/src/components/datepicker/MonthPicker.tsx index 0c847d4fe..367bd8e73 100644 --- a/src/components/datepicker/MonthPicker.tsx +++ b/src/components/datepicker/MonthPicker.tsx @@ -69,6 +69,7 @@ const MonthPickerUnary: GenericComponent = ({ date, locale, lo const selectedMonth = useMemo( () => date && localeUtils && { value: date.getMonth().toString(), label: localeUtils.formatMonthTitle(date, locale) }, + // eslint-disable-next-line react-hooks/exhaustive-deps [date], ); @@ -96,6 +97,7 @@ const MonthPickerSplit: GenericComponent = ({ date, locale, lo const [yearInput, setYearInput] = useState(date && `${date.getFullYear()}`); const selectedMonth = useMemo( () => date && localeUtils && { value: date.getMonth(), label: localeUtils.formatMonthTitle(date, locale) }, + // eslint-disable-next-line react-hooks/exhaustive-deps [date], ); const selectedYear = useMemo(() => date && date.getFullYear(), [date]); diff --git a/src/components/dialog/Dialog.tsx b/src/components/dialog/Dialog.tsx index c72f6b861..32fe95c68 100644 --- a/src/components/dialog/Dialog.tsx +++ b/src/components/dialog/Dialog.tsx @@ -65,6 +65,7 @@ const Dialog: GenericComponent = ({ }, [bodyRef]); useEffect(() => { handleScrollShadow(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [bodyRef, otherProps.active]); useResizeDetector({ diff --git a/src/components/dialog/useDraggable.ts b/src/components/dialog/useDraggable.ts index ad9cd43ba..c61448c79 100644 --- a/src/components/dialog/useDraggable.ts +++ b/src/components/dialog/useDraggable.ts @@ -51,6 +51,7 @@ const useDraggable = ({ active = false, dragTargetRef, dragHandleRef }: UseDragg return function cleanup() { currentDragHandleRef.removeEventListener('mousedown', mouseDownHandler); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [active]); }; diff --git a/src/components/emailSelector/EmailSelector.tsx b/src/components/emailSelector/EmailSelector.tsx index 62611c000..3e000f3ce 100644 --- a/src/components/emailSelector/EmailSelector.tsx +++ b/src/components/emailSelector/EmailSelector.tsx @@ -76,6 +76,7 @@ const EmailSelector: GenericComponent = ({ !disableRemovalOfFirst && setEditingLabel(index); setSelection(selection.filter((selection, i) => i <= index || selection.email.trim() !== '')); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [setEditingLabel, setSelection, selection], ); diff --git a/src/components/emailSelector/Label.tsx b/src/components/emailSelector/Label.tsx index 1e75d3cb7..a7f3b6136 100644 --- a/src/components/emailSelector/Label.tsx +++ b/src/components/emailSelector/Label.tsx @@ -173,6 +173,7 @@ const Label: GenericComponent = ({ } } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [ onFinish, index, diff --git a/src/components/input/input.stories.tsx b/src/components/input/input.stories.tsx index 8ae78520a..226bbb244 100644 --- a/src/components/input/input.stories.tsx +++ b/src/components/input/input.stories.tsx @@ -86,7 +86,7 @@ export default { }, } as ComponentMeta; -export const input: ComponentStory = (args) => { +export const BasicInput: ComponentStory = (args) => { const [value, setValue] = useState(''); const handleChange = (event: ChangeEvent, value: string) => { @@ -96,8 +96,8 @@ export const input: ComponentStory = (args) => { return ; }; -input.storyName = 'Input'; -input.args = { +BasicInput.storyName = 'Input'; +BasicInput.args = { bold: false, disabled: false, error: '', @@ -112,7 +112,7 @@ input.args = { textAlignRight: false, width: '', }; -input.argTypes = { +BasicInput.argTypes = { ...inputArgTypes, type: { control: 'select', @@ -120,7 +120,7 @@ input.argTypes = { }, }; -export const inputConnected: ComponentStory = (args) => { +export const InputConnected: ComponentStory = (args) => { const [value, setValue] = useState(''); const handleChange = (event: ChangeEvent, value: string) => { @@ -130,13 +130,13 @@ export const inputConnected: ComponentStory = (args) => { return ; }; -inputConnected.storyName = 'Input with connected'; -inputConnected.args = { - ...input.args, +InputConnected.storyName = 'Input with connected'; +InputConnected.args = { + ...BasicInput.args, connectedLeft, connectedRight, }; -inputConnected.argTypes = { +InputConnected.argTypes = { ...inputArgTypes, type: { control: 'select', @@ -144,7 +144,7 @@ inputConnected.argTypes = { }, }; -export const inputPrefixSuffix: ComponentStory = (args) => { +export const InputPrefixSuffix: ComponentStory = (args) => { const [value, setValue] = useState(''); const handleChange = (event: ChangeEvent, value: string) => { @@ -154,13 +154,13 @@ export const inputPrefixSuffix: ComponentStory = (args) => { return ; }; -inputPrefixSuffix.storyName = 'Input with prefix and suffix'; -inputPrefixSuffix.args = { - ...input.args, +InputPrefixSuffix.storyName = 'Input with prefix and suffix'; +InputPrefixSuffix.args = { + ...BasicInput.args, prefix, suffix, }; -inputPrefixSuffix.argTypes = { +InputPrefixSuffix.argTypes = { ...inputArgTypes, type: { control: 'select', @@ -168,7 +168,7 @@ inputPrefixSuffix.argTypes = { }, }; -export const numericInput: ComponentStory = (args) => { +export const BasicNumericInput: ComponentStory = (args) => { const [value, setValue] = useState(6); const handleChange = (event: ChangeEvent, value: string) => { @@ -178,8 +178,8 @@ export const numericInput: ComponentStory = (args) => { return ; }; -numericInput.storyName = 'NumericInput'; -numericInput.args = { +BasicNumericInput.storyName = 'NumericInput'; +BasicNumericInput.args = { bold: false, disabled: false, error: '', @@ -197,9 +197,9 @@ numericInput.args = { textAlignRight: false, width: '', }; -numericInput.argTypes = { ...inputArgTypes, stepper: { control: 'select', options: stepperOptions } }; +BasicNumericInput.argTypes = { ...inputArgTypes, stepper: { control: 'select', options: stepperOptions } }; -export const timeInput: ComponentStory = (args) => { +export const BasicTimeInput: ComponentStory = (args) => { const [value, setValue] = useState(''); const handleChange = (event: ChangeEvent) => { @@ -209,8 +209,8 @@ export const timeInput: ComponentStory = (args) => { return ; }; -timeInput.storyName = 'TimeInput'; -timeInput.args = { +BasicTimeInput.storyName = 'TimeInput'; +BasicTimeInput.args = { bold: false, disabled: false, error: '', @@ -224,9 +224,9 @@ timeInput.args = { textAlighRight: false, width: '90px', }; -timeInput.argTypes = inputArgTypes; +BasicTimeInput.argTypes = inputArgTypes; -export const durationInput: ComponentStory = (args) => { +export const BasicDurationInput: ComponentStory = (args) => { const [value, setValue] = useState<{ hours?: number | undefined; minutes?: number | undefined } | undefined>(); const handleChange = (value?: { hours?: number; minutes?: number }) => { @@ -236,9 +236,9 @@ export const durationInput: ComponentStory = (args) => { return ; }; -durationInput.storyName = 'DurationInput'; +BasicDurationInput.storyName = 'DurationInput'; -export const textarea: ComponentStory = (args) => { +export const BasicTextarea: ComponentStory = (args) => { const [value, setValue] = useState(''); const handleChange = (event: ChangeEvent) => { @@ -248,8 +248,8 @@ export const textarea: ComponentStory = (args) => { return