@mistertemp/libs-front-shared 1.1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.1](https://github.com/mistertemp/shared-libs-front/compare/@mistertemp/libs-front-shared@1.2.0...@mistertemp/libs-front-shared@1.2.1) (2025-08-08)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * fix initial value of input in TextFilter ([#592](https://github.com/mistertemp/shared-libs-front/issues/592)) ([e3ca8a6](https://github.com/mistertemp/shared-libs-front/commit/e3ca8a690999ae365d904a980eef2283d7811346))
9
+
10
+ ## [1.2.0](https://github.com/mistertemp/shared-libs-front/compare/@mistertemp/libs-front-shared@1.1.2...@mistertemp/libs-front-shared@1.2.0) (2025-07-25)
11
+
12
+
13
+ ### Features
14
+
15
+ * **Filters:** add accountFilter ([#580](https://github.com/mistertemp/shared-libs-front/issues/580)) ([1179a39](https://github.com/mistertemp/shared-libs-front/commit/1179a39832cd57ced44dd3f79322ea6b7b72af66))
16
+
3
17
  ## [1.1.2](https://github.com/mistertemp/shared-libs-front/compare/@mistertemp/libs-front-shared@1.1.1...@mistertemp/libs-front-shared@1.1.2) (2025-05-06)
4
18
 
5
19
 
package/index.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @module @mistertemp/libs-front-shared
3
+ * @description Main entry point for the shared front-end library
4
+ * Exports all components, hooks, and type definitions
5
+ */
6
+
1
7
  export * from './src/components';
2
8
  export * from './src/hooks';
3
9
  export * from './src/typings';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mistertemp/libs-front-shared",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "main": "index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "scripts": {
@@ -22,9 +22,9 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@axe-core/react": "4.10.0",
25
- "@mistertemp/design-system": "12.0.0",
25
+ "@mistertemp/design-system": "12.3.0",
26
26
  "@mistertemp/libs-work-environments": "0.8.1",
27
- "@mistertemp/types-shared": "2.2.0",
27
+ "@mistertemp/types-shared": "2.3.0",
28
28
  "@testing-library/dom": "10.4.0",
29
29
  "@testing-library/jest-dom": "6.6.2",
30
30
  "@testing-library/react": "12.1.5",
@@ -38,13 +38,13 @@
38
38
  "@types/react-transition-group": "4.4.10",
39
39
  "@typescript-eslint/eslint-plugin": "7.18.0",
40
40
  "@typescript-eslint/parser": "7.18.0",
41
- "@vitejs/plugin-react-swc": "3.9.0",
41
+ "@vitejs/plugin-react-swc": "3.10.0",
42
42
  "date-fns": "2.30.0",
43
43
  "eslint": "8.57.0",
44
44
  "eslint-config-prettier": "9.1.0",
45
45
  "eslint-plugin-import": "2.31.0",
46
46
  "eslint-plugin-jsx-a11y": "6.10.0",
47
- "eslint-plugin-prettier": "5.2.1",
47
+ "eslint-plugin-prettier": "5.4.0",
48
48
  "eslint-plugin-react": "7.37.1",
49
49
  "eslint-plugin-react-hooks": "4.6.0",
50
50
  "eslint-plugin-simple-import-sort": "12.1.0",
@@ -56,21 +56,21 @@
56
56
  "identity-obj-proxy": "3.0.0",
57
57
  "jest-environment-jsdom": "29.7.0",
58
58
  "lodash": "4.17.21",
59
- "prettier": "3.4.1",
59
+ "prettier": "3.5.3",
60
60
  "react": "17.0.2",
61
61
  "react-dom": "17.0.2",
62
- "react-hook-form": "7.53.0",
62
+ "react-hook-form": "7.57.0",
63
63
  "react-i18next": "14.1.0",
64
- "react-router-dom": "6.28.0",
64
+ "react-router-dom": "6.30.0",
65
65
  "react-transition-group": "4.4.5",
66
- "sass": "1.87.0",
67
- "stylelint": "16.19.1",
66
+ "sass": "1.89.0",
67
+ "stylelint": "16.20.0",
68
68
  "stylelint-config-idiomatic-order": "10.0.0",
69
69
  "stylelint-config-standard-scss": "14.0.0",
70
70
  "stylelint-prettier": "5.0.3",
71
- "ts-jest": "29.2.3",
71
+ "ts-jest": "29.3.2",
72
72
  "ts-node": "10.9.1",
73
- "typescript": "5.7.2",
73
+ "typescript": "5.8.3",
74
74
  "vite": "6.3.4",
75
75
  "vite-plugin-environment": "1.1.3",
76
76
  "vite-plugin-svgr": "4.3.0"
@@ -0,0 +1,45 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { useBundledTranslation } from '../../hooks';
4
+ import fr from '../../locales/fr/scc-common-filters.json';
5
+ import it from '../../locales/it/scc-common-filters.json';
6
+ import { Filter, FilterDropdownOption, FilterProps } from '../Filter';
7
+
8
+ export type AccountFilterProps = Omit<FilterProps, 'name' | 'options'> & {
9
+ name?: string;
10
+ onInputValueChanged?: (value: string | undefined) => void;
11
+ isLoading?: boolean;
12
+ options: FilterDropdownOption[];
13
+ };
14
+
15
+ export const AccountFilter = ({
16
+ name = 'account',
17
+ onInputValueChanged,
18
+ isLoading = false,
19
+ options,
20
+ ...props
21
+ }: AccountFilterProps) => {
22
+ const { t } = useBundledTranslation('scc-common-filters', { fr, it });
23
+ const [inputValue, setInputValue] = useState('');
24
+
25
+ return (
26
+ <Filter
27
+ name={name}
28
+ placeholder={props.placeholder}
29
+ options={options}
30
+ listProps={{
31
+ search: {
32
+ value: inputValue,
33
+ isLoading,
34
+ onInputValueChanged: (value) => {
35
+ setInputValue(value ?? '');
36
+ onInputValueChanged?.(value);
37
+ },
38
+ placeholder: t('scc-common-filters:filters.account.placeholder'),
39
+ },
40
+ withSelectedTags: true,
41
+ }}
42
+ {...props}
43
+ />
44
+ );
45
+ };
@@ -0,0 +1,70 @@
1
+ import { fireEvent, screen, waitFor } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import React from 'react';
4
+
5
+ import { render } from '../../../../.jest/reactTestingLibrary.config';
6
+ import { AccountFilter } from '../AccountFilter';
7
+
8
+ describe('AccountFilter', () => {
9
+ beforeEach(() => {
10
+ jest.clearAllMocks();
11
+ });
12
+
13
+ it('should display all account options', async () => {
14
+ render(
15
+ <AccountFilter
16
+ options={[
17
+ { id: 'testId', label: 'label' },
18
+ { id: 'testId2', label: 'label2' },
19
+ ]}
20
+ />,
21
+ );
22
+
23
+ fireEvent.click(screen.getByTestId('filters+account+trigger-button'));
24
+
25
+ expect(screen.getByTestId(`filters+account_option_testId`)).toBeInTheDocument();
26
+ expect(screen.getByTestId(`filters+account_option_testId2`)).toBeInTheDocument();
27
+ });
28
+
29
+ it('should select one account', async () => {
30
+ const mock = jest.fn();
31
+
32
+ render(
33
+ <AccountFilter
34
+ onDropdownValueChanged={mock}
35
+ options={[
36
+ { id: 'testId', label: 'label' },
37
+ { id: 'testId2', label: 'label2' },
38
+ ]}
39
+ />,
40
+ );
41
+
42
+ fireEvent.click(screen.getByTestId('filters+account+trigger-button'));
43
+
44
+ fireEvent.click(screen.getByTestId(`filters+account_option_testId`));
45
+
46
+ await userEvent.click(document.body);
47
+
48
+ await waitFor(() => {
49
+ expect(mock).toHaveBeenCalledWith(['testId']);
50
+ });
51
+ });
52
+
53
+ it('should set placeholder title', async () => {
54
+ const newPlaceholder = 'New placeholder';
55
+
56
+ render(
57
+ <AccountFilter
58
+ placeholder={newPlaceholder}
59
+ options={[
60
+ { id: 'testId', label: 'label' },
61
+ { id: 'testId2', label: 'label2' },
62
+ ]}
63
+ />,
64
+ );
65
+
66
+ expect(screen.getByTestId('filters+account+trigger-button-title')).toHaveTextContent(
67
+ newPlaceholder,
68
+ );
69
+ });
70
+ });
@@ -0,0 +1 @@
1
+ export * from './AccountFilter';
@@ -3,16 +3,44 @@ import { format, parse } from 'date-fns';
3
3
  import React from 'react';
4
4
  import { Controller, FieldPath, FieldValues, UseControllerProps } from 'react-hook-form';
5
5
 
6
+ /**
7
+ * Default date format used for the date input
8
+ */
6
9
  const controlledInputDateDefaultFormat = 'dd/MM/yyyy';
7
10
 
11
+ /**
12
+ * Converts a form date value string to the format expected by the date input
13
+ *
14
+ * @param {string | null | undefined} formDateValue - The date value from the form
15
+ * @param {string} dateFormat - The format of the date in the form
16
+ * @returns {string} The formatted date string for the input
17
+ */
8
18
  const toDateInputValue = (formDateValue: string | null | undefined, dateFormat: string) =>
9
19
  formDateValue
10
20
  ? format(parse(formDateValue, dateFormat, new Date()), controlledInputDateDefaultFormat)
11
21
  : '';
12
22
 
23
+ /**
24
+ * Converts a Date object to a formatted string for the form
25
+ *
26
+ * @param {Date | null | undefined} valueAsDate - The date object from the input
27
+ * @param {string} dateFormat - The target format for the form value
28
+ * @returns {string} The formatted date string
29
+ */
13
30
  const toDateFormValue = (valueAsDate: Date | null | undefined, dateFormat: string) =>
14
31
  valueAsDate ? format(valueAsDate, dateFormat) : '';
15
32
 
33
+ /**
34
+ * Props for the ControlledInputDate component
35
+ *
36
+ * @template TFieldValues - Type of the form values
37
+ * @template TName - Type of the field name
38
+ * @typedef {Object} ControlledInputDateProps
39
+ * @property {Omit<InputProps, 'inputType' | 'value'>} inputProps - Props for the underlying Input component
40
+ * @property {string} [format='dd/MM/yyyy'] - Date format to use
41
+ * @property {string} [minErrorMessage='min exceeded'] - Error message for minimum date validation
42
+ * @property {string} [maxErrorMessage='max exceeded'] - Error message for maximum date validation
43
+ */
16
44
  export type ControlledInputDateProps<
17
45
  TFieldValues extends FieldValues,
18
46
  TName extends FieldPath<TFieldValues>,
@@ -23,6 +51,17 @@ export type ControlledInputDateProps<
23
51
  maxErrorMessage?: string;
24
52
  };
25
53
 
54
+ /**
55
+ * A controlled date input component for use with react-hook-form
56
+ *
57
+ * This component provides a date input that integrates with react-hook-form's
58
+ * Controller component, handling the conversion between form values and input values.
59
+ *
60
+ * @template TFieldValues - Type of the form values
61
+ * @template TName - Type of the field name
62
+ * @param {ControlledInputDateProps<TFieldValues, TName>} props - Component props
63
+ * @returns {JSX.Element} Controlled date input component
64
+ */
26
65
  export const ControlledInputDate = <
27
66
  TFieldValues extends FieldValues = FieldValues,
28
67
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
@@ -3,8 +3,19 @@ import { DEFAULT_TIME_SEPARATOR } from '@mistertemp/design-system/src/components
3
3
  import React from 'react';
4
4
  import { Controller, FieldPath, FieldValues, UseControllerProps } from 'react-hook-form';
5
5
 
6
+ /**
7
+ * Default separator used for time values in form data
8
+ */
6
9
  const controlledInputTimeDefaultSeparator = ':';
7
10
 
11
+ /**
12
+ * Converts a form time value to the format expected by the time input
13
+ *
14
+ * @param {string | null | undefined} formTimeValue - The time value from the form
15
+ * @param {string} inputSeparator - The separator used in the input component
16
+ * @param {string} dataSeparator - The separator used in the form data
17
+ * @returns {string} The formatted time string for the input
18
+ */
8
19
  const toTimeInputValue = (
9
20
  formTimeValue: string | null | undefined,
10
21
  inputSeparator: string,
@@ -13,6 +24,14 @@ const toTimeInputValue = (
13
24
  return formTimeValue?.replace(dataSeparator, inputSeparator) ?? '';
14
25
  };
15
26
 
27
+ /**
28
+ * Converts an input time value to the format expected by the form
29
+ *
30
+ * @param {string | null | undefined} inputValue - The time value from the input
31
+ * @param {string} inputSeparator - The separator used in the input component
32
+ * @param {string} dataSeparator - The separator used in the form data
33
+ * @returns {string} The formatted time string for the form
34
+ */
16
35
  const toTimeFormValue = (
17
36
  inputValue: string | null | undefined,
18
37
  inputSeparator: string,
@@ -21,6 +40,15 @@ const toTimeFormValue = (
21
40
  return inputValue?.replace(inputSeparator, dataSeparator) ?? '';
22
41
  };
23
42
 
43
+ /**
44
+ * Props for the ControlledInputTime component
45
+ *
46
+ * @template TFieldValues - Type of the form values
47
+ * @template TName - Type of the field name
48
+ * @typedef {Object} ControlledInputTimeProps
49
+ * @property {Omit<InputProps, 'inputType' | 'value'>} inputProps - Props for the underlying Input component
50
+ * @property {string} [separator=':'] - Separator to use in the form data
51
+ */
24
52
  export type ControlledInputTimeProps<
25
53
  TFieldValues extends FieldValues,
26
54
  TName extends FieldPath<TFieldValues>,
@@ -29,6 +57,17 @@ export type ControlledInputTimeProps<
29
57
  separator?: string;
30
58
  };
31
59
 
60
+ /**
61
+ * A controlled time input component for use with react-hook-form
62
+ *
63
+ * This component provides a time input that integrates with react-hook-form's
64
+ * Controller component, handling the conversion between form values and input values.
65
+ *
66
+ * @template TFieldValues - Type of the form values
67
+ * @template TName - Type of the field name
68
+ * @param {ControlledInputTimeProps<TFieldValues, TName>} props - Component props
69
+ * @returns {JSX.Element} Controlled time input component
70
+ */
32
71
  export const ControlledInputTime = <
33
72
  TFieldValues extends FieldValues = FieldValues,
34
73
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
@@ -8,6 +8,17 @@ import {
8
8
  } from '@mistertemp/design-system';
9
9
  import React, { MouseEvent, useContext } from 'react';
10
10
 
11
+ /**
12
+ * Props for the CopyToClipboard component
13
+ *
14
+ * @typedef {Object} CopyToClipboardProps
15
+ * @property {string | null} [value] - The text value to copy to clipboard
16
+ * @property {string} [className] - Additional CSS class name
17
+ * @property {SvgIcon} [icon=DuplicateSvg] - Icon to display on the button
18
+ * @property {string | Omit<ToastProps, 'id'>} [toast] - Toast message or props to show after copying
19
+ * @property {Function} [onCopy] - Callback function triggered after copying
20
+ * @property {string} [data-testid='copyToClipboard'] - Test ID for testing
21
+ */
11
22
  export type CopyToClipboardProps = {
12
23
  value?: string | null;
13
24
  className?: string;
@@ -17,6 +28,15 @@ export type CopyToClipboardProps = {
17
28
  'data-testid'?: string;
18
29
  };
19
30
 
31
+ /**
32
+ * A button component that copies text to the clipboard when clicked
33
+ *
34
+ * This component provides a simple way to add copy-to-clipboard functionality
35
+ * with optional toast notification and callback.
36
+ *
37
+ * @param {CopyToClipboardProps} props - Component props
38
+ * @returns {JSX.Element} Copy to clipboard button
39
+ */
20
40
  export const CopyToClipboard = ({
21
41
  value,
22
42
  className,
@@ -22,6 +22,18 @@ import itFilters from '../../locales/it/scc-common-filters.json';
22
22
  import styles from './DateFilter.module.scss';
23
23
  import { deduceMode, defaultDateFormat, getDisplayValue, sanitizeValue } from './DateFilter.utils';
24
24
 
25
+ /**
26
+ * Props for the DateFilter component
27
+ *
28
+ * @typedef {Object} DateFilterProps
29
+ * @property {string} [name='date'] - Name of the filter
30
+ * @property {string} [format] - Date format to use for display
31
+ * @property {Locale} [locale] - Date-fns locale to use
32
+ * @property {Object} [selectorProps] - Props for the dropdown selector trigger
33
+ * @property {MixedDatePickerSelection} [dropdownValue] - Currently selected date(s)
34
+ * @property {Function} [onDropdownValueChanged] - Callback when date selection changes
35
+ * @property {DatePickerProps['availableModes']} [modes] - Available date picker modes
36
+ */
25
37
  export type DateFilterProps = Omit<
26
38
  DropdownProps,
27
39
  'trigger' | 'onOpenChange' | 'dropdownValue' | 'onDropdownValueChanged' | 'withCTA' | 'ctaTitle'
@@ -35,6 +47,15 @@ export type DateFilterProps = Omit<
35
47
  modes?: DatePickerProps['availableModes'];
36
48
  };
37
49
 
50
+ /**
51
+ * A date filter component with dropdown selection
52
+ *
53
+ * This component provides a date picker in a dropdown format, supporting
54
+ * single date, multiple dates, and date range selection modes.
55
+ *
56
+ * @param {DateFilterProps} props - Component props
57
+ * @returns {JSX.Element} Date filter component
58
+ */
38
59
  export const DateFilter: VFC<DateFilterProps> = ({
39
60
  name = 'date',
40
61
  'data-testid': dataTestId = `filters+${name}`,
@@ -6,16 +6,44 @@ import {
6
6
  import { format, isDate as isDateFn, min } from 'date-fns';
7
7
  import { DateRange } from 'react-day-picker';
8
8
 
9
+ /**
10
+ * Default date format used for displaying dates
11
+ */
9
12
  export const defaultDateFormat = 'dd/MM/yy';
10
13
 
14
+ /**
15
+ * Type guard to check if a selection is an array of dates
16
+ *
17
+ * @param {MixedDatePickerSelection} selection - The date selection to check
18
+ * @returns {boolean} True if selection is an array of dates
19
+ */
11
20
  const isMultiple = (selection: MixedDatePickerSelection): selection is Date[] =>
12
21
  Array.isArray(selection);
13
22
 
23
+ /**
24
+ * Type guard to check if a selection is a date range
25
+ *
26
+ * @param {MixedDatePickerSelection} selection - The date selection to check
27
+ * @returns {boolean} True if selection is a date range
28
+ */
14
29
  const isRange = (selection: MixedDatePickerSelection): selection is DateRange =>
15
30
  typeof selection === 'object' && 'from' in selection;
16
31
 
32
+ /**
33
+ * Type guard to check if a selection is a single date
34
+ *
35
+ * @param {MixedDatePickerSelection} selection - The date selection to check
36
+ * @returns {boolean} True if selection is a single date
37
+ */
17
38
  const isDate = (selection: MixedDatePickerSelection): selection is Date => isDateFn(selection);
18
39
 
40
+ /**
41
+ * Determines the appropriate date picker mode based on the selection type
42
+ *
43
+ * @param {MixedDatePickerSelection} selection - The current date selection
44
+ * @param {DatePickerProps['availableModes']} availableModes - Available picker modes
45
+ * @returns {DatePickerMode} The appropriate date picker mode
46
+ */
19
47
  export const deduceMode = (
20
48
  selection: MixedDatePickerSelection,
21
49
  availableModes: DatePickerProps['availableModes'],
@@ -32,6 +60,12 @@ export const deduceMode = (
32
60
  }
33
61
  };
34
62
 
63
+ /**
64
+ * Sanitizes a date selection value, handling empty objects
65
+ *
66
+ * @param {MixedDatePickerSelection | object} value - The value to sanitize
67
+ * @returns {MixedDatePickerSelection} The sanitized value
68
+ */
35
69
  export const sanitizeValue = (
36
70
  value: MixedDatePickerSelection | object,
37
71
  ): MixedDatePickerSelection => {
@@ -46,6 +80,13 @@ export const sanitizeValue = (
46
80
  return value as MixedDatePickerSelection;
47
81
  };
48
82
 
83
+ /**
84
+ * Generates a display string for the current date selection
85
+ *
86
+ * @param {MixedDatePickerSelection} selection - The date selection
87
+ * @param {string} dateFormat - The format to use for displaying dates
88
+ * @returns {string | undefined} The formatted display string or undefined if no selection
89
+ */
49
90
  export const getDisplayValue = (
50
91
  selection: MixedDatePickerSelection,
51
92
  dateFormat: string,
@@ -9,6 +9,9 @@ import fr from '../../locales/fr/scc-common-filters.json';
9
9
  import it from '../../locales/it/scc-common-filters.json';
10
10
  import { Filter, FilterDropdownOption, FilterProps } from '../Filter';
11
11
 
12
+ /**
13
+ * Default fuzzy search options for environment filtering
14
+ */
12
15
  const DEFAULT_FUSE_OPTIONS: IFuseOptions<FilterDropdownOption<ENVIRONMENTS_CODE>> = {
13
16
  isCaseSensitive: false,
14
17
  shouldSort: true,
@@ -18,16 +21,35 @@ const DEFAULT_FUSE_OPTIONS: IFuseOptions<FilterDropdownOption<ENVIRONMENTS_CODE>
18
21
  threshold: 0.2,
19
22
  };
20
23
 
24
+ /**
25
+ * Props for the EnvironmentFilter component
26
+ *
27
+ * @typedef {Object} EnvironmentFilterProps
28
+ * @property {string} [name='environment'] - Name of the filter
29
+ * @property {IFuseOptions<FilterDropdownOption<ENVIRONMENTS_CODE>>} [fuseOptions] - Custom fuzzy search options
30
+ */
21
31
  export type EnvironmentFilterProps = Omit<FilterProps<ENVIRONMENTS_CODE>, 'name' | 'options'> & {
22
32
  name?: string;
23
33
  fuseOptions?: IFuseOptions<FilterDropdownOption<ENVIRONMENTS_CODE>>;
24
34
  };
25
35
 
36
+ /**
37
+ * List of all available environment options
38
+ */
26
39
  const options = getAllFlattenedEnvironments().map((env) => ({
27
40
  id: env.code,
28
41
  label: env.label,
29
42
  }));
30
43
 
44
+ /**
45
+ * A filter component for selecting work environments
46
+ *
47
+ * This component provides a searchable dropdown for selecting one or more
48
+ * work environments from a predefined list.
49
+ *
50
+ * @param {EnvironmentFilterProps} props - Component props
51
+ * @returns {JSX.Element} Environment filter component
52
+ */
31
53
  export const EnvironmentFilter = ({
32
54
  listProps,
33
55
  name = 'environment',
@@ -16,12 +16,37 @@ import { useBundledTranslation } from '../../hooks';
16
16
  import fr from '../../locales/fr/scc-common-filters.json';
17
17
  import it from '../../locales/it/scc-common-filters.json';
18
18
 
19
+ /**
20
+ * Option type for filter dropdown items
21
+ *
22
+ * @template T - Type of the option ID
23
+ * @typedef {Object} FilterDropdownOption
24
+ * @property {T} id - Unique identifier for the option
25
+ * @property {string} label - Display label for the option
26
+ * @property {boolean} [disabled] - Whether the option is disabled
27
+ */
19
28
  export type FilterDropdownOption<T extends string = string> = {
20
29
  id: T;
21
30
  label: string;
22
31
  disabled?: boolean;
23
32
  };
24
33
 
34
+ /**
35
+ * Props for the Filter component
36
+ *
37
+ * @template T - Type of the option ID
38
+ * @typedef {Object} FilterProps
39
+ * @property {Object} [listProps] - Props for the dropdown list provider
40
+ * @property {Object} [selectorProps] - Props for the dropdown selector trigger
41
+ * @property {string} name - Name of the filter
42
+ * @property {string} [data-testid] - Test ID for testing
43
+ * @property {string} [placeholder] - Placeholder text when no selection
44
+ * @property {Array<FilterDropdownOption<T>>} options - Available filter options
45
+ * @property {'single' | 'multiple'} [mode='single'] - Selection mode
46
+ * @property {T[]} [dropdownValue] - Currently selected values
47
+ * @property {Function} [onDropdownValueChanged] - Callback when selection changes
48
+ * @property {string} [ctaTitle] - Title for the CTA button
49
+ */
25
50
  export type FilterProps<T extends string = string> = Omit<
26
51
  DropdownProps,
27
52
  'trigger' | 'dropdownValue' | 'onDropdownValueChanged' | 'onOpenChange'
@@ -41,6 +66,16 @@ export type FilterProps<T extends string = string> = Omit<
41
66
  ctaTitle?: string;
42
67
  };
43
68
 
69
+ /**
70
+ * A generic filter component with dropdown selection
71
+ *
72
+ * This component provides a base for creating dropdown filters with
73
+ * single or multiple selection modes.
74
+ *
75
+ * @template T - Type of the option ID
76
+ * @param {FilterProps<T>} props - Component props
77
+ * @returns {JSX.Element} Filter component
78
+ */
44
79
  export function Filter<T extends string = string>({
45
80
  name,
46
81
  'data-testid': dataTestId = `filters+${name}`,
@@ -13,10 +13,28 @@ import { SearchableFilterProps } from '../../typings';
13
13
  import type { FilterDropdownOption, FilterProps } from '../Filter';
14
14
  import styles from './ProfessionFilter.module.scss';
15
15
 
16
+ /**
17
+ * Props for parent components that use ProfessionFilter
18
+ *
19
+ * @typedef {Omit<FilterProps, 'name' | 'options'>} ProfessionFilterParentProps
20
+ */
16
21
  export type ProfessionFilterParentProps = Omit<FilterProps, 'name' | 'options'>;
17
22
 
23
+ /**
24
+ * Type alias for profession filter dropdown options
25
+ *
26
+ * @typedef {FilterDropdownOption} ProfessionFilterDropdownOption
27
+ */
18
28
  export type ProfessionFilterDropdownOption = FilterDropdownOption;
19
29
 
30
+ /**
31
+ * Props for the ProfessionFilter component
32
+ *
33
+ * @typedef {Object} ProfessionFilterProps
34
+ * @property {string} [placeholder] - Placeholder text when no selection
35
+ * @property {FilterDropdownOption[]} options - Available profession options
36
+ * @property {Function} [onChangeSelectedOptions] - Callback when selection changes
37
+ */
20
38
  type ProfessionFilterProps = Omit<ProfessionFilterParentProps, 'onDropdownValueChanged'> &
21
39
  SearchableFilterProps & {
22
40
  placeholder?: string;
@@ -24,6 +42,15 @@ type ProfessionFilterProps = Omit<ProfessionFilterParentProps, 'onDropdownValueC
24
42
  onChangeSelectedOptions?: (options: FilterDropdownOption[]) => void;
25
43
  };
26
44
 
45
+ /**
46
+ * A filter component for selecting professions/qualifications
47
+ *
48
+ * This component provides a searchable dropdown for selecting one or more
49
+ * professions from a provided list, with support for debounced search.
50
+ *
51
+ * @param {ProfessionFilterProps} props - Component props
52
+ * @returns {JSX.Element} Profession filter component
53
+ */
27
54
  export const ProfessionFilter = ({
28
55
  dropdownValue,
29
56
  onDropdownCTAClick,
@@ -15,6 +15,18 @@ import fr from '../../locales/fr/scc-common-filters.json';
15
15
  import it from '../../locales/it/scc-common-filters.json';
16
16
  import styles from './TextFilter.module.scss';
17
17
 
18
+ /**
19
+ * Props for the TextFilter component
20
+ *
21
+ * @typedef {Object} TextFilterProps
22
+ * @property {string} name - Name of the filter
23
+ * @property {'small' | 'medium'} [size='small'] - Size of the filter
24
+ * @property {string} placeholder - Placeholder text when no value
25
+ * @property {string} [dropdownValue] - Current filter value
26
+ * @property {Function} [onDropdownValueChanged] - Callback when value changes
27
+ * @property {Object} [selectorProps] - Props for the dropdown selector trigger
28
+ * @property {Object} [inputProps] - Props for the input component
29
+ */
18
30
  export type TextFilterProps = Omit<
19
31
  DropdownProps<Record<string, string>>,
20
32
  'id' | 'dropdownValue' | 'onDropdownValueChanged' | 'trigger' | 'withCTA' | 'ctaTitle' | 'size'
@@ -41,6 +53,15 @@ export type TextFilterProps = Omit<
41
53
  >;
42
54
  };
43
55
 
56
+ /**
57
+ * A text input filter component with dropdown
58
+ *
59
+ * This component provides a text input in a dropdown format,
60
+ * allowing users to filter by entering text.
61
+ *
62
+ * @param {TextFilterProps} props - Component props
63
+ * @returns {JSX.Element} Text filter component
64
+ */
44
65
  export const TextFilter: VFC<TextFilterProps> = ({
45
66
  name,
46
67
  placeholder,
@@ -55,7 +76,7 @@ export const TextFilter: VFC<TextFilterProps> = ({
55
76
  }) => {
56
77
  const { t } = useBundledTranslation('scc-common-filters', { fr, it });
57
78
 
58
- const [inputValue, setInputValue] = useState('');
79
+ const [inputValue, setInputValue] = useState(dropdownValue ?? '');
59
80
 
60
81
  const triggerValueChanged = () => {
61
82
  if (inputValue !== dropdownValue) {
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @module Components
3
+ * @description Exports all shared UI components
4
+ */
5
+
6
+ export * from './AccountFilter';
1
7
  export * from './ControlledInputDate';
2
8
  export * from './ControlledInputTime';
3
9
  export * from './CopyToClipboard';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @module Hooks
3
+ * @description Exports all shared React hooks
4
+ */
5
+
1
6
  export * from './useBundledTranslation';
2
7
  export * from './useDebouncedSearchInput';
3
8
  export * from './usePrevious';
@@ -2,11 +2,30 @@ import type { KeyPrefix, Namespace, TFunction } from 'i18next';
2
2
  import { useEffect, useState } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
 
5
+ /**
6
+ * Response type for the useBundledTranslation hook
7
+ *
8
+ * @template N - Namespace type
9
+ * @template TKPrefix - Key prefix type
10
+ * @typedef {Object} UseBundedTranslationResponse
11
+ * @property {TFunction<N, TKPrefix> | Function} t - Translation function
12
+ * @property {boolean} isReady - Whether translations are ready to use
13
+ */
5
14
  export type UseBundedTranslationResponse<N extends Namespace, TKPrefix> = {
6
15
  t: TFunction<N, TKPrefix> | ((key: string) => string);
7
16
  isReady: boolean;
8
17
  };
9
18
 
19
+ /**
20
+ * Hook for handling bundled translations with i18next
21
+ * Allows loading translations from a provided object rather than fetching them
22
+ *
23
+ * @template N - Namespace type
24
+ * @template TKPrefix - Key prefix type
25
+ * @param {N | Readonly<N>} namespace - The translation namespace
26
+ * @param {Record<string, unknown>} translations - Object containing translations for different languages
27
+ * @returns {UseBundedTranslationResponse<N, TKPrefix>} Translation function and ready state
28
+ */
10
29
  export const useBundledTranslation = <
11
30
  N extends Namespace,
12
31
  TKPrefix extends KeyPrefix<N> = undefined,
@@ -3,12 +3,31 @@ import { useMemo } from 'react';
3
3
 
4
4
  import { usePrevious } from './usePrevious';
5
5
 
6
+ /**
7
+ * Configuration options for debounced search input
8
+ *
9
+ * @typedef {Object} DebouncedSearchConfig
10
+ * @property {number} [debounceDelay=100] - Delay in milliseconds before search is triggered
11
+ * @property {boolean} [forceEmptyValue] - Whether to force empty value when input is below threshold
12
+ * @property {number} [inputThreshold=2] - Minimum number of characters required to trigger search
13
+ */
6
14
  export type DebouncedSearchConfig = {
7
15
  debounceDelay?: number;
8
16
  forceEmptyValue?: boolean;
9
17
  inputThreshold?: number;
10
18
  };
11
19
 
20
+ /**
21
+ * Hook for handling debounced search input with threshold control
22
+ *
23
+ * This hook provides a debounced search value that only updates when:
24
+ * 1. The input exceeds the threshold length
25
+ * 2. The input falls below threshold and forceEmptyValue is true
26
+ *
27
+ * @param {string} inputValue - The current input value
28
+ * @param {DebouncedSearchConfig} [config] - Configuration options
29
+ * @returns {string} The debounced search value
30
+ */
12
31
  export function useDebouncedSearchInput(
13
32
  inputValue: string,
14
33
  config?: DebouncedSearchConfig,
@@ -1,5 +1,15 @@
1
1
  import { useRef } from 'react';
2
2
 
3
+ /**
4
+ * Hook to keep track of the previous value of a variable
5
+ *
6
+ * This hook stores the previous value of a variable across renders,
7
+ * only updating when the value actually changes.
8
+ *
9
+ * @template T - Type of the value to track
10
+ * @param {T} value - The current value
11
+ * @returns {T | undefined} The previous value, or undefined on first render
12
+ */
3
13
  export const usePrevious = <T>(value: T) => {
4
14
  const currentRef = useRef<T>(value);
5
15
  const previousRef = useRef<T>();
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "filters": {
3
+ "account":{
4
+ "placeholder": "Rechercher un client"
5
+ },
3
6
  "profession": {
4
7
  "label": "Qualification",
5
8
  "placeholder": "Qualification",
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "filters": {
3
+ "account":{
4
+ "placeholder": "Trova un cliente"
5
+ },
3
6
  "profession": {
4
7
  "label": "Qualificazione",
5
8
  "placeholder": "Qualificazione",
@@ -1,5 +1,13 @@
1
1
  import { FilterDropdownOption } from '../components';
2
2
 
3
+ /**
4
+ * Mock data for profession filter options
5
+ *
6
+ * This array contains sample profession data for use in tests and demos.
7
+ * Each profession has a unique ID and display label.
8
+ *
9
+ * @type {FilterDropdownOption[]}
10
+ */
3
11
  export const filterOptionsMock: FilterDropdownOption[] = [
4
12
  { id: '00270025-6f9e-4e98-83da-4e7c9409653a', label: 'Webmaster' },
5
13
  { id: '21960b88-c606-4daa-b100-1fbc88834f7d', label: 'Carreleur' },
@@ -1,5 +1,13 @@
1
1
  import { DebouncedSearchConfig } from '../hooks';
2
2
 
3
+ /**
4
+ * Props for components that support searchable filtering
5
+ *
6
+ * @typedef {Object} SearchableFilterProps
7
+ * @property {boolean} [isLoading] - Indicates if search results are loading
8
+ * @property {Function} [onChangeSearchText] - Callback triggered when search text changes
9
+ * @property {DebouncedSearchConfig} searchConfig - Configuration for debounced search behavior
10
+ */
3
11
  export type SearchableFilterProps = {
4
12
  isLoading?: boolean;
5
13
  onChangeSearchText?: (text: string) => void;
@@ -1 +1,6 @@
1
+ /**
2
+ * @module Typings
3
+ * @description Exports all shared TypeScript type definitions
4
+ */
5
+
1
6
  export * from './filters';