@douglasneuroinformatics/libui 3.8.7 → 4.0.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 (123) hide show
  1. package/README.md +7 -9
  2. package/dist/{chunk-CAWCERN4.js → chunk-655XRTXX.js} +10 -2
  3. package/dist/{chunk-CAWCERN4.js.map → chunk-655XRTXX.js.map} +1 -1
  4. package/dist/{chunk-VJSOLDCS.js → chunk-HCQE34RL.js} +1 -1
  5. package/dist/chunk-HCQE34RL.js.map +1 -0
  6. package/dist/{chunk-GFIT4FAN.js → chunk-KI6BSSS6.js} +3 -4
  7. package/dist/chunk-KI6BSSS6.js.map +1 -0
  8. package/dist/components.d.ts +137 -89
  9. package/dist/components.js +111 -77
  10. package/dist/components.js.map +1 -1
  11. package/dist/hooks.d.ts +1 -1
  12. package/dist/hooks.js +3 -3
  13. package/dist/i18n.d.ts +2 -2
  14. package/dist/i18n.js +1 -1
  15. package/dist/tailwind/globals.css +181 -39
  16. package/dist/{types-DTkK8l-q.d.ts → types-CMuti1SJ.d.ts} +14 -6
  17. package/dist/utils.js +1 -1
  18. package/package.json +89 -86
  19. package/src/components/ActionDropdown/ActionDropdown.tsx +1 -1
  20. package/src/components/ArrowToggle/ArrowToggle.spec.tsx +3 -1
  21. package/src/components/ArrowToggle/ArrowToggle.tsx +5 -3
  22. package/src/components/Badge/Badge.tsx +7 -5
  23. package/src/components/Breadcrumb/BreadcrumbLink.tsx +2 -2
  24. package/src/components/Breadcrumb/BreadcrumbRoot.tsx +2 -2
  25. package/src/components/Button/Button.tsx +13 -12
  26. package/src/components/Card/Card.tsx +3 -3
  27. package/src/components/Chart/ChartContainer.tsx +3 -3
  28. package/src/components/Chart/ChartLegendContent.tsx +5 -5
  29. package/src/components/Chart/ChartTooltipContent.tsx +8 -8
  30. package/src/components/Checkbox/Checkbox.tsx +1 -1
  31. package/src/components/ClientTable/ClientTable.spec.tsx +87 -0
  32. package/src/components/ClientTable/ClientTable.stories.tsx +12 -9
  33. package/src/components/ClientTable/ClientTable.tsx +5 -4
  34. package/src/components/ClientTable/ClientTablePagination.tsx +28 -1
  35. package/src/components/Collapsible/Collapsible.stories.tsx +3 -3
  36. package/src/components/Command/CommandInput.tsx +1 -1
  37. package/src/components/Command/CommandItem.tsx +1 -1
  38. package/src/components/ContextMenu/ContextMenuCheckboxItem.tsx +1 -1
  39. package/src/components/ContextMenu/ContextMenuItem.tsx +3 -3
  40. package/src/components/ContextMenu/ContextMenuLabel.tsx +2 -2
  41. package/src/components/ContextMenu/ContextMenuRadioItem.tsx +1 -1
  42. package/src/components/ContextMenu/ContextMenuSubTrigger.tsx +3 -3
  43. package/src/components/CopyButton/CopyButton.tsx +3 -1
  44. package/src/components/DatePicker/DatePicker.tsx +3 -3
  45. package/src/components/Dialog/DialogContent.tsx +2 -2
  46. package/src/components/DropdownButton/DropdownButton.tsx +1 -1
  47. package/src/components/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -1
  48. package/src/components/DropdownMenu/DropdownMenuContent.tsx +2 -2
  49. package/src/components/DropdownMenu/DropdownMenuItem.tsx +3 -3
  50. package/src/components/DropdownMenu/DropdownMenuLabel.tsx +2 -2
  51. package/src/components/DropdownMenu/DropdownMenuRadioItem.tsx +1 -1
  52. package/src/components/DropdownMenu/DropdownMenuSubTrigger.tsx +3 -3
  53. package/src/components/FileDropzone/FileDropzone.stories.tsx +4 -6
  54. package/src/components/FileDropzone/FileDropzone.tsx +2 -1
  55. package/src/components/Form/BaseRadioField.tsx +2 -2
  56. package/src/components/Form/BooleanField/BooleanField.spec.tsx +3 -1
  57. package/src/components/Form/BooleanField/BooleanField.tsx +5 -2
  58. package/src/components/Form/DateField/DateField.tsx +2 -1
  59. package/src/components/Form/Form.stories.tsx +15 -16
  60. package/src/components/Form/Form.tsx +0 -1
  61. package/src/components/Form/NumberField/NumberField.tsx +7 -3
  62. package/src/components/Form/NumberField/NumberFieldSelect.tsx +2 -1
  63. package/src/components/Form/RecordArrayField.tsx +1 -3
  64. package/src/components/Form/ScalarField.tsx +18 -13
  65. package/src/components/Form/SetField/SetFieldListbox.tsx +2 -2
  66. package/src/components/Form/SetField/SetFieldSelect.tsx +2 -2
  67. package/src/components/Form/StaticField.tsx +2 -1
  68. package/src/components/Form/StringField/StringField.tsx +9 -4
  69. package/src/components/Form/StringField/StringFieldPassword.tsx +5 -5
  70. package/src/components/Form/StringField/StringFieldSelect.tsx +2 -1
  71. package/src/components/HoverCard/HoverCardContent.tsx +1 -1
  72. package/src/components/Input/Input.tsx +1 -1
  73. package/src/components/Label/Label.tsx +2 -1
  74. package/src/components/LanguageToggle/LanguageToggle.tsx +3 -1
  75. package/src/components/LineGraph/LineGraph.tsx +8 -4
  76. package/src/components/ListboxDropdown/ListboxDropdown.stories.tsx +4 -4
  77. package/src/components/ListboxDropdown/ListboxDropdown.tsx +2 -1
  78. package/src/components/MenuBar/MenuBarCheckboxItem.tsx +1 -1
  79. package/src/components/MenuBar/MenuBarItem.tsx +3 -3
  80. package/src/components/MenuBar/MenuBarLabel.tsx +2 -2
  81. package/src/components/MenuBar/MenuBarRadioItem.tsx +1 -1
  82. package/src/components/MenuBar/MenuBarRoot.tsx +1 -1
  83. package/src/components/MenuBar/MenuBarSubTrigger.tsx +3 -3
  84. package/src/components/MenuBar/MenuBarTrigger.tsx +1 -1
  85. package/src/components/NotificationHub/NotificationHub.tsx +3 -3
  86. package/src/components/NotificationHub/NotificationIcon.tsx +1 -1
  87. package/src/components/Pagination/PaginationLink.tsx +7 -5
  88. package/src/components/Pagination/PaginationPrevious.tsx +3 -1
  89. package/src/components/Popover/PopoverContent.tsx +1 -1
  90. package/src/components/RadioGroup/RadioGroup.spec.tsx +3 -1
  91. package/src/components/RadioGroup/RadioGroupItem.tsx +1 -1
  92. package/src/components/Resizable/Resizable.tsx +9 -5
  93. package/src/components/Resizable/ResizableHandle.tsx +4 -4
  94. package/src/components/SearchBar/SearchBar.tsx +7 -5
  95. package/src/components/Select/SelectItem.tsx +1 -1
  96. package/src/components/Sheet/SheetContent.tsx +3 -2
  97. package/src/components/Slider/Slider.tsx +4 -4
  98. package/src/components/StatisticCard/StatisticCard.tsx +2 -1
  99. package/src/components/Switch/Switch.tsx +2 -2
  100. package/src/components/Tabs/TabsContent.tsx +1 -1
  101. package/src/components/Tabs/TabsTrigger.tsx +1 -1
  102. package/src/components/TextArea/TextArea.tsx +1 -1
  103. package/src/components/ThemeToggle/ThemeToggle.tsx +3 -1
  104. package/src/components/Tooltip/TooltipTrigger.tsx +3 -1
  105. package/src/hooks/useEventListener/useEventListener.ts +2 -1
  106. package/src/hooks/useOnClickOutside/useOnClickOutside.ts +1 -1
  107. package/src/hooks/useStorage/useLocalStorage.ts +3 -1
  108. package/src/hooks/useStorage/useSessionStorage.ts +3 -1
  109. package/src/hooks/useTheme/useTheme.test.ts +14 -11
  110. package/src/i18n/internal.ts +1 -1
  111. package/src/i18n/store.ts +1 -1
  112. package/src/i18n/translations/libui.json +8 -0
  113. package/src/i18n/types.ts +6 -6
  114. package/src/tailwind/globals.css +181 -39
  115. package/src/utils/index.ts +2 -1
  116. package/dist/chunk-GFIT4FAN.js.map +0 -1
  117. package/dist/chunk-VJSOLDCS.js.map +0 -1
  118. package/dist/douglasneuroinformatics-libui-3.8.7.tgz +0 -0
  119. package/dist/tailwind/config.cjs +0 -178
  120. package/dist/tailwind/config.cjs.map +0 -1
  121. package/dist/tailwind/config.d.cts +0 -16
  122. package/src/tailwind/config.cts +0 -174
  123. package/tailwind.config.cjs +0 -3
@@ -7,14 +7,14 @@ 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
16
16
  className={cn(
17
- 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',
17
+ 'focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none',
18
18
  inset && 'pl-8',
19
19
  className
20
20
  )}
@@ -4,14 +4,12 @@ import type { Meta, StoryObj } from '@storybook/react';
4
4
 
5
5
  import { FileDropzone } from './FileDropzone.js';
6
6
 
7
- const meta: Meta<typeof FileDropzone> = {
8
- component: FileDropzone
9
- };
10
-
11
- export default meta;
12
-
13
7
  type Story = StoryObj<typeof FileDropzone>;
14
8
 
9
+ export default {
10
+ component: FileDropzone
11
+ } satisfies Meta<typeof FileDropzone>;
12
+
15
13
  export const Default: Story = {
16
14
  decorators: [
17
15
  (Story) => {
@@ -1,7 +1,8 @@
1
1
  import { useCallback } from 'react';
2
2
 
3
3
  import { UploadIcon } from 'lucide-react';
4
- import { type FileRejection, useDropzone } from 'react-dropzone';
4
+ import { useDropzone } from 'react-dropzone';
5
+ import type { FileRejection } from 'react-dropzone';
5
6
 
6
7
  import { useTranslation } from '@/hooks/useTranslation';
7
8
  import { cn } from '@/utils';
@@ -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>({
@@ -3,7 +3,9 @@ import { useState } from 'react';
3
3
  import { render, screen } from '@testing-library/react';
4
4
  import { describe, expect, it } from 'vitest';
5
5
 
6
- import { BooleanField, type BooleanFieldProps } from './BooleanField';
6
+ import { BooleanField } from './BooleanField';
7
+
8
+ import type { BooleanFieldProps } from './BooleanField';
7
9
 
8
10
  const TestBooleanField = ({ variant }: Pick<BooleanFieldProps, 'variant'>) => {
9
11
  const [error, setError] = useState<string[] | undefined>();
@@ -1,7 +1,10 @@
1
1
  import { match } from 'ts-pattern';
2
2
 
3
- import { BooleanFieldCheckbox, type BooleanFieldCheckboxProps } from './BooleanFieldCheckbox';
4
- import { BooleanFieldRadio, type BooleanFieldRadioProps } from './BooleanFieldRadio';
3
+ import { BooleanFieldCheckbox } from './BooleanFieldCheckbox';
4
+ import { BooleanFieldRadio } from './BooleanFieldRadio';
5
+
6
+ import type { BooleanFieldCheckboxProps } from './BooleanFieldCheckbox';
7
+ import type { BooleanFieldRadioProps } from './BooleanFieldRadio';
5
8
 
6
9
  export type BooleanFieldProps = BooleanFieldCheckboxProps | BooleanFieldRadioProps;
7
10
 
@@ -10,7 +10,8 @@ import { Label } from '@/components/Label';
10
10
  import { Popover } from '@/components/Popover';
11
11
 
12
12
  import { FieldGroup } from '../FieldGroup';
13
- import { type BaseFieldComponentProps } from '../types';
13
+
14
+ import type { BaseFieldComponentProps } from '../types';
14
15
 
15
16
  const isValidDateString = (s: string) => /^(\d{4})-((0[1-9])|(1[0-2]))-((0[1-9])|([12])[0-9]|3[01])$/.test(s);
16
17
 
@@ -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';
@@ -57,21 +56,6 @@ const $SimpleExampleFormData = z.object({
57
56
  });
58
57
  type SimpleExampleFormSchemaType = typeof $SimpleExampleFormData;
59
58
 
60
- export default {
61
- component: Form,
62
- decorators: [
63
- (Story) => (
64
- <div className="container mx-auto max-w-5xl">
65
- <Heading className="my-8 text-center" variant="h1">
66
- Example Form
67
- </Heading>
68
- <Story />
69
- </div>
70
- )
71
- ],
72
- tags: ['autodocs']
73
- } as Meta<typeof Form>;
74
-
75
59
  const booleanFields: FormFields<Pick<ExampleFormData, 'booleanCheck' | 'booleanRadio'>> = {
76
60
  booleanRadio: {
77
61
  disabled: DISABLED,
@@ -317,6 +301,21 @@ const ungroupedContent = {
317
301
  ...recordArrayFields
318
302
  } as const;
319
303
 
304
+ export default {
305
+ component: Form,
306
+ decorators: [
307
+ (Story) => (
308
+ <div className="container mx-auto max-w-5xl">
309
+ <Heading className="my-8 text-center" variant="h1">
310
+ Example Form
311
+ </Heading>
312
+ <Story />
313
+ </div>
314
+ )
315
+ ],
316
+ tags: ['autodocs']
317
+ } as Meta<typeof Form>;
318
+
320
319
  export const Grouped: StoryObj<typeof Form<ExampleFormSchemaType>> = {
321
320
  args: {
322
321
  content: [
@@ -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,
@@ -1,9 +1,13 @@
1
1
  import { match } from 'ts-pattern';
2
2
 
3
- import { NumberFieldInput, type NumberFieldInputProps } from './NumberFieldInput';
4
- import { NumberFieldRadio, type NumberFieldRadioProps } from './NumberFieldRadio';
3
+ import { NumberFieldInput } from './NumberFieldInput';
4
+ import { NumberFieldRadio } from './NumberFieldRadio';
5
5
  import { NumberFieldSelect } from './NumberFieldSelect';
6
- import { NumberFieldSlider, type NumberFieldSliderProps } from './NumberFieldSlider';
6
+ import { NumberFieldSlider } from './NumberFieldSlider';
7
+
8
+ import type { NumberFieldInputProps } from './NumberFieldInput';
9
+ import type { NumberFieldRadioProps } from './NumberFieldRadio';
10
+ import type { NumberFieldSliderProps } from './NumberFieldSlider';
7
11
 
8
12
  export type NumberFieldProps = NumberFieldInputProps | NumberFieldRadioProps | NumberFieldSliderProps;
9
13
 
@@ -5,7 +5,8 @@ import { Label } from '@/components/Label';
5
5
  import { Select } from '@/components/Select';
6
6
 
7
7
  import { FieldGroup } from '../FieldGroup';
8
- import { type BaseFieldComponentProps } from '../types';
8
+
9
+ import type { BaseFieldComponentProps } from '../types';
9
10
 
10
11
  export type NumberFieldSelectProps<T extends number = number> = Simplify<
11
12
  BaseFieldComponentProps<T> & Extract<NumberFormField<T>, { options: object }>
@@ -85,9 +85,7 @@ export const RecordArrayField = memo(function RecordArrayField({
85
85
  readOnly={disabled || readOnly}
86
86
  setError={(error) => {
87
87
  const newArrayError = arrayError ? [...arrayError] : [];
88
- if (!newArrayError[i]) {
89
- newArrayError[i] = {};
90
- }
88
+ newArrayError[i] ??= {};
91
89
  newArrayError[i][name] = error;
92
90
  setArrayError(newArrayError);
93
91
  }}
@@ -7,30 +7,35 @@ import type {
7
7
  StringFormField
8
8
  } from '@douglasneuroinformatics/libui-form-types';
9
9
 
10
- import { BooleanField, type BooleanFieldProps } from './BooleanField';
11
- import { DateField, type DateFieldProps } from './DateField';
12
- import { NumberField, type NumberFieldProps } from './NumberField';
13
- import { SetField, type SetFieldProps } from './SetField';
14
- import { StringField, type StringFieldProps } from './StringField';
10
+ import { BooleanField } from './BooleanField';
11
+ import { DateField } from './DateField';
12
+ import { NumberField } from './NumberField';
13
+ import { SetField } from './SetField';
14
+ import { StringField } from './StringField';
15
15
 
16
+ import type { BooleanFieldProps } from './BooleanField';
17
+ import type { DateFieldProps } from './DateField';
18
+ import type { NumberFieldProps } from './NumberField';
19
+ import type { SetFieldProps } from './SetField';
20
+ import type { StringFieldProps } from './StringField';
16
21
  import type { BaseFieldComponentProps } from './types';
17
22
 
18
- export type ScalarFieldProps = {
23
+ export type ScalarFieldProps = BaseFieldComponentProps<ScalarFieldValue> & {
19
24
  field: BooleanFormField | DateFormField | NumberFormField | SetFormField | StringFormField;
20
- } & BaseFieldComponentProps<ScalarFieldValue>;
25
+ };
21
26
 
22
27
  export const ScalarField = ({ field, ...props }: ScalarFieldProps) => {
23
28
  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
29
  case 'boolean':
31
30
  return <BooleanField {...field} {...(props as BooleanFieldProps)} />;
31
+ case 'date':
32
+ return <DateField {...field} {...(props as DateFieldProps)} />;
33
+ case 'number':
34
+ return <NumberField {...field} {...(props as NumberFieldProps)} />;
32
35
  case 'set':
33
36
  return <SetField {...field} {...(props as SetFieldProps)} />;
37
+ case 'string':
38
+ return <StringField {...field} {...(props as StringFieldProps)} />;
34
39
  default:
35
40
  throw new Error(`Unexpected value for kind: ${Reflect.get(field, 'kind') satisfies never}`);
36
41
  }
@@ -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,
@@ -15,8 +15,9 @@ import { match } from 'ts-pattern';
15
15
 
16
16
  import { NumberRecordField } from './NumberRecordField';
17
17
  import { RecordArrayField } from './RecordArrayField';
18
- import { ScalarField, type ScalarFieldProps } from './ScalarField';
18
+ import { ScalarField } from './ScalarField';
19
19
 
20
+ import type { ScalarFieldProps } from './ScalarField';
20
21
  import type { FieldError, FormErrors } from './types';
21
22
 
22
23
  export type StaticFieldProps<TData extends FormDataType> = {
@@ -1,10 +1,15 @@
1
1
  import { match } from 'ts-pattern';
2
2
 
3
- import { StringFieldInput, type StringFieldInputProps } from './StringFieldInput';
4
- import { StringFieldPassword, type StringFieldPasswordProps } from './StringFieldPassword';
5
- import { StringFieldRadio, type StringFieldRadioProps } from './StringFieldRadio';
3
+ import { StringFieldInput } from './StringFieldInput';
4
+ import { StringFieldPassword } from './StringFieldPassword';
5
+ import { StringFieldRadio } from './StringFieldRadio';
6
6
  import { StringFieldSelect } from './StringFieldSelect';
7
- import { StringFieldTextArea, type StringFieldTextAreaProps } from './StringFieldTextArea';
7
+ import { StringFieldTextArea } from './StringFieldTextArea';
8
+
9
+ import type { StringFieldInputProps } from './StringFieldInput';
10
+ import type { StringFieldPasswordProps } from './StringFieldPassword';
11
+ import type { StringFieldRadioProps } from './StringFieldRadio';
12
+ import type { StringFieldTextAreaProps } from './StringFieldTextArea';
8
13
 
9
14
  export type StringFieldProps =
10
15
  | StringFieldInputProps
@@ -52,26 +52,26 @@ export const StringFieldPassword = ({
52
52
  onChange={(event) => setValue(event.target.value)}
53
53
  />
54
54
  <button
55
- className="absolute right-0 flex h-full w-8 items-center justify-center text-muted-foreground"
55
+ className="text-muted-foreground absolute right-0 flex h-full w-8 items-center justify-center"
56
56
  disabled={disabled || readOnly}
57
57
  tabIndex={-1}
58
58
  type="button"
59
59
  onClick={() => setShow(!show)}
60
60
  >
61
- <EyeIcon className={cn('absolute transition-all', show ? '-rotate-90 scale-0' : 'rotate-0 scale-100')} />
62
- <EyeOffIcon className={cn('absolute transition-all', !show ? 'rotate-90 scale-0' : 'rotate-0 scale-100')} />
61
+ <EyeIcon className={cn('absolute transition-all', show ? 'scale-0 -rotate-90' : 'scale-100 rotate-0')} />
62
+ <EyeOffIcon className={cn('absolute transition-all', !show ? 'scale-0 rotate-90' : 'scale-100 rotate-0')} />
63
63
  </button>
64
64
  </FieldGroup.Row>
65
65
  {strength !== null && (
66
66
  <motion.div
67
67
  animate={{ width: `${Math.max(strength * 25, 5)}%` }}
68
- className="h-1 w-full overflow-hidden rounded"
68
+ className="h-1 w-full overflow-hidden rounded-sm"
69
69
  initial={{ width: '5%' }}
70
70
  transition={{ duration: 0.5 }}
71
71
  >
72
72
  <div
73
73
  className={cn(
74
- 'h-full w-full bg-destructive transition-colors duration-500',
74
+ 'bg-destructive h-full w-full transition-colors duration-500',
75
75
  strength === 2 && 'bg-yellow-500 dark:bg-yellow-700',
76
76
  strength === 3 && 'bg-sky-500 dark:bg-sky-700',
77
77
  strength === 4 && 'bg-green-500 dark:bg-green-700'
@@ -5,7 +5,8 @@ import { Label } from '@/components/Label';
5
5
  import { Select } from '@/components/Select';
6
6
 
7
7
  import { FieldGroup } from '../FieldGroup';
8
- import { type BaseFieldComponentProps } from '../types';
8
+
9
+ import type { BaseFieldComponentProps } from '../types';
9
10
 
10
11
  export type StringFieldSelectProps<T extends string = string> = Simplify<
11
12
  BaseFieldComponentProps<T> & Extract<StringFormField<T>, { options: object }>
@@ -12,7 +12,7 @@ export const HoverCardContent = forwardRef<
12
12
  <Content
13
13
  align={align}
14
14
  className={cn(
15
- 'z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
15
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 rounded-md border p-4 shadow-md outline-hidden',
16
16
  className
17
17
  )}
18
18
  ref={ref}
@@ -9,7 +9,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(function Inp
9
9
  <input
10
10
  autoComplete="off"
11
11
  className={cn(
12
- 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground placeholder:opacity-80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
12
+ 'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:opacity-80 focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
13
13
  className
14
14
  )}
15
15
  data-testid="input"
@@ -1,7 +1,8 @@
1
1
  import { forwardRef } from 'react';
2
2
 
3
3
  import * as LabelPrimitive from '@radix-ui/react-label';
4
- import { cva, type VariantProps } from 'class-variance-authority';
4
+ import { cva } from 'class-variance-authority';
5
+ import type { VariantProps } from 'class-variance-authority';
5
6
 
6
7
  import { cn } from '@/utils';
7
8
 
@@ -3,9 +3,11 @@ import { LanguagesIcon } from 'lucide-react';
3
3
  import { useTranslation } from '@/hooks';
4
4
  import type { Language } from '@/i18n';
5
5
 
6
- import { Button, type ButtonProps } from '../Button';
6
+ import { Button } from '../Button';
7
7
  import { DropdownMenu } from '../DropdownMenu';
8
8
 
9
+ import type { ButtonProps } from '../Button';
10
+
9
11
  export type LanguageToggleProps = {
10
12
  align?: 'center' | 'end' | 'start';
11
13
  contentClassName?: string;
@@ -8,16 +8,17 @@ import {
8
8
  Legend,
9
9
  Line,
10
10
  LineChart,
11
- type LineProps,
12
11
  ResponsiveContainer,
13
12
  Tooltip,
14
13
  XAxis,
15
14
  YAxis
16
15
  } from 'recharts';
16
+ import type { LineProps } from 'recharts';
17
17
  import type { ConditionalKeys } from 'type-fest';
18
18
 
19
19
  import { useTranslation } from '@/hooks';
20
- import { type Theme, useTheme } from '@/hooks/useTheme';
20
+ import { useTheme } from '@/hooks/useTheme';
21
+ import type { Theme } from '@/hooks/useTheme';
21
22
 
22
23
  /** An array of arbitrary objects with data to graph */
23
24
 
@@ -26,11 +27,14 @@ type LineGraphData = readonly { [key: string]: any }[];
26
27
  /** Extract string keys from items in `T` where the value of `T[K]` extends `K` */
27
28
  type ExtractValidKeys<T extends LineGraphData, K> = Extract<ConditionalKeys<T[number], K>, string>;
28
29
 
29
- type LineGraphLine<T extends LineGraphData = { [key: string]: any }[]> = {
30
+ type LineGraphLine<T extends LineGraphData = { [key: string]: any }[]> = Pick<
31
+ LineProps,
32
+ 'legendType' | 'stroke' | 'strokeDasharray' | 'strokeWidth' | 'type'
33
+ > & {
30
34
  err?: ExtractValidKeys<T, number>;
31
35
  name: string;
32
36
  val: ExtractValidKeys<T, number>;
33
- } & Pick<LineProps, 'legendType' | 'stroke' | 'strokeDasharray' | 'strokeWidth' | 'type'>;
37
+ };
34
38
 
35
39
  const strokeColors = {
36
40
  dark: '#cbd5e1', // slate-300
@@ -6,10 +6,6 @@ import { ListboxDropdown } from './ListboxDropdown';
6
6
 
7
7
  type Story = StoryObj<typeof ListboxDropdown>;
8
8
 
9
- const meta: Meta<typeof ListboxDropdown> = { component: ListboxDropdown };
10
-
11
- export default meta;
12
-
13
9
  const options = [
14
10
  {
15
11
  key: 'o1',
@@ -25,6 +21,10 @@ const options = [
25
21
  }
26
22
  ];
27
23
 
24
+ export default {
25
+ component: ListboxDropdown
26
+ } satisfies Meta<typeof ListboxDropdown>;
27
+
28
28
  export const Default: Story = {
29
29
  decorators: [
30
30
  (Story) => {
@@ -2,10 +2,11 @@ import * as React from 'react';
2
2
 
3
3
  import { cn } from '@/utils';
4
4
 
5
- import { type ButtonProps } from '../Button';
6
5
  import { DropdownButton } from '../DropdownButton';
7
6
  import { DropdownMenu } from '../DropdownMenu';
8
7
 
8
+ import type { ButtonProps } from '../Button';
9
+
9
10
  export type ListboxDropdownOption = {
10
11
  key: string;
11
12
  label: string;
@@ -13,7 +13,7 @@ export const MenuBarCheckboxItem = forwardRef<
13
13
  <CheckboxItem
14
14
  checked={checked}
15
15
  className={cn(
16
- 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
16
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
17
17
  className
18
18
  )}
19
19
  ref={ref}
@@ -6,14 +6,14 @@ 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
15
15
  className={cn(
16
- 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
16
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
17
17
  inset && 'pl-8',
18
18
  className
19
19
  )}
@@ -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
  });
@@ -12,7 +12,7 @@ export const MenuBarRadioItem = forwardRef<
12
12
  return (
13
13
  <RadioItem
14
14
  className={cn(
15
- 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
15
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
16
16
  className
17
17
  )}
18
18
  ref={ref}
@@ -8,7 +8,7 @@ export const MenuBarRoot = forwardRef<React.ElementRef<typeof Root>, React.Compo
8
8
  function MenuBarRoot({ className, ...props }, ref) {
9
9
  return (
10
10
  <Root
11
- className={cn('flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-sm', className)}
11
+ className={cn('bg-background flex h-9 items-center space-x-1 rounded-md border p-1 shadow-xs', className)}
12
12
  ref={ref}
13
13
  {...props}
14
14
  />
@@ -7,14 +7,14 @@ 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
16
16
  className={cn(
17
- 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
17
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none',
18
18
  inset && 'pl-8',
19
19
  className
20
20
  )}
@@ -10,7 +10,7 @@ export const MenuBarTrigger = forwardRef<
10
10
  return (
11
11
  <Trigger
12
12
  className={cn(
13
- 'flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
13
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-xs px-3 py-1 text-sm font-medium outline-hidden select-none',
14
14
  className
15
15
  )}
16
16
  ref={ref}
@@ -33,11 +33,11 @@ const NotificationHub = ({ timeout = 5000 }: NotificationHubProps) => {
33
33
  <div className="p-4">
34
34
  <div className="mb-2 flex items-center">
35
35
  <NotificationIcon type={item.type} />
36
- <h5 className="ml-3 flex-grow font-medium text-slate-900 dark:text-slate-100">
36
+ <h5 className="ml-3 grow font-medium text-slate-900 dark:text-slate-100">
37
37
  {item.title ?? t(`notifications.types.${item.type}`)}
38
38
  </h5>
39
39
  <button
40
- className="inline-flex rounded-md text-slate-400 hover:text-slate-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:focus:ring-sky-600"
40
+ className="inline-flex rounded-md text-slate-400 hover:text-slate-500 focus:ring-1 focus:ring-sky-500 focus:outline-hidden dark:focus:ring-sky-600"
41
41
  type="button"
42
42
  onClick={() => {
43
43
  dismissNotification(item.id);
@@ -46,7 +46,7 @@ const NotificationHub = ({ timeout = 5000 }: NotificationHubProps) => {
46
46
  <XIcon aria-hidden="true" className="h-5 w-5" />
47
47
  </button>
48
48
  </div>
49
- <p className="my-2 text-muted-foreground">{item.message}</p>
49
+ <p className="text-muted-foreground my-2">{item.message}</p>
50
50
  </div>
51
51
  <motion.div
52
52
  animate={{ width: '100%' }}
@@ -1,4 +1,4 @@
1
- import { type NotificationInterface } from '@/hooks/useNotificationsStore';
1
+ import type { NotificationInterface } from '@/hooks/useNotificationsStore';
2
2
 
3
3
  export type NotificationIconProps = {
4
4
  type: NotificationInterface['type'];
@@ -4,13 +4,15 @@ import type { Simplify } from 'type-fest';
4
4
 
5
5
  import { cn } from '@/utils';
6
6
 
7
- import { type ButtonProps, buttonVariants } from '../Button';
7
+ import { buttonVariants } from '../Button';
8
+
9
+ import type { ButtonProps } from '../Button';
8
10
 
9
11
  export type PaginationLinkProps = Simplify<
10
- {
11
- isActive?: boolean;
12
- } & Pick<ButtonProps, 'size'> &
13
- React.ComponentProps<'a'>
12
+ Pick<ButtonProps, 'size'> &
13
+ React.ComponentProps<'a'> & {
14
+ isActive?: boolean;
15
+ }
14
16
  >;
15
17
 
16
18
  export const PaginationLink = ({ children, className, isActive, size = 'icon', ...props }: PaginationLinkProps) => (
@@ -3,7 +3,9 @@ import { ChevronLeftIcon } from 'lucide-react';
3
3
  import { useTranslation } from '@/hooks';
4
4
  import { cn } from '@/utils';
5
5
 
6
- import { PaginationLink, type PaginationLinkProps } from './PaginationLink';
6
+ import { PaginationLink } from './PaginationLink';
7
+
8
+ import type { PaginationLinkProps } from './PaginationLink';
7
9
 
8
10
  export const PaginationPrevious = ({ className, ...props }: PaginationLinkProps) => {
9
11
  const { t } = useTranslation('libui');