@tpzdsp/next-toolkit 1.14.2 → 1.15.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 (30) hide show
  1. package/package.json +2 -1
  2. package/src/assets/styles/globals.css +5 -1
  3. package/src/components/ErrorBoundary/ErrorBoundary.stories.tsx +1 -1
  4. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +1 -1
  5. package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
  6. package/src/components/InfoBox/InfoBox.tsx +7 -4
  7. package/src/components/accordion/Accordion.test.tsx +5 -10
  8. package/src/components/accordion/Accordion.tsx +4 -7
  9. package/src/components/divider/RuleDivider.test.tsx +4 -4
  10. package/src/components/form/Input.test.tsx +3 -11
  11. package/src/components/form/Input.tsx +2 -2
  12. package/src/components/form/TextArea.test.tsx +3 -5
  13. package/src/components/form/TextArea.tsx +2 -2
  14. package/src/components/layout/header/Header.stories.tsx +3 -3
  15. package/src/components/layout/header/Header.test.tsx +3 -3
  16. package/src/components/layout/header/HeaderNavClient.test.tsx +3 -3
  17. package/src/components/select/Select.stories.tsx +5 -5
  18. package/src/components/select/Select.test.tsx +2 -2
  19. package/src/components/select/Select.tsx +3 -4
  20. package/src/components/select/SelectSkeleton.test.tsx +1 -2
  21. package/src/components/select/SelectSkeleton.tsx +3 -3
  22. package/src/components/select/common.ts +2 -3
  23. package/src/http/constants.ts +4 -0
  24. package/src/http/fetch.ts +2 -0
  25. package/src/http/logger.test.ts +346 -0
  26. package/src/http/logger.ts +412 -76
  27. package/src/map/useKeyboardDrawing.ts +8 -4
  28. package/src/utils/constants.ts +8 -0
  29. package/src/utils/utils.ts +4 -4
  30. package/src/components/theme/ThemeProvider.tsx +0 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpzdsp/next-toolkit",
3
- "version": "1.14.2",
3
+ "version": "1.15.0",
4
4
  "description": "A reusable React component library for Next.js applications",
5
5
  "engines": {
6
6
  "node": ">= 24.12.0",
@@ -119,6 +119,7 @@
119
119
  "preview": "vite preview",
120
120
  "dev:publish": "yalc publish",
121
121
  "dev:push": "yalc push",
122
+ "tsc:check": "tsc -b --noEmit",
122
123
  "storybook": "storybook dev -p 6006",
123
124
  "release": "semantic-release"
124
125
  },
@@ -45,7 +45,7 @@
45
45
  /* Component-specific styles */
46
46
  @layer components {
47
47
  .focus-yellow {
48
- @apply focus:border-[#ffbf47] focus:outline focus:outline-[3px] focus:outline-[#ffbf47];
48
+ @apply focus:border-focus focus:outline focus:outline-2 focus:outline-focus;
49
49
  }
50
50
 
51
51
  .library-button {
@@ -83,6 +83,10 @@
83
83
  top: calc(calc(var(--border) + var(--shadow)) * -1);
84
84
  }
85
85
  }
86
+
87
+ .input-height {
88
+ @apply h-[38px];
89
+ }
86
90
  }
87
91
 
88
92
  /* Utilities */
@@ -14,7 +14,7 @@ const CustomFallback = ({ error, resetErrorBoundary }: FallbackProps) => (
14
14
  <div role="alert" className="p-4 border border-red-300 rounded-lg bg-red-50">
15
15
  <p className="font-medium text-red-700">Custom Fallback:</p>
16
16
 
17
- <p className="text-red-600">{error.message}</p>
17
+ <p className="text-red-600">{error instanceof Error ? error.message : 'Unknown'}</p>
18
18
 
19
19
  <button
20
20
  className="px-3 py-1 mt-2 text-white bg-red-600 rounded hover:bg-red-700"
@@ -12,7 +12,7 @@ const Bomb = () => {
12
12
  // Custom fallback with button for reset
13
13
  const CustomFallback = ({ error, resetErrorBoundary }: FallbackProps) => (
14
14
  <div role="alert">
15
- <p>Custom fallback: {error.message}</p>
15
+ <p>Custom fallback: {error instanceof Error ? error.message : 'Unknown'}</p>
16
16
 
17
17
  <button onClick={resetErrorBoundary}>Try again</button>
18
18
  </div>
@@ -12,7 +12,7 @@ type ErrorBoundaryProps = {
12
12
 
13
13
  export const ErrorBoundary = ({ children, fallback, onReset }: ErrorBoundaryProps) => {
14
14
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
- const logError = (error: unknown, info: ErrorInfo) => {
15
+ const logError = (_error: unknown, _info: ErrorInfo) => {
16
16
  // send error to third party api, etc
17
17
  };
18
18
 
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { type ReactNode, useRef, useId, useState } from 'react';
3
+ import { type ReactNode, type ComponentType, useRef, useId, useState } from 'react';
4
4
 
5
5
  import { FaInfoCircle } from 'react-icons/fa';
6
6
 
@@ -39,6 +39,8 @@ type Props = {
39
39
  triggerLabel?: string;
40
40
  /** Preferred placement (Floating UI will auto-adjust if needed) */
41
41
  placement?: Placement;
42
+ /** Custom icon component to replace the default FaInfoCircle */
43
+ icon?: ComponentType<{ className?: string }>;
42
44
  };
43
45
 
44
46
  export type InfoBoxProps = ExtendProps<'div', Props>;
@@ -51,6 +53,7 @@ export const InfoBox = ({
51
53
  maxWidth = '320px',
52
54
  triggerLabel = 'Show information',
53
55
  placement = 'bottom-start',
56
+ icon: Icon = FaInfoCircle,
54
57
  className,
55
58
  ...props
56
59
  }: InfoBoxProps) => {
@@ -95,8 +98,8 @@ export const InfoBox = ({
95
98
  const iconClasses = cn(
96
99
  // Icon size
97
100
  'w-5 h-5',
98
- // Icon color - yellow when open, black when closed
99
- isOpen ? 'text-focus' : 'text-black',
101
+ // Icon color - yellow when open, auto when closed
102
+ isOpen ? 'text-focus' : '',
100
103
  // Hover state - yellow
101
104
  'hover:text-focus',
102
105
  // Focus state - yellow
@@ -128,7 +131,7 @@ export const InfoBox = ({
128
131
  className={triggerClasses}
129
132
  {...getReferenceProps()}
130
133
  >
131
- <FaInfoCircle className={iconClasses} aria-hidden="true" />
134
+ <Icon className={iconClasses} aria-hidden="true" />
132
135
  </button>
133
136
 
134
137
  {isOpen && (
@@ -173,14 +173,7 @@ describe('Accordion', () => {
173
173
 
174
174
  const container = screen.getByRole('button').closest('div');
175
175
 
176
- expect(container).toHaveClass(
177
- 'flex',
178
- 'flex-col',
179
- 'gap-2',
180
- 'border-l-2',
181
- 'border-neutral-100',
182
- 'rounded-md',
183
- );
176
+ expect(container).toHaveClass('flex', 'flex-col', 'border-l-2', 'border-neutral-100');
184
177
 
185
178
  const button = screen.getByRole('button');
186
179
 
@@ -190,8 +183,10 @@ describe('Accordion', () => {
190
183
  'items-center',
191
184
  'px-2',
192
185
  'py-1',
193
- 'bg-neutral-100',
194
- 'rounded-md',
186
+ 'text-[color:#000000]',
187
+ 'border-y-2',
188
+ 'border-neutral-100',
189
+ 'focus-yellow',
195
190
  );
196
191
  });
197
192
  });
@@ -28,15 +28,12 @@ export const Accordion = ({
28
28
  const [isOpen, setIsOpen] = useState(defaultOpen);
29
29
 
30
30
  return (
31
- <div
32
- className={cn('flex flex-col gap-2 border-l-2 border-neutral-100 rounded-md', className)}
33
- {...props}
34
- >
31
+ <div className={cn('flex flex-col border-l-2 border-neutral-100', className)} {...props}>
35
32
  <button
36
33
  aria-expanded={isOpen}
37
34
  aria-controls={contentId}
38
- className="flex justify-between items-center px-2 py-1 bg-neutral-100 rounded-md
39
- focus-yellow"
35
+ className="flex justify-between items-center px-2 py-1 bg-[#fefefefe] text-[color:#000000]
36
+ border-y-2 border-neutral-100 focus-yellow"
40
37
  id={buttonId}
41
38
  onClick={() => setIsOpen(!isOpen)}
42
39
  type="button"
@@ -52,7 +49,7 @@ export const Accordion = ({
52
49
  id={contentId}
53
50
  aria-labelledby={buttonId}
54
51
  aria-hidden={!isOpen}
55
- className={cn('px-2 pb-1', isOpen ? 'block' : 'hidden')}
52
+ className={cn('p-2 bg-[#efefef]', isOpen ? 'block' : 'hidden')}
56
53
  >
57
54
  {children}
58
55
  </section>
@@ -93,9 +93,9 @@ describe('RuleDivider', () => {
93
93
 
94
94
  const [firstHr, span, secondHr] = containerElement.children;
95
95
 
96
- expect(firstHr.tagName).toBe('HR');
97
- expect(span.tagName).toBe('SPAN');
98
- expect(secondHr.tagName).toBe('HR');
96
+ expect(firstHr?.tagName).toBe('HR');
97
+ expect(span?.tagName).toBe('SPAN');
98
+ expect(secondHr?.tagName).toBe('HR');
99
99
  });
100
100
 
101
101
  it('should have proper structure when no children provided', () => {
@@ -107,7 +107,7 @@ describe('RuleDivider', () => {
107
107
 
108
108
  const hrElement = containerElement.children[0];
109
109
 
110
- expect(hrElement.tagName).toBe('HR');
110
+ expect(hrElement?.tagName).toBe('HR');
111
111
  });
112
112
 
113
113
  it('should handle empty string as children', () => {
@@ -1,7 +1,6 @@
1
1
  import { Input } from './Input';
2
2
  import { render, screen } from '../../test/renderers';
3
3
 
4
- const ROUNDED_MD = 'rounded-md';
5
4
  const BORDER_ERROR = 'border-error';
6
5
 
7
6
  describe('Input', () => {
@@ -19,13 +18,7 @@ describe('Input', () => {
19
18
 
20
19
  const input = screen.getByRole('textbox');
21
20
 
22
- expect(input).toHaveClass(
23
- ROUNDED_MD,
24
- 'border',
25
- 'p-1',
26
- 'disabled:opacity-60',
27
- 'disabled:bg-gray-100',
28
- );
21
+ expect(input).toHaveClass('border', 'p-1', 'disabled:opacity-60', 'disabled:bg-gray-100');
29
22
  });
30
23
 
31
24
  it('applies error styling when hasError is true', () => {
@@ -57,7 +50,7 @@ describe('Input', () => {
57
50
 
58
51
  const input = screen.getByRole('textbox');
59
52
 
60
- expect(input).toHaveClass(ROUNDED_MD, 'border', 'p-1', 'custom-class');
53
+ expect(input).toHaveClass('border', 'p-1', 'custom-class');
61
54
  });
62
55
 
63
56
  it('allows custom className to override default classes', () => {
@@ -105,7 +98,7 @@ describe('Input', () => {
105
98
 
106
99
  const input = screen.getByRole('textbox');
107
100
 
108
- expect(input).toHaveClass(BORDER_ERROR, 'w-full', ROUNDED_MD, 'border', 'p-1');
101
+ expect(input).toHaveClass(BORDER_ERROR, 'w-full', 'border', 'p-1');
109
102
  });
110
103
 
111
104
  it('handles different input types', () => {
@@ -174,7 +167,6 @@ describe('Input', () => {
174
167
 
175
168
  // Custom classes should override defaults due to twMerge
176
169
  expect(input).toHaveClass('border-green-500', 'p-4');
177
- expect(input).toHaveClass(ROUNDED_MD); // Default class preserved
178
170
  expect(input).toHaveClass('border'); // Base border class is still present
179
171
  expect(input).not.toHaveClass('p-1'); // Overridden by p-4
180
172
  expect(input).not.toHaveClass(BORDER_ERROR); // Overridden by border-green-500
@@ -14,8 +14,8 @@ export const Input = ({ hasError, className, ...props }: InputProps) => {
14
14
  <input
15
15
  {...props}
16
16
  className={cn(
17
- 'rounded-md border p-1 disabled:opacity-60 disabled:bg-gray-100',
18
- hasError ? 'border-error' : '',
17
+ 'border p-1 disabled:opacity-60 disabled:bg-gray-100 input-height focus-yellow',
18
+ hasError ? 'border-error' : 'border-black',
19
19
  className,
20
20
  )}
21
21
  />
@@ -3,7 +3,6 @@ import { render, screen } from '@testing-library/react';
3
3
  import { TextArea } from './TextArea';
4
4
 
5
5
  // Constants for repeated class names
6
- const ROUNDED_MD = 'rounded-md';
7
6
  const BORDER = 'border';
8
7
  const P_1 = 'p-1';
9
8
  const DISABLED_OPACITY = 'disabled:opacity-60';
@@ -26,7 +25,7 @@ describe('TextArea', () => {
26
25
 
27
26
  const textarea = screen.getByRole('textbox');
28
27
 
29
- expect(textarea).toHaveClass(ROUNDED_MD, BORDER, P_1, DISABLED_OPACITY, DISABLED_BG);
28
+ expect(textarea).toHaveClass(BORDER, P_1, DISABLED_OPACITY, DISABLED_BG);
30
29
  });
31
30
 
32
31
  it('applies error styling when hasError is true', () => {
@@ -58,7 +57,7 @@ describe('TextArea', () => {
58
57
 
59
58
  const textarea = screen.getByRole('textbox');
60
59
 
61
- expect(textarea).toHaveClass(ROUNDED_MD, BORDER, P_1, 'custom-class');
60
+ expect(textarea).toHaveClass(BORDER, P_1, 'custom-class');
62
61
  });
63
62
 
64
63
  it('allows custom className to override default classes', () => {
@@ -109,7 +108,7 @@ describe('TextArea', () => {
109
108
 
110
109
  const textarea = screen.getByRole('textbox');
111
110
 
112
- expect(textarea).toHaveClass(BORDER_ERROR, 'w-full', ROUNDED_MD, BORDER, P_1);
111
+ expect(textarea).toHaveClass(BORDER_ERROR, 'w-full', BORDER, P_1);
113
112
  });
114
113
 
115
114
  it('supports required attribute', () => {
@@ -143,7 +142,6 @@ describe('TextArea', () => {
143
142
 
144
143
  // Custom classes should override defaults due to twMerge
145
144
  expect(textarea).toHaveClass('border-green-500', 'p-4');
146
- expect(textarea).toHaveClass(ROUNDED_MD); // Default class preserved
147
145
  expect(textarea).toHaveClass(BORDER); // Base border class is still present
148
146
  expect(textarea).not.toHaveClass(P_1); // Overridden by p-4
149
147
  expect(textarea).not.toHaveClass(BORDER_ERROR); // Overridden by border-green-500
@@ -14,8 +14,8 @@ export const TextArea = ({ hasError, className, ...props }: TextAreaProps) => {
14
14
  <textarea
15
15
  {...props}
16
16
  className={cn(
17
- 'rounded-md border p-1 disabled:opacity-60 disabled:bg-gray-100',
18
- hasError ? 'border-error' : '',
17
+ 'border p-1 disabled:opacity-60 disabled:bg-gray-100',
18
+ hasError ? 'border-error' : 'border-black',
19
19
  className,
20
20
  )}
21
21
  />
@@ -5,9 +5,9 @@ import type { Credentials } from '../../../types/auth';
5
5
  import type { NavLink } from '../../../types/navigation';
6
6
 
7
7
  const navLinks: NavLink[] = [
8
- { label: 'Home', url: '/', isExternal: false },
9
- { label: 'API', url: '/api-docs', isExternal: false },
10
- { label: 'Support', url: 'https://example.com/support', isExternal: true },
8
+ { label: 'Home', url: '/', openInNewTab: false },
9
+ { label: 'API', url: '/api-docs', openInNewTab: false },
10
+ { label: 'Support', url: 'https://example.com/support', openInNewTab: true },
11
11
  ];
12
12
 
13
13
  const authenticatedCredentials: Credentials = {
@@ -3,9 +3,9 @@ import { render, screen } from '../../../test/renderers';
3
3
  import type { NavLink } from '../../../types/navigation';
4
4
 
5
5
  const NAV_LINKS: NavLink[] = [
6
- { label: 'Home', url: '/', isExternal: false },
7
- { label: 'API', url: '/api-docs', isExternal: false },
8
- { label: 'Support', url: 'https://example.com/support', isExternal: true },
6
+ { label: 'Home', url: '/', openInNewTab: false },
7
+ { label: 'API', url: '/api-docs', openInNewTab: false },
8
+ { label: 'Support', url: 'https://example.com/support', openInNewTab: true },
9
9
  ];
10
10
 
11
11
  describe('Header', () => {
@@ -3,9 +3,9 @@ import { render, screen, userEvent } from '../../../test/renderers';
3
3
  import type { NavLink } from '../../../types/navigation';
4
4
 
5
5
  const NAV_LINKS: NavLink[] = [
6
- { label: 'Home', url: '/', isExternal: false },
7
- { label: 'API', url: '/api-docs', isExternal: false },
8
- { label: 'Support', url: 'https://example.com/support', isExternal: true },
6
+ { label: 'Home', url: '/', openInNewTab: false },
7
+ { label: 'API', url: '/api-docs', openInNewTab: false },
8
+ { label: 'Support', url: 'https://example.com/support', openInNewTab: true },
9
9
  ];
10
10
 
11
11
  describe('HeaderNavClient', () => {
@@ -27,7 +27,7 @@ const OPTIONS = [
27
27
  { value: 'vanilla', label: 'Vanilla' },
28
28
  { value: 'mint', label: 'Mint' },
29
29
  { value: 'cookies', label: 'Cookies & Cream' },
30
- ];
30
+ ] as const;
31
31
 
32
32
  const GROUPED_OPTIONS = [
33
33
  {
@@ -46,16 +46,16 @@ const GROUPED_OPTIONS = [
46
46
  { value: 'spinach', label: 'Spinach' },
47
47
  ],
48
48
  },
49
- ];
49
+ ] as const;
50
50
 
51
51
  const USERS = [
52
52
  { value: 'john', label: 'John Doe', email: 'john@example.com' },
53
53
  { value: 'jane', label: 'Jane Smith', email: 'jane@example.com' },
54
54
  { value: 'bob', label: 'Bob Johnson', email: 'bob@example.com' },
55
- ];
55
+ ] as const;
56
56
 
57
- const FLAVOUR_PLACEHOLDER_TEXT = 'Select a flavour...';
58
- const FLAVOUR_MULTI_PLACEHOLDER_TEXT = 'Select multiple flavours...';
57
+ const FLAVOUR_PLACEHOLDER_TEXT = 'Select a flavour...' as const;
58
+ const FLAVOUR_MULTI_PLACEHOLDER_TEXT = 'Select multiple flavours...' as const;
59
59
 
60
60
  export const Default: Story = {
61
61
  args: {
@@ -346,11 +346,11 @@ describe('Select', () => {
346
346
 
347
347
  // Check which option was actually selected
348
348
  const selectedCall = onChangeMock.mock.calls[0];
349
- const selectedOption = selectedCall[0];
349
+ const selectedOption = selectedCall?.[0];
350
350
 
351
351
  // Verify the selected option is displayed
352
352
  await waitFor(() => {
353
- expect(screen.getByText(selectedOption.label)).toBeInTheDocument();
353
+ expect(screen.getByText(selectedOption?.label)).toBeInTheDocument();
354
354
  });
355
355
  });
356
356
 
@@ -13,7 +13,7 @@ import type {
13
13
  } from 'react-select';
14
14
  import { components, default as ReactSelect } from 'react-select';
15
15
 
16
- import { SELECT_CONTAINER_CLASSES, SELECT_CONTROL_CLASSES, SELECT_MIN_HEIGHT } from './common';
16
+ import { SELECT_CONTAINER_CLASSES, SELECT_CONTROL_CLASSES } from './common';
17
17
  import { cn } from '../../utils';
18
18
 
19
19
  // extends the react-select props with some of our own
@@ -30,7 +30,6 @@ const getClassNames = <Option, IsMulti extends boolean, Group extends GroupBase<
30
30
  control: (props) =>
31
31
  cn(
32
32
  SELECT_CONTROL_CLASSES,
33
- SELECT_MIN_HEIGHT,
34
33
  props.isDisabled ? '!cursor-not-allowed bg-gray-100' : 'bg-white',
35
34
  props.isFocused
36
35
  ? 'shadow-[0px_0px_0px_theme(borderWidth.form)_theme(colors.focus)] border-focus'
@@ -41,7 +40,7 @@ const getClassNames = <Option, IsMulti extends boolean, Group extends GroupBase<
41
40
  placeholder: (props) => cn('text-text-secondary', userClassNames?.placeholder?.(props)),
42
41
  menu: (props) =>
43
42
  cn(
44
- 'bg-white rounded-md border mt-1 overflow-hidden shadow-sm shadow-[0px_0px_6px_0px_#00000044]',
43
+ 'bg-white border border-black mt-1 overflow-hidden shadow-sm shadow-[0px_0px_6px_0px_#00000044]',
45
44
  userClassNames?.menu?.(props),
46
45
  ),
47
46
  menuList: (props) => cn('flex flex-col', userClassNames?.menuList?.(props)),
@@ -64,7 +63,7 @@ const getClassNames = <Option, IsMulti extends boolean, Group extends GroupBase<
64
63
  ),
65
64
  multiValue: (props) =>
66
65
  cn(
67
- 'flex gap-2 items-center justify-center px-2 bg-brand text-white rounded-md m-[2px]',
66
+ 'flex gap-2 items-center justify-center px-2 bg-brand text-white m-[2px]',
68
67
  userClassNames?.multiValue?.(props),
69
68
  ),
70
69
  multiValueRemove: (props) => cn('w-3 h-3', userClassNames?.multiValueRemove?.(props)),
@@ -27,7 +27,6 @@ describe('SelectSkeleton', () => {
27
27
  'h-full',
28
28
  'bg-gray-100',
29
29
  'animate-pulse',
30
- 'rounded-md',
31
30
  'col-span-2',
32
31
  );
33
32
  });
@@ -70,7 +69,7 @@ describe('SelectSkeleton', () => {
70
69
  expect(containerElement.tagName).toBe('DIV');
71
70
  });
72
71
 
73
- it('should apply SELECT_CONTROL_CLASSES and SELECT_MIN_HEIGHT to control element', () => {
72
+ it('should apply SELECT_CONTROL_CLASSES to control element', () => {
74
73
  const { container } = render(<SelectSkeleton />);
75
74
 
76
75
  const controlElement = container.firstChild?.firstChild as HTMLElement;
@@ -1,4 +1,4 @@
1
- import { SELECT_CONTAINER_CLASSES, SELECT_CONTROL_CLASSES, SELECT_MIN_HEIGHT } from './common';
1
+ import { SELECT_CONTAINER_CLASSES, SELECT_CONTROL_CLASSES } from './common';
2
2
  import type { ExtendProps } from '../../types';
3
3
  import { cn } from '../../utils';
4
4
 
@@ -12,9 +12,9 @@ export type SelectSkeletonProps = ExtendProps<'div', Props>;
12
12
  export const SelectSkeleton = ({ className, ...props }: SelectSkeletonProps = {}) => {
13
13
  return (
14
14
  <div className={cn(SELECT_CONTAINER_CLASSES, className)} {...props}>
15
- <div className={cn(SELECT_CONTROL_CLASSES, SELECT_MIN_HEIGHT)}>
15
+ <div className={cn(SELECT_CONTROL_CLASSES, 'p-2')}>
16
16
  <div
17
- className="w-full h-full bg-gray-100 animate-pulse rounded-md col-span-2"
17
+ className="w-full h-full bg-gray-100 animate-pulse col-span-2"
18
18
  aria-label="Loading options"
19
19
  ></div>
20
20
  </div>
@@ -1,4 +1,3 @@
1
- export const SELECT_MIN_HEIGHT = '!min-h-[38px]';
2
- export const SELECT_CONTAINER_CLASSES = 'w-full h-max select-none !pointer-events-auto';
1
+ export const SELECT_CONTAINER_CLASSES = 'w-full select-none !pointer-events-auto input-height';
3
2
  export const SELECT_CONTROL_CLASSES =
4
- 'px-2 py-2 !grid gap-4 grid-cols-[1fr_min-content] w-full border h-full rounded-md';
3
+ 'p-1 !grid gap-4 grid-cols-[1fr_min-content] w-full border input-height border-black';
@@ -11,6 +11,8 @@ export const MimeType = {
11
11
  UrlEncodedForm: 'application/x-www-form-urlencoded',
12
12
  MultipartForm: 'multipart/form-data',
13
13
  Text: 'text/plain',
14
+ NTriples: 'application/n-triples',
15
+ OctetStream: 'application/octet-stream',
14
16
  } as const;
15
17
 
16
18
  /**
@@ -49,6 +51,7 @@ export const HttpStatus = {
49
51
  UnprocessableContent: 422,
50
52
  InternalServerError: 500,
51
53
  NotImplemented: 501,
54
+ BadGateway: 502,
52
55
  } as const;
53
56
 
54
57
  /**
@@ -71,6 +74,7 @@ export const HttpStatusText = {
71
74
  UnprocessableContent: 'Unprocessable Content',
72
75
  InternalServerError: 'Internal Server Error',
73
76
  NotImplemented: 'Not Implemented',
77
+ BadGateway: 'Bad Gateway',
74
78
  } as const;
75
79
 
76
80
  /**
package/src/http/fetch.ts CHANGED
@@ -14,6 +14,8 @@ import {
14
14
  type BetterFetchPlugin,
15
15
  } from '@better-fetch/fetch';
16
16
 
17
+ export { type BetterFetchPlugin } from '@better-fetch/fetch';
18
+
17
19
  import { ApiError } from '../errors';
18
20
  import { Header, isJsonMimeType, MimeType, type HttpMethods } from './constants';
19
21
  import { HttpStatus } from './constants';