@douglasneuroinformatics/libui 3.8.7 → 3.9.0

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.
Files changed (48) hide show
  1. package/dist/{chunk-CAWCERN4.js → chunk-IYOZHDZL.js} +10 -2
  2. package/dist/{chunk-CAWCERN4.js.map → chunk-IYOZHDZL.js.map} +1 -1
  3. package/dist/{chunk-GFIT4FAN.js → chunk-JTEI2ZYI.js} +2 -2
  4. package/dist/components.d.ts +61 -61
  5. package/dist/components.js +46 -10
  6. package/dist/components.js.map +1 -1
  7. package/dist/hooks.d.ts +1 -1
  8. package/dist/hooks.js +2 -2
  9. package/dist/i18n.d.ts +2 -2
  10. package/dist/i18n.js +1 -1
  11. package/dist/{types-DTkK8l-q.d.ts → types-CU3FS63U.d.ts} +12 -4
  12. package/package.json +5 -7
  13. package/src/components/ArrowToggle/ArrowToggle.tsx +2 -2
  14. package/src/components/Breadcrumb/BreadcrumbLink.tsx +2 -2
  15. package/src/components/Breadcrumb/BreadcrumbRoot.tsx +2 -2
  16. package/src/components/Button/Button.tsx +6 -6
  17. package/src/components/Chart/ChartContainer.tsx +2 -2
  18. package/src/components/Chart/ChartLegendContent.tsx +5 -5
  19. package/src/components/Chart/ChartTooltipContent.tsx +8 -8
  20. package/src/components/ClientTable/ClientTable.spec.tsx +87 -0
  21. package/src/components/ClientTable/ClientTable.tsx +2 -1
  22. package/src/components/ClientTable/ClientTablePagination.tsx +28 -1
  23. package/src/components/ContextMenu/ContextMenuItem.tsx +2 -2
  24. package/src/components/ContextMenu/ContextMenuLabel.tsx +2 -2
  25. package/src/components/ContextMenu/ContextMenuSubTrigger.tsx +2 -2
  26. package/src/components/DropdownMenu/DropdownMenuContent.tsx +2 -2
  27. package/src/components/DropdownMenu/DropdownMenuItem.tsx +2 -2
  28. package/src/components/DropdownMenu/DropdownMenuLabel.tsx +2 -2
  29. package/src/components/DropdownMenu/DropdownMenuSubTrigger.tsx +2 -2
  30. package/src/components/Form/BaseRadioField.tsx +2 -2
  31. package/src/components/Form/Form.stories.tsx +0 -1
  32. package/src/components/Form/Form.tsx +0 -1
  33. package/src/components/Form/ScalarField.tsx +8 -8
  34. package/src/components/Form/SetField/SetFieldListbox.tsx +2 -2
  35. package/src/components/Form/SetField/SetFieldSelect.tsx +2 -2
  36. package/src/components/LineGraph/LineGraph.tsx +5 -2
  37. package/src/components/MenuBar/MenuBarItem.tsx +2 -2
  38. package/src/components/MenuBar/MenuBarLabel.tsx +2 -2
  39. package/src/components/MenuBar/MenuBarSubTrigger.tsx +2 -2
  40. package/src/components/Pagination/PaginationLink.tsx +4 -4
  41. package/src/components/Resizable/Resizable.tsx +2 -2
  42. package/src/components/Resizable/ResizableHandle.tsx +2 -2
  43. package/src/components/SearchBar/SearchBar.tsx +4 -4
  44. package/src/i18n/store.ts +1 -1
  45. package/src/i18n/translations/libui.json +8 -0
  46. package/src/i18n/types.ts +4 -4
  47. package/dist/douglasneuroinformatics-libui-3.8.7.tgz +0 -0
  48. /package/dist/{chunk-GFIT4FAN.js.map → chunk-JTEI2ZYI.js.map} +0 -0
package/dist/hooks.d.ts CHANGED
@@ -3,7 +3,7 @@ export { D as DEFAULT_THEME, a as SYS_DARK_MEDIA_QUERY, S as StorageName, b as T
3
3
  import { Promisable } from 'type-fest';
4
4
  import { RefObject, useEffect, Dispatch, SetStateAction } from 'react';
5
5
  import * as zustand from 'zustand';
6
- import { T as TranslationNamespace, L as Language, a as TranslateFunction } from './types-DTkK8l-q.js';
6
+ import { T as TranslationNamespace, L as Language, a as TranslateFunction } from './types-CU3FS63U.js';
7
7
 
8
8
  declare function useChart(): {
9
9
  config: ChartConfig;
package/dist/hooks.js CHANGED
@@ -19,8 +19,8 @@ import {
19
19
  useTheme,
20
20
  useTranslation,
21
21
  useWindowSize
22
- } from "./chunk-GFIT4FAN.js";
23
- import "./chunk-CAWCERN4.js";
22
+ } from "./chunk-JTEI2ZYI.js";
23
+ import "./chunk-IYOZHDZL.js";
24
24
  import "./chunk-VJSOLDCS.js";
25
25
  export {
26
26
  DEFAULT_THEME,
package/dist/i18n.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as zustand from 'zustand';
2
2
  import { SetOptional } from 'type-fest';
3
- import { L as Language, b as Translations, a as TranslateFunction } from './types-DTkK8l-q.js';
4
- export { E as ExtractTranslationKey, c as LanguageOptions, d as TranslationKey, T as TranslationNamespace, U as UserConfig } from './types-DTkK8l-q.js';
3
+ import { L as Language, b as Translations, a as TranslateFunction } from './types-CU3FS63U.js';
4
+ export { E as ExtractTranslationKey, c as LanguageOptions, d as TranslationKey, T as TranslationNamespace, U as UserConfig } from './types-CU3FS63U.js';
5
5
 
6
6
  type InitOptions = {
7
7
  defaultLanguage?: Language;
package/dist/i18n.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  i18n,
4
4
  translationStore
5
- } from "./chunk-CAWCERN4.js";
5
+ } from "./chunk-IYOZHDZL.js";
6
6
  export {
7
7
  i18n,
8
8
  translationStore
@@ -144,6 +144,14 @@ var pagination = {
144
144
  previous: {
145
145
  en: "Previous",
146
146
  fr: "Précédent"
147
+ },
148
+ firstPage: {
149
+ en: "<< First",
150
+ fr: "<< Première"
151
+ },
152
+ lastPage: {
153
+ en: "Last >>",
154
+ fr: "Dernière >>"
147
155
  }
148
156
  };
149
157
  var searchBar = {
@@ -171,16 +179,16 @@ declare namespace UserConfig {
171
179
  } | Translations;
172
180
  }
173
181
  }
174
- type LanguageOptions = {
182
+ type LanguageOptions = UserConfig.LanguageOptions & {
175
183
  en: true;
176
184
  fr: true;
177
- } & UserConfig.LanguageOptions;
185
+ };
178
186
  type Language = keyof {
179
187
  [L in keyof LanguageOptions as LanguageOptions[L] extends true ? L : never]: any;
180
188
  };
181
- type Translations = Simplify<{
189
+ type Translations = Simplify<OmitIndexSignature<UserConfig.Translations> & {
182
190
  libui: typeof libuiTranslations;
183
- } & OmitIndexSignature<UserConfig.Translations>>;
191
+ }>;
184
192
  type ExtractTranslationKey<T extends {
185
193
  [key: string]: any;
186
194
  }, Key = keyof T> = Key extends string ? T[Key] extends {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@douglasneuroinformatics/libui",
3
3
  "type": "module",
4
- "version": "3.8.7",
4
+ "version": "3.9.0",
5
5
  "packageManager": "pnpm@9.14.2",
6
6
  "description": "Generic UI components for DNP projects, built using React and Tailwind CSS",
7
7
  "author": "Joshua Unrau",
@@ -112,11 +112,9 @@
112
112
  "zustand": "^4.5.5"
113
113
  },
114
114
  "devDependencies": {
115
- "@commitlint/cli": "^19.5.0",
116
- "@commitlint/config-conventional": "^19.5.0",
117
- "@douglasneuroinformatics/eslint-config": "^5.2.1",
115
+ "@douglasneuroinformatics/eslint-config": "^5.2.4",
118
116
  "@douglasneuroinformatics/prettier-config": "^0.0.1",
119
- "@douglasneuroinformatics/semantic-release": "^0.0.1",
117
+ "@douglasneuroinformatics/semantic-release": "^0.2.1",
120
118
  "@douglasneuroinformatics/tsconfig": "^1.0.2",
121
119
  "@faker-js/faker": "^9.0.3",
122
120
  "@storybook/addon-essentials": "^8.3.5",
@@ -140,7 +138,7 @@
140
138
  "@vitejs/plugin-react-swc": "^3.7.1",
141
139
  "@vitest/coverage-v8": "^2.1.2",
142
140
  "autoprefixer": "^10.4.20",
143
- "eslint": "^9.12.0",
141
+ "eslint": "^9.19.0",
144
142
  "happy-dom": "^14.12.0",
145
143
  "husky": "^9.1.6",
146
144
  "jsdom": "25.0.1",
@@ -156,7 +154,7 @@
156
154
  },
157
155
  "commitlint": {
158
156
  "extends": [
159
- "@commitlint/config-conventional"
157
+ "@douglasneuroinformatics/semantic-release/commitlint-config"
160
158
  ]
161
159
  },
162
160
  "release": {
@@ -9,7 +9,7 @@ import { cn } from '@/utils';
9
9
  import { Button, type ButtonProps } from '../Button';
10
10
 
11
11
  export type ArrowToggleProps = Simplify<
12
- {
12
+ React.HTMLAttributes<HTMLButtonElement> & {
13
13
  /** Whether or not the arrow is currently toggled */
14
14
  isToggled?: boolean;
15
15
 
@@ -23,7 +23,7 @@ export type ArrowToggleProps = Simplify<
23
23
 
24
24
  /** The variant of button to use */
25
25
  variant?: Extract<ButtonProps['variant'], 'ghost' | 'outline'>;
26
- } & React.HTMLAttributes<HTMLButtonElement>
26
+ }
27
27
  >;
28
28
 
29
29
  export const ArrowToggle = React.forwardRef<HTMLButtonElement, ArrowToggleProps>(function ArrowToggle(
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const BreadcrumbLink = forwardRef<
8
8
  HTMLAnchorElement,
9
- {
9
+ React.ComponentPropsWithoutRef<'a'> & {
10
10
  asChild?: boolean;
11
- } & React.ComponentPropsWithoutRef<'a'>
11
+ }
12
12
  >(function BreadcrumbLink({ asChild, className, ...props }, ref) {
13
13
  const Comp = asChild ? Slot : 'a';
14
14
  return <Comp className={cn('transition-colors hover:text-foreground', className)} ref={ref} {...props} />;
@@ -2,9 +2,9 @@ import { forwardRef } from 'react';
2
2
 
3
3
  export const BreadcrumbRoot = forwardRef<
4
4
  HTMLElement,
5
- {
5
+ React.ComponentPropsWithoutRef<'nav'> & {
6
6
  separator?: React.ReactNode;
7
- } & React.ComponentPropsWithoutRef<'nav'>
7
+ }
8
8
  >(function BreadcrumbRoot({ ...props }, ref) {
9
9
  return <nav aria-label="breadcrumb" ref={ref} {...props} />;
10
10
  });
@@ -39,12 +39,12 @@ export const buttonVariants = cva(
39
39
  );
40
40
 
41
41
  export type ButtonProps = Simplify<
42
- {
43
- asChild?: boolean;
44
- /** @deprecated - use children */
45
- label?: string;
46
- } & React.ButtonHTMLAttributes<HTMLButtonElement> &
47
- VariantProps<typeof buttonVariants>
42
+ React.ButtonHTMLAttributes<HTMLButtonElement> &
43
+ VariantProps<typeof buttonVariants> & {
44
+ asChild?: boolean;
45
+ /** @deprecated - use children */
46
+ label?: string;
47
+ }
48
48
  >;
49
49
 
50
50
  export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
@@ -11,10 +11,10 @@ import type { ChartConfig } from './types';
11
11
 
12
12
  export const ChartContainer = forwardRef<
13
13
  HTMLDivElement,
14
- {
14
+ React.ComponentProps<'div'> & {
15
15
  children: React.ComponentProps<typeof ResponsiveContainer>['children'];
16
16
  config: ChartConfig;
17
- } & React.ComponentProps<'div'>
17
+ }
18
18
  >(function ChartContainer({ children, className, config, id, ...props }, ref) {
19
19
  const uniqueId = useId();
20
20
  const chartId = `chart-${id ?? uniqueId.replace(/:/g, '')}`;
@@ -9,11 +9,11 @@ import { getPayloadConfigFromPayload } from './utils';
9
9
 
10
10
  export const ChartLegendContent = forwardRef<
11
11
  HTMLDivElement,
12
- {
13
- hideIcon?: boolean;
14
- nameKey?: string;
15
- } & Pick<LegendProps, 'payload' | 'verticalAlign'> &
16
- React.ComponentProps<'div'>
12
+ Pick<LegendProps, 'payload' | 'verticalAlign'> &
13
+ React.ComponentProps<'div'> & {
14
+ hideIcon?: boolean;
15
+ nameKey?: string;
16
+ }
17
17
  >(function ChartLegendContent({ className, hideIcon = false, nameKey, payload, verticalAlign = 'bottom' }, ref) {
18
18
  const { config } = useChart();
19
19
 
@@ -9,14 +9,14 @@ import { getPayloadConfigFromPayload } from './utils';
9
9
 
10
10
  export const ChartTooltipContent = forwardRef<
11
11
  HTMLDivElement,
12
- {
13
- hideIndicator?: boolean;
14
- hideLabel?: boolean;
15
- indicator?: 'dashed' | 'dot' | 'line';
16
- labelKey?: string;
17
- nameKey?: string;
18
- } & React.ComponentProps<'div'> &
19
- React.ComponentProps<typeof Tooltip>
12
+ React.ComponentProps<'div'> &
13
+ React.ComponentProps<typeof Tooltip> & {
14
+ hideIndicator?: boolean;
15
+ hideLabel?: boolean;
16
+ indicator?: 'dashed' | 'dot' | 'line';
17
+ labelKey?: string;
18
+ nameKey?: string;
19
+ }
20
20
  >(function ChartLegendContent(
21
21
  {
22
22
  active,
@@ -0,0 +1,87 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+
5
+ import { ClientTable } from './ClientTable';
6
+
7
+ const TEST_ID = 'ClientTable';
8
+ const FIRST_BUTTON_ID = 'first-page-button';
9
+ const PREVIOUS_BUTTON_ID = 'previous-page-button';
10
+ const NEXT_BUTTON_ID = 'next-page-button';
11
+ const LAST_BUTTON_ID = 'last-page-button';
12
+ const PAGE_NUMBER_TEST_ID = 'page-numbers';
13
+ describe('ClientTable', () => {
14
+ it('should render', () => {
15
+ render(<ClientTable columns={[]} data={[]} minRows={10} />);
16
+ expect(screen.getByTestId(TEST_ID)).toBeInTheDocument();
17
+ expect(screen.getByTestId(FIRST_BUTTON_ID)).toBeInTheDocument();
18
+ expect(screen.getByTestId(PREVIOUS_BUTTON_ID)).toBeInTheDocument();
19
+ expect(screen.getByTestId(NEXT_BUTTON_ID)).toBeInTheDocument();
20
+ expect(screen.getByTestId(LAST_BUTTON_ID)).toBeInTheDocument();
21
+ });
22
+ it('should contain a custom class name', () => {
23
+ render(<ClientTable className="foo" columns={[]} data={[]} minRows={10} />);
24
+ expect(screen.getByTestId(TEST_ID)).toHaveClass('foo');
25
+ });
26
+ it('should function correctly', async () => {
27
+ const handleClientTableItemClick = vi.fn();
28
+ const handleClientTableDropdownClick = vi.fn();
29
+ render(
30
+ <ClientTable
31
+ columnDropdownOptions={[
32
+ {
33
+ label: 'delete',
34
+ onSelection: handleClientTableDropdownClick
35
+ }
36
+ ]}
37
+ columns={[
38
+ {
39
+ field: 'f1',
40
+ label: 'Field 1'
41
+ },
42
+ {
43
+ field: 'f2',
44
+ label: 'Field 2'
45
+ }
46
+ ]}
47
+ data={[
48
+ {
49
+ f1: 1,
50
+ f2: 2
51
+ },
52
+ {
53
+ f1: 23,
54
+ f2: 24
55
+ }
56
+ ]}
57
+ entriesPerPage={1}
58
+ minRows={3}
59
+ onEntryClick={handleClientTableItemClick}
60
+ />
61
+ );
62
+ expect(screen.getByTestId(PAGE_NUMBER_TEST_ID)).toBeInTheDocument();
63
+ await userEvent.click(screen.getByTestId(NEXT_BUTTON_ID));
64
+ await userEvent.click(await screen.findByText('23.00'));
65
+ expect(handleClientTableItemClick).toBeCalled();
66
+
67
+ expect(screen.getByTestId(PAGE_NUMBER_TEST_ID).textContent).toBe('2 - 2 / 2');
68
+ await userEvent.click(screen.getByTestId(PREVIOUS_BUTTON_ID));
69
+ await userEvent.click(await screen.findByText('1.00'));
70
+ expect(handleClientTableItemClick).toBeCalled();
71
+
72
+ expect(screen.getByTestId(PAGE_NUMBER_TEST_ID).textContent).toBe('1 - 1 / 2');
73
+ await userEvent.click(screen.getByTestId(LAST_BUTTON_ID));
74
+ await userEvent.click(await screen.findByText('23.00'));
75
+ expect(handleClientTableItemClick).toBeCalled();
76
+
77
+ expect(screen.getByTestId(PAGE_NUMBER_TEST_ID).textContent).toBe('2 - 2 / 2');
78
+ await userEvent.click(screen.getByTestId(FIRST_BUTTON_ID));
79
+ await userEvent.click(await screen.findByText('1.00'));
80
+ expect(handleClientTableItemClick).toBeCalled();
81
+ expect(screen.getByTestId(PAGE_NUMBER_TEST_ID).textContent).toBe('1 - 1 / 2');
82
+
83
+ await userEvent.click(await screen.findByText('Field 1'));
84
+ await userEvent.click(screen.getByTestId('delete-test-id'));
85
+ expect(handleClientTableDropdownClick).toBeCalled();
86
+ });
87
+ });
@@ -85,7 +85,7 @@ export const ClientTable = <T extends ClientTableEntry>({
85
85
  const nRows = Math.max(currentEntries.length, minRows ?? -1);
86
86
 
87
87
  return (
88
- <div className={className} {...props}>
88
+ <div className={className} {...props} data-testid="ClientTable">
89
89
  <div className="rounded-md border bg-card tracking-tight text-muted-foreground shadow-sm">
90
90
  <Table>
91
91
  <Table.Header>
@@ -104,6 +104,7 @@ export const ClientTable = <T extends ClientTableEntry>({
104
104
  const Icon = option.icon;
105
105
  return (
106
106
  <DropdownMenu.Item
107
+ data-testid={option.label + '-test-id'}
107
108
  key={option.label}
108
109
  onClick={() => {
109
110
  option.onSelection(column);
@@ -23,10 +23,25 @@ export const ClientTablePagination = ({
23
23
  return (
24
24
  <div className="flex items-center justify-between py-3">
25
25
  <div className="hidden sm:block">
26
- <p className="text-sm font-medium text-muted-foreground">{`${firstEntry} - ${lastEntry} / ${totalEntries}`}</p>
26
+ <p
27
+ className="text-sm font-medium text-muted-foreground"
28
+ data-testid="page-numbers"
29
+ >{`${firstEntry} - ${lastEntry} / ${totalEntries}`}</p>
27
30
  </div>
28
31
  <div className="flex flex-1 justify-between gap-3 sm:justify-end">
29
32
  <Button
33
+ data-testid="first-page-button"
34
+ disabled={currentPage === 1}
35
+ type="button"
36
+ variant="outline"
37
+ onClick={() => {
38
+ setCurrentPage(1);
39
+ }}
40
+ >
41
+ {t('pagination.firstPage')}
42
+ </Button>
43
+ <Button
44
+ data-testid="previous-page-button"
30
45
  disabled={currentPage === 1}
31
46
  type="button"
32
47
  variant="outline"
@@ -37,6 +52,7 @@ export const ClientTablePagination = ({
37
52
  {t('pagination.previous')}
38
53
  </Button>
39
54
  <Button
55
+ data-testid="next-page-button"
40
56
  disabled={currentPage === pageCount}
41
57
  type="button"
42
58
  variant="outline"
@@ -46,6 +62,17 @@ export const ClientTablePagination = ({
46
62
  >
47
63
  {t('pagination.next')}
48
64
  </Button>
65
+ <Button
66
+ data-testid="last-page-button"
67
+ disabled={currentPage === pageCount}
68
+ type="button"
69
+ variant="outline"
70
+ onClick={() => {
71
+ setCurrentPage(pageCount);
72
+ }}
73
+ >
74
+ {t('pagination.lastPage')}
75
+ </Button>
49
76
  </div>
50
77
  </div>
51
78
  );
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const ContextMenuItem = forwardRef<
8
8
  React.ElementRef<typeof ContextMenuPrimitive.Item>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item>
11
+ }
12
12
  >(function ContextMenuItem({ className, inset, ...props }, ref) {
13
13
  return (
14
14
  <ContextMenuPrimitive.Item
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const ContextMenuLabel = forwardRef<
8
8
  React.ElementRef<typeof ContextMenuPrimitive.Label>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label>
11
+ }
12
12
  >(function ContextMenuLabel({ className, inset, ...props }, ref) {
13
13
  return (
14
14
  <ContextMenuPrimitive.Label
@@ -7,9 +7,9 @@ import { cn } from '@/utils';
7
7
 
8
8
  export const ContextMenuSubTrigger = forwardRef<
9
9
  React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
10
- {
10
+ React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
11
11
  inset?: boolean;
12
- } & React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger>
12
+ }
13
13
  >(function ContextMenuSubTrigger({ children, className, inset, ...props }, ref) {
14
14
  return (
15
15
  <ContextMenuPrimitive.SubTrigger
@@ -4,9 +4,9 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
4
4
 
5
5
  import { cn } from '@/utils';
6
6
 
7
- export type DropdownMenuContentProps = {
7
+ export type DropdownMenuContentProps = React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {
8
8
  widthFull?: boolean;
9
- } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>;
9
+ };
10
10
  export const DropdownMenuContent = React.forwardRef<
11
11
  React.ElementRef<typeof DropdownMenuPrimitive.Content>,
12
12
  DropdownMenuContentProps
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const DropdownMenuItem = forwardRef<
8
8
  React.ElementRef<typeof DropdownMenuPrimitive.Item>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>
11
+ }
12
12
  >(function DropdownMenuItem({ className, inset, ...props }, ref) {
13
13
  return (
14
14
  <DropdownMenuPrimitive.Item
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const DropdownMenuLabel = forwardRef<
8
8
  React.ElementRef<typeof DropdownMenuPrimitive.Label>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>
11
+ }
12
12
  >(function DropdownMenuLabel({ className, inset, ...props }, ref) {
13
13
  return (
14
14
  <DropdownMenuPrimitive.Label
@@ -7,9 +7,9 @@ import { cn } from '@/utils';
7
7
 
8
8
  export const DropdownMenuSubTrigger = forwardRef<
9
9
  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
10
- {
10
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
11
11
  inset?: boolean;
12
- } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger>
12
+ }
13
13
  >(function DropdownMenuSubTrigger({ children, className, inset, ...props }, ref) {
14
14
  return (
15
15
  <DropdownMenuPrimitive.SubTrigger
@@ -20,13 +20,13 @@ const baseRadioFieldVariants = cva('flex', {
20
20
  });
21
21
 
22
22
  export type BaseRadioFieldProps<T extends string> = Simplify<
23
- {
23
+ BaseFieldComponentProps<T> & {
24
24
  description?: string;
25
25
  disabled?: boolean;
26
26
  label: string;
27
27
  options: { [K in T]: string };
28
28
  orientation?: 'horizontal' | 'vertical';
29
- } & BaseFieldComponentProps<T>
29
+ }
30
30
  >;
31
31
 
32
32
  export const BaseRadioField = <T extends string>({
@@ -1,4 +1,3 @@
1
- /* eslint-disable max-lines */
2
1
  /* eslint-disable perfectionist/sort-objects */
3
2
 
4
3
  import { useEffect, useState } from 'react';
@@ -45,7 +45,6 @@ type FormProps<TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<T
45
45
  validationSchema: z.ZodType<TData>;
46
46
  };
47
47
 
48
- // eslint-disable-next-line max-lines-per-function
49
48
  const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TSchema> = z.TypeOf<TSchema>>({
50
49
  additionalButtons,
51
50
  className,
@@ -15,22 +15,22 @@ import { StringField, type StringFieldProps } from './StringField';
15
15
 
16
16
  import type { BaseFieldComponentProps } from './types';
17
17
 
18
- export type ScalarFieldProps = {
18
+ export type ScalarFieldProps = BaseFieldComponentProps<ScalarFieldValue> & {
19
19
  field: BooleanFormField | DateFormField | NumberFormField | SetFormField | StringFormField;
20
- } & BaseFieldComponentProps<ScalarFieldValue>;
20
+ };
21
21
 
22
22
  export const ScalarField = ({ field, ...props }: ScalarFieldProps) => {
23
23
  switch (field.kind) {
24
- case 'string':
25
- return <StringField {...field} {...(props as StringFieldProps)} />;
26
- case 'number':
27
- return <NumberField {...field} {...(props as NumberFieldProps)} />;
28
- case 'date':
29
- return <DateField {...field} {...(props as DateFieldProps)} />;
30
24
  case 'boolean':
31
25
  return <BooleanField {...field} {...(props as BooleanFieldProps)} />;
26
+ case 'date':
27
+ return <DateField {...field} {...(props as DateFieldProps)} />;
28
+ case 'number':
29
+ return <NumberField {...field} {...(props as NumberFieldProps)} />;
32
30
  case 'set':
33
31
  return <SetField {...field} {...(props as SetFieldProps)} />;
32
+ case 'string':
33
+ return <StringField {...field} {...(props as StringFieldProps)} />;
34
34
  default:
35
35
  throw new Error(`Unexpected value for kind: ${Reflect.get(field, 'kind') satisfies never}`);
36
36
  }
@@ -5,9 +5,9 @@ import { FieldGroup } from '../FieldGroup';
5
5
 
6
6
  import type { SetFieldProps } from './SetField';
7
7
 
8
- export type SetFieldListboxProps<T extends string = string> = {
8
+ export type SetFieldListboxProps<T extends string = string> = SetFieldProps<T> & {
9
9
  onCheckedChange: (option: T, isChecked: boolean) => void;
10
- } & SetFieldProps<T>;
10
+ };
11
11
 
12
12
  export const SetFieldListbox = <T extends string = string>({
13
13
  description,
@@ -7,9 +7,9 @@ import { FieldGroup } from '../FieldGroup';
7
7
 
8
8
  import type { SetFieldProps } from './SetField';
9
9
 
10
- export type SetFieldSelectProps<T extends string = string> = {
10
+ export type SetFieldSelectProps<T extends string = string> = SetFieldProps<T> & {
11
11
  onCheckedChange: (option: T, isChecked: boolean) => void;
12
- } & SetFieldProps<T>;
12
+ };
13
13
 
14
14
  export const SetFieldSelect = <T extends string = string>({
15
15
  description,
@@ -26,11 +26,14 @@ type LineGraphData = readonly { [key: string]: any }[];
26
26
  /** Extract string keys from items in `T` where the value of `T[K]` extends `K` */
27
27
  type ExtractValidKeys<T extends LineGraphData, K> = Extract<ConditionalKeys<T[number], K>, string>;
28
28
 
29
- type LineGraphLine<T extends LineGraphData = { [key: string]: any }[]> = {
29
+ type LineGraphLine<T extends LineGraphData = { [key: string]: any }[]> = Pick<
30
+ LineProps,
31
+ 'legendType' | 'stroke' | 'strokeDasharray' | 'strokeWidth' | 'type'
32
+ > & {
30
33
  err?: ExtractValidKeys<T, number>;
31
34
  name: string;
32
35
  val: ExtractValidKeys<T, number>;
33
- } & Pick<LineProps, 'legendType' | 'stroke' | 'strokeDasharray' | 'strokeWidth' | 'type'>;
36
+ };
34
37
 
35
38
  const strokeColors = {
36
39
  dark: '#cbd5e1', // slate-300
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const MenuBarItem = forwardRef<
8
8
  React.ElementRef<typeof Item>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof Item> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof Item>
11
+ }
12
12
  >(function MenuBarItem({ className, inset, ...props }, ref) {
13
13
  return (
14
14
  <Item
@@ -6,9 +6,9 @@ import { cn } from '@/utils';
6
6
 
7
7
  export const MenuBarLabel = forwardRef<
8
8
  React.ElementRef<typeof Label>,
9
- {
9
+ React.ComponentPropsWithoutRef<typeof Label> & {
10
10
  inset?: boolean;
11
- } & React.ComponentPropsWithoutRef<typeof Label>
11
+ }
12
12
  >(function MenuBarLabel({ className, inset, ...props }, ref) {
13
13
  return <Label className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)} ref={ref} {...props} />;
14
14
  });
@@ -7,9 +7,9 @@ import { cn } from '@/utils';
7
7
 
8
8
  export const MenuBarSubTrigger = forwardRef<
9
9
  React.ElementRef<typeof SubTrigger>,
10
- {
10
+ React.ComponentPropsWithoutRef<typeof SubTrigger> & {
11
11
  inset?: boolean;
12
- } & React.ComponentPropsWithoutRef<typeof SubTrigger>
12
+ }
13
13
  >(function MenuBarSubTrigger({ children, className, inset, ...props }, ref) {
14
14
  return (
15
15
  <SubTrigger