uibee 2.7.17 → 2.8.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.
@@ -1,13 +1,8 @@
1
- import { type ChangeEvent } from 'react';
2
- export type CheckboxProps = {
3
- label?: string;
1
+ export type CheckboxProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
2
  name: string;
5
- checked?: boolean;
6
- onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
7
- className?: string;
8
- disabled?: boolean;
3
+ label?: string;
9
4
  error?: string;
10
5
  info?: string;
11
- required?: boolean;
6
+ className?: string;
12
7
  };
13
- export default function Checkbox({ label, name, checked, onChange, className, disabled, error, info, required, }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
8
+ export default function Checkbox(props: CheckboxProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Check } from 'lucide-react';
3
3
  import { SelectionWrapper } from './shared';
4
- export default function Checkbox({ label, name, checked, onChange, className, disabled, error, info, required, }) {
5
- return (_jsx(SelectionWrapper, { label: label, name: name, required: required, info: info, error: error, className: className, disabled: disabled, children: _jsxs("div", { className: 'relative flex items-center', children: [_jsx("input", { id: name, name: name, type: 'checkbox', checked: checked, onChange: onChange, disabled: disabled, required: required, className: `
4
+ export default function Checkbox(props) {
5
+ const { name, label, error, info, className, ...inputProps } = props;
6
+ return (_jsx(SelectionWrapper, { label: label, name: name, required: inputProps.required, info: info, error: error, className: className, disabled: inputProps.disabled, children: _jsxs("div", { className: 'relative flex items-center', children: [_jsx("input", { ...inputProps, id: name, name: name, type: 'checkbox', className: `
6
7
  peer appearance-none h-5 w-5 rounded border border-login-500 bg-login-500/50
7
8
  checked:bg-login checked:border-login
8
9
  focus:outline-none focus:ring-2 focus:ring-login/50
@@ -1,17 +1,10 @@
1
- import { type ChangeEvent, type JSX } from 'react';
2
- export type InputProps = {
3
- label?: string;
1
+ import { type JSX } from 'react';
2
+ export type InputProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
3
  name: string;
5
- type?: React.HTMLInputTypeAttribute;
6
- placeholder?: string;
7
- value?: string | number;
8
- onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
4
+ label?: string;
9
5
  error?: string;
10
6
  className?: string;
11
- disabled?: boolean;
12
- required?: boolean;
13
7
  icon?: JSX.Element;
14
8
  info?: string;
15
- multiple?: boolean;
16
9
  };
17
- export default function Input({ label, name, type, placeholder, value, onChange, error, className, disabled, required, icon, info, multiple, }: InputProps): import("react/jsx-runtime").JSX.Element;
10
+ export default function Input(props: InputProps): import("react/jsx-runtime").JSX.Element;
@@ -3,21 +3,27 @@ import { useRef, useState } from 'react';
3
3
  import { Calendar, Clock } from 'lucide-react';
4
4
  import { FieldWrapper } from './shared';
5
5
  import DateTimePickerPopup from './shared/dateTimePickerPopup';
6
+ import ColorPickerPopup from './shared/colorPickerPopup';
6
7
  import useClickOutside from '../../hooks/useClickOutside';
7
- export default function Input({ label, name, type = 'text', placeholder, value, onChange, error, className, disabled, required, icon, info, multiple, }) {
8
+ export default function Input(props) {
9
+ const { name, label, error, className, icon, info, ...inputProps } = props;
10
+ const { type = 'text', value } = inputProps;
8
11
  const localRef = useRef(null);
9
12
  const [isOpen, setIsOpen] = useState(false);
10
13
  const containerRef = useClickOutside(() => setIsOpen(false));
11
14
  const isDateType = ['date', 'datetime-local', 'time'].includes(type);
15
+ const isColorType = type === 'color';
16
+ const isClickableType = isDateType || isColorType;
12
17
  function handleIconClick() {
13
- if (isDateType && !disabled) {
18
+ if (isClickableType && !inputProps.disabled) {
14
19
  setIsOpen(!isOpen);
15
20
  }
16
- else if (localRef.current && !disabled) {
21
+ else if (localRef.current && !inputProps.disabled) {
17
22
  localRef.current.focus();
18
23
  }
19
24
  }
20
25
  function handleDateChange(date) {
26
+ const onChange = inputProps.onChange;
21
27
  if (!onChange)
22
28
  return;
23
29
  const pad = (n) => n.toString().padStart(2, '0');
@@ -42,6 +48,19 @@ export default function Input({ label, name, type = 'text', placeholder, value,
42
48
  };
43
49
  onChange(event);
44
50
  }
51
+ function handleColorChange(color) {
52
+ const onChange = inputProps.onChange;
53
+ if (!onChange)
54
+ return;
55
+ const event = {
56
+ target: {
57
+ name,
58
+ value: color,
59
+ type,
60
+ },
61
+ };
62
+ onChange(event);
63
+ }
45
64
  let displayIcon = icon;
46
65
  if (!displayIcon && isDateType) {
47
66
  if (type === 'time') {
@@ -51,6 +70,9 @@ export default function Input({ label, name, type = 'text', placeholder, value,
51
70
  displayIcon = _jsx(Calendar, { className: 'w-4 h-4' });
52
71
  }
53
72
  }
73
+ else if (!displayIcon && isColorType) {
74
+ displayIcon = (_jsx("div", { className: 'w-4 h-4 rounded border border-login-200', style: { backgroundColor: value || '#000000' } }));
75
+ }
54
76
  function getDateValue() {
55
77
  if (!value)
56
78
  return null;
@@ -61,10 +83,10 @@ export default function Input({ label, name, type = 'text', placeholder, value,
61
83
  const date = new Date(value);
62
84
  return isNaN(date.getTime()) ? null : date;
63
85
  }
64
- return (_jsx(FieldWrapper, { label: label, name: name, required: required, info: info, error: error, className: className, children: _jsxs("div", { className: 'relative flex items-center', ref: containerRef, children: [displayIcon && (_jsx("div", { className: `
86
+ return (_jsx(FieldWrapper, { label: label, name: name, required: inputProps.required, info: info, error: error, className: className, children: _jsxs("div", { className: 'relative flex items-center', ref: containerRef, children: [displayIcon && (_jsx("div", { className: `
65
87
  absolute left-3 text-login-200
66
- ${isDateType && !disabled ? 'cursor-pointer hover:text-login-text' : 'pointer-events-none'}
67
- `, onClick: handleIconClick, children: displayIcon })), _jsx("input", { ref: localRef, id: name, name: name, type: isDateType ? 'text' : type, placeholder: placeholder, value: value, onChange: onChange, disabled: disabled, required: required, readOnly: isDateType, onClick: () => isDateType && !disabled && setIsOpen(true), title: label, multiple: multiple, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
88
+ ${isClickableType && !inputProps.disabled ? 'cursor-pointer hover:text-login-text' : 'pointer-events-none'}
89
+ `, onClick: handleIconClick, children: displayIcon })), _jsx("input", { ...inputProps, ref: localRef, id: name, name: name, type: isClickableType ? 'text' : type, value: value, readOnly: isClickableType, onClick: () => isClickableType && !inputProps.disabled && setIsOpen(true), title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
68
90
  w-full rounded-md bg-login-500/50 border border-login-500
69
91
  text-login-text placeholder-login-200
70
92
  focus:outline-none focus:border-login focus:ring-1 focus:ring-login
@@ -73,6 +95,6 @@ export default function Input({ label, name, type = 'text', placeholder, value,
73
95
  transition-all duration-200
74
96
  input-reset
75
97
  ${error ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
76
- ${isDateType && !disabled ? 'cursor-pointer' : ''}
77
- ` }), isOpen && isDateType && !disabled && (_jsx(DateTimePickerPopup, { value: getDateValue(), onChange: handleDateChange, type: type, onClose: () => setIsOpen(false) }))] }) }));
98
+ ${isClickableType && !inputProps.disabled ? 'cursor-pointer' : ''}
99
+ ` }), isOpen && isDateType && !inputProps.disabled && (_jsx(DateTimePickerPopup, { value: getDateValue(), onChange: handleDateChange, type: type, onClose: () => setIsOpen(false) })), isOpen && isColorType && !inputProps.disabled && (_jsx(ColorPickerPopup, { value: value || '', onChange: handleColorChange, onClose: () => setIsOpen(false) }))] }) }));
78
100
  }
@@ -1,14 +1,8 @@
1
- import { type ChangeEvent } from 'react';
2
- export type RadioProps = {
3
- label?: string;
1
+ export type RadioProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
2
  name: string;
5
- value: string | number;
6
- checked?: boolean;
7
- onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
8
- className?: string;
9
- disabled?: boolean;
3
+ label?: string;
10
4
  error?: string;
11
5
  info?: string;
12
- required?: boolean;
6
+ className?: string;
13
7
  };
14
- export default function Radio({ label, name, value, checked, onChange, className, disabled, error, info, required, }: RadioProps): import("react/jsx-runtime").JSX.Element;
8
+ export default function Radio(props: RadioProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SelectionWrapper } from './shared';
3
- export default function Radio({ label, name, value, checked, onChange, className, disabled, error, info, required, }) {
3
+ export default function Radio(props) {
4
+ const { name, label, error, info, className, ...inputProps } = props;
5
+ const { value } = inputProps;
4
6
  const id = `${name}-${value}`;
5
- return (_jsx(SelectionWrapper, { label: label, name: id, required: required, info: info, error: error, className: className, disabled: disabled, children: _jsxs("div", { className: 'relative flex items-center', children: [_jsx("input", { id: id, name: name, type: 'radio', value: value, checked: checked, onChange: onChange, disabled: disabled, required: required, className: `
7
+ return (_jsx(SelectionWrapper, { label: label, name: id, required: inputProps.required, info: info, error: error, className: className, disabled: inputProps.disabled, children: _jsxs("div", { className: 'relative flex items-center', children: [_jsx("input", { ...inputProps, id: id, name: name, type: 'radio', className: `
6
8
  peer appearance-none h-5 w-5 rounded-full border border-login-500 bg-login-500/50
7
9
  checked:bg-login checked:border-login
8
10
  focus:outline-none focus:ring-2 focus:ring-login/50
@@ -1,17 +1,9 @@
1
- import { type ChangeEvent } from 'react';
2
- export type RangeProps = {
3
- label?: string;
1
+ export type RangeProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
2
  name: string;
5
- min?: number;
6
- max?: number;
7
- step?: number;
8
- value?: number;
9
- onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
3
+ label?: string;
10
4
  error?: string;
11
5
  className?: string;
12
- disabled?: boolean;
13
- required?: boolean;
14
6
  info?: string;
15
7
  showValue?: boolean;
16
8
  };
17
- export default function Range({ label, name, min, max, step, value, onChange, error, className, disabled, required, info, showValue, }: RangeProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function Range(props: RangeProps): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { FieldWrapper } from './shared';
3
- export default function Range({ label, name, min = 0, max = 100, step = 1, value = 0, onChange, error, className, disabled, required, info, showValue = true, }) {
4
- return (_jsx(FieldWrapper, { label: label, name: name, required: required, info: info, error: error, className: className, children: _jsxs("div", { className: 'flex items-center gap-4', children: [_jsx("input", { id: name, name: name, type: 'range', min: min, max: max, step: step, value: value, onChange: onChange, disabled: disabled, required: required, title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
3
+ export default function Range(props) {
4
+ const { name, label, error, className, info, showValue = true, ...inputProps } = props;
5
+ const { min = 0, max = 100, step = 1, value = 0 } = inputProps;
6
+ return (_jsx(FieldWrapper, { label: label, name: name, required: inputProps.required, info: info, error: error, className: className, children: _jsxs("div", { className: 'flex items-center gap-4', children: [_jsx("input", { ...inputProps, id: name, name: name, type: 'range', min: min, max: max, step: step, value: value, title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
5
7
  flex-1 h-2 bg-login-500 rounded-lg appearance-none cursor-pointer
6
8
  accent-login
7
9
  [&::-webkit-slider-thumb]:appearance-none
@@ -0,0 +1,7 @@
1
+ import { type JSX } from 'react';
2
+ export type ColorPickerPopupProps = {
3
+ value: string;
4
+ onChange: (color: string) => void;
5
+ onClose: () => void;
6
+ };
7
+ export default function ColorPickerPopup({ value, onChange, onClose }: ColorPickerPopupProps): JSX.Element;
@@ -0,0 +1,185 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useRef } from 'react';
3
+ function hexToHsv(hex) {
4
+ hex = hex.replace('#', '');
5
+ let r = 0, g = 0, b = 0;
6
+ if (hex.length === 3) {
7
+ r = parseInt(hex[0] + hex[0], 16);
8
+ g = parseInt(hex[1] + hex[1], 16);
9
+ b = parseInt(hex[2] + hex[2], 16);
10
+ }
11
+ else if (hex.length === 6) {
12
+ r = parseInt(hex.substring(0, 2), 16);
13
+ g = parseInt(hex.substring(2, 4), 16);
14
+ b = parseInt(hex.substring(4, 6), 16);
15
+ }
16
+ r /= 255;
17
+ g /= 255;
18
+ b /= 255;
19
+ const max = Math.max(r, g, b);
20
+ const min = Math.min(r, g, b);
21
+ const d = max - min;
22
+ let h = 0;
23
+ const s = max === 0 ? 0 : d / max;
24
+ const v = max;
25
+ if (max !== min) {
26
+ switch (max) {
27
+ case r:
28
+ h = (g - b) / d + (g < b ? 6 : 0);
29
+ break;
30
+ case g:
31
+ h = (b - r) / d + 2;
32
+ break;
33
+ case b:
34
+ h = (r - g) / d + 4;
35
+ break;
36
+ }
37
+ h /= 6;
38
+ }
39
+ return { h: h * 360, s: s * 100, v: v * 100 };
40
+ }
41
+ function hsvToRgb(h, s, v) {
42
+ let r = 0, g = 0, b = 0;
43
+ const i = Math.floor(h * 6);
44
+ const f = h * 6 - i;
45
+ const p = v * (1 - s);
46
+ const q = v * (1 - f * s);
47
+ const t = v * (1 - (1 - f) * s);
48
+ switch (i % 6) {
49
+ case 0:
50
+ r = v;
51
+ g = t;
52
+ b = p;
53
+ break;
54
+ case 1:
55
+ r = q;
56
+ g = v;
57
+ b = p;
58
+ break;
59
+ case 2:
60
+ r = p;
61
+ g = v;
62
+ b = t;
63
+ break;
64
+ case 3:
65
+ r = p;
66
+ g = q;
67
+ b = v;
68
+ break;
69
+ case 4:
70
+ r = t;
71
+ g = p;
72
+ b = v;
73
+ break;
74
+ case 5:
75
+ r = v;
76
+ g = p;
77
+ b = q;
78
+ break;
79
+ }
80
+ return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
81
+ }
82
+ function hsvToHex(h, s, v) {
83
+ const { r, g, b } = hsvToRgb(h / 360, s / 100, v / 100);
84
+ function toHex(x) {
85
+ const hex = x.toString(16);
86
+ return hex.length === 1 ? '0' + hex : hex;
87
+ }
88
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
89
+ }
90
+ const PRESET_COLORS = [
91
+ '#f87171', '#fb923c', '#fbbf24', '#facc15', '#a3e635', '#4ade80', '#34d399', '#2dd4bf',
92
+ '#38bdf8', '#60a5fa', '#818cf8', '#a78bfa', '#c084fc', '#e879f9', '#f472b6', '#fb7185'
93
+ ];
94
+ function SaturationPicker({ hsv, onChange }) {
95
+ const containerRef = useRef(null);
96
+ function handleMove(e) {
97
+ if (!containerRef.current)
98
+ return;
99
+ const { left, top, width, height } = containerRef.current.getBoundingClientRect();
100
+ const x = Math.min(Math.max((e.clientX - left) / width, 0), 1);
101
+ const y = Math.min(Math.max((e.clientY - top) / height, 0), 1);
102
+ onChange(x * 100, (1 - y) * 100);
103
+ }
104
+ function handleMouseDown(e) {
105
+ handleMove(e);
106
+ function moveHandler(e) { handleMove(e); }
107
+ function upHandler() {
108
+ window.removeEventListener('mousemove', moveHandler);
109
+ window.removeEventListener('mouseup', upHandler);
110
+ }
111
+ window.addEventListener('mousemove', moveHandler);
112
+ window.addEventListener('mouseup', upHandler);
113
+ }
114
+ const bgColor = hsvToHex(hsv.h, 100, 100);
115
+ return (_jsxs("div", { ref: containerRef, className: 'w-full h-32 relative rounded-md overflow-hidden cursor-crosshair mb-3 select-none', style: { backgroundColor: bgColor }, onMouseDown: handleMouseDown, children: [_jsx("div", { className: 'absolute inset-0 bg-linear-to-r from-white to-transparent' }), _jsx("div", { className: 'absolute inset-0 bg-linear-to-t from-black to-transparent' }), _jsx("div", { className: `
116
+ absolute w-3 h-3 border-2 border-white rounded-full
117
+ shadow-md -translate-x-1/2 -translate-y-1/2 pointer-events-none
118
+ `, style: { left: `${hsv.s}%`, top: `${100 - hsv.v}%` } })] }));
119
+ }
120
+ function HuePicker({ hue, onChange }) {
121
+ const containerRef = useRef(null);
122
+ function handleMove(e) {
123
+ if (!containerRef.current)
124
+ return;
125
+ const { left, width } = containerRef.current.getBoundingClientRect();
126
+ const x = Math.min(Math.max((e.clientX - left) / width, 0), 1);
127
+ onChange(x * 360);
128
+ }
129
+ function handleMouseDown(e) {
130
+ handleMove(e);
131
+ function moveHandler(e) { handleMove(e); }
132
+ function upHandler() {
133
+ window.removeEventListener('mousemove', moveHandler);
134
+ window.removeEventListener('mouseup', upHandler);
135
+ }
136
+ window.addEventListener('mousemove', moveHandler);
137
+ window.addEventListener('mouseup', upHandler);
138
+ }
139
+ return (_jsx("div", { ref: containerRef, className: 'w-full h-3 relative rounded-full cursor-pointer mb-4 select-none', style: { background: 'linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)' }, onMouseDown: handleMouseDown, children: _jsx("div", { className: `
140
+ absolute w-4 h-4 bg-white border border-gray-200
141
+ rounded-full shadow-sm -translate-x-1/2 -translate-y-1/2
142
+ top-1/2 pointer-events-none
143
+ `, style: { left: `${(hue / 360) * 100}%` } }) }));
144
+ }
145
+ export default function ColorPickerPopup({ value, onChange, onClose }) {
146
+ const [hsv, setHsv] = useState(() => hexToHsv(value || '#000000'));
147
+ const [hexInput, setHexInput] = useState(value || '#000000');
148
+ useEffect(() => {
149
+ if (value && value !== hexInput) {
150
+ setHsv(hexToHsv(value));
151
+ setHexInput(value);
152
+ }
153
+ }, [value]);
154
+ function handleColorChange(newHsv) {
155
+ setHsv(newHsv);
156
+ const hex = hsvToHex(newHsv.h, newHsv.s, newHsv.v);
157
+ setHexInput(hex);
158
+ onChange(hex);
159
+ }
160
+ function handleSaturationChange(s, v) { handleColorChange({ ...hsv, s, v }); }
161
+ function handleHueChange(h) { handleColorChange({ ...hsv, h }); }
162
+ function manualHexChange(e) {
163
+ const val = e.target.value;
164
+ setHexInput(val);
165
+ if (/^#[0-9A-F]{6}$/i.test(val)) {
166
+ const newHsv = hexToHsv(val);
167
+ setHsv(newHsv);
168
+ onChange(val);
169
+ }
170
+ }
171
+ return (_jsxs("div", { className: 'absolute top-full left-0 mt-1 z-50 bg-login-600 border border-login-500 rounded-md shadow-lg p-3 w-64 select-none', children: [_jsx(SaturationPicker, { hsv: hsv, onChange: handleSaturationChange }), _jsx(HuePicker, { hue: hsv.h, onChange: handleHueChange }), _jsxs("div", { className: 'flex items-center gap-2 mb-3', children: [_jsx("div", { className: 'text-xs text-login-200 font-mono', children: "HEX" }), _jsx("input", { type: 'text', value: hexInput, onChange: manualHexChange, className: `
172
+ flex-1 min-w-0 bg-login-500 border border-login-500 rounded
173
+ px-2 py-1 text-sm text-login-text focus:outline-none
174
+ focus:border-login focus:ring-1 focus:ring-login
175
+ `, spellCheck: false }), _jsx("div", { className: 'w-8 h-8 rounded border border-login-500 shrink-0', style: { backgroundColor: hexInput } })] }), _jsx("div", { className: 'grid grid-cols-8 gap-1.5 pt-3 border-t border-login-500', children: PRESET_COLORS.map(color => (_jsx("button", { type: 'button', className: `
176
+ w-6 h-6 rounded-sm cursor-pointer hover:scale-110
177
+ hover:zIndex-10 transition-transform ring-1 ring-inset ring-black/10
178
+ `, style: { backgroundColor: color }, onClick: () => {
179
+ const newHsv = hexToHsv(color);
180
+ setHsv(newHsv);
181
+ setHexInput(color);
182
+ onChange(color);
183
+ onClose();
184
+ }, title: color }, color))) })] }));
185
+ }
@@ -3,3 +3,4 @@ export { default as SelectionWrapper } from './selectionWrapper';
3
3
  export { default as InputLabel } from './inputLabel';
4
4
  export { default as InputInfo } from './inputInfo';
5
5
  export { default as InputError } from './inputError';
6
+ export { default as ColorPickerPopup } from './colorPickerPopup';
@@ -3,3 +3,4 @@ export { default as SelectionWrapper } from './selectionWrapper';
3
3
  export { default as InputLabel } from './inputLabel';
4
4
  export { default as InputInfo } from './inputInfo';
5
5
  export { default as InputError } from './inputError';
6
+ export { default as ColorPickerPopup } from './colorPickerPopup';
@@ -1,14 +1,9 @@
1
- import { type ChangeEvent } from 'react';
2
- export type SwitchProps = {
3
- label?: string;
1
+ export type SwitchProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
2
  name: string;
5
- checked?: boolean;
6
- onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
7
- className?: string;
8
- disabled?: boolean;
3
+ label?: string;
9
4
  error?: string;
10
5
  info?: string;
11
- required?: boolean;
6
+ className?: string;
12
7
  switchOnly?: boolean;
13
8
  };
14
- export default function Switch({ label, name, checked, onChange, className, disabled, error, info, required, switchOnly, }: SwitchProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function Switch(props: SwitchProps): import("react/jsx-runtime").JSX.Element;
@@ -1,13 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SelectionWrapper } from './shared';
3
- export default function Switch({ label, name, checked, onChange, className, disabled, error, info, required, switchOnly, }) {
4
- return (_jsx(SelectionWrapper, { label: label, name: name, required: required, info: info, error: error, hideError: switchOnly, className: className, disabled: disabled, children: _jsxs("label", { className: `relative inline-flex items-center cursor-pointer ${switchOnly ? 'h-fit' : 'h-10.5'}`, children: [_jsx("input", { type: 'checkbox', id: name, name: name, checked: checked, onChange: onChange, disabled: disabled, required: required, className: 'sr-only peer' }), _jsx("div", { className: `
3
+ export default function Switch(props) {
4
+ const { name, label, error, info, className, switchOnly, ...inputProps } = props;
5
+ return (_jsx(SelectionWrapper, { label: label, name: name, required: inputProps.required, info: info, error: error, hideError: switchOnly, className: className, disabled: inputProps.disabled, children: _jsxs("label", { className: `relative inline-flex items-center cursor-pointer ${switchOnly ? 'h-fit' : 'h-10.5'}`, children: [_jsx("input", { ...inputProps, type: 'checkbox', id: name, name: name, className: 'sr-only peer' }), _jsx("div", { className: `
5
6
  w-11 h-6 bg-login-500/50 rounded-full peer
6
7
  peer-checked:after:translate-x-full peer-checked:after:border-white
7
8
  after:content-[''] after:absolute ${switchOnly ? 'after:top-0.5' : 'after:top-2.75'} after:left-0.5
8
9
  after:bg-white after:border-gray-300 after:border after:rounded-full
9
10
  after:h-5 after:w-5 after:transition-all peer-checked:bg-login
10
- ${disabled ? 'opacity-50 cursor-not-allowed' : ''}
11
+ ${inputProps.disabled ? 'opacity-50 cursor-not-allowed' : ''}
11
12
  ${error ? 'ring-1 ring-red-500' : ''}
12
13
  ` })] }) }));
13
14
  }
@@ -1,16 +1,9 @@
1
- import { type ChangeEvent } from 'react';
2
- export type TextareaProps = {
3
- label?: string;
1
+ export type TextareaProps = Omit<React.ComponentProps<'textarea'>, 'name'> & {
4
2
  name: string;
5
- placeholder?: string;
6
- type?: 'markdown' | 'json' | 'text';
7
- value?: string;
8
- onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void;
3
+ label?: string;
9
4
  error?: string;
10
5
  className?: string;
11
- disabled?: boolean;
12
- required?: boolean;
13
- rows?: number;
14
6
  info?: string;
7
+ type?: 'markdown' | 'json' | 'text';
15
8
  };
16
- export default function Textarea({ label, name, placeholder, value, onChange, error, className, disabled, required, rows, info, type, }: TextareaProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function Textarea(props: TextareaProps): import("react/jsx-runtime").JSX.Element;
@@ -12,17 +12,19 @@ function isValidJson(str) {
12
12
  return error.message;
13
13
  }
14
14
  }
15
- export default function Textarea({ label, name, placeholder, value, onChange, error, className, disabled, required, rows = 4, info, type = 'text', }) {
15
+ export default function Textarea(props) {
16
+ const { name, label, error, className, info, type = 'text', rows = 4, ...textareaProps } = props;
17
+ const { value } = textareaProps;
16
18
  const [preview, setPreview] = useState(false);
17
19
  const jsonError = type === 'json' && value ? isValidJson(value) : undefined;
18
20
  const displayError = jsonError || error;
19
- return (_jsx(FieldWrapper, { label: label, name: name, required: required, info: info, error: displayError, className: className, children: _jsxs("div", { className: 'relative', children: [type === 'markdown' && (_jsx("div", { className: 'absolute right-2 top-2 z-10 flex gap-2', children: _jsx("button", { type: 'button', onClick: () => setPreview(!preview), className: 'p-1 rounded hover:bg-login-500/50 text-login-text transition-colors', title: preview ? 'Edit' : 'Preview', children: preview ? _jsx(Pencil, { size: 16 }) : _jsx(Eye, { size: 16 }) }) })), type === 'markdown' && preview ? (_jsx("div", { className: `
21
+ return (_jsx(FieldWrapper, { label: label, name: name, required: textareaProps.required, info: info, error: displayError, className: className, children: _jsxs("div", { className: 'relative', children: [type === 'markdown' && (_jsx("div", { className: 'absolute right-2 top-2 z-10 flex gap-2', children: _jsx("button", { type: 'button', onClick: () => setPreview(!preview), className: 'p-1 rounded hover:bg-login-500/50 text-login-text transition-colors', title: preview ? 'Edit' : 'Preview', children: preview ? _jsx(Pencil, { size: 16 }) : _jsx(Eye, { size: 16 }) }) })), type === 'markdown' && preview ? (_jsx("div", { className: `
20
22
  w-full rounded-md bg-login-500/50 border border-login-500
21
23
  text-login-text
22
24
  p-3
23
25
  prose prose-invert prose-sm max-w-none overflow-y-auto
24
26
  ${error ? 'border-red-500' : ''}
25
- `, style: { minHeight: `${rows * 1.5}rem` }, children: _jsx(ReactMarkdown, { children: value || '' }) })) : (_jsx("textarea", { id: name, name: name, placeholder: placeholder, value: value, onChange: onChange, disabled: disabled, required: required, rows: rows, title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
27
+ `, style: { minHeight: `${rows * 1.5}rem` }, children: _jsx(ReactMarkdown, { children: String(value || '') }) })) : (_jsx("textarea", { ...textareaProps, id: name, name: name, rows: rows, title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
26
28
  w-full rounded-md bg-login-500/50 border border-login-500
27
29
  text-login-text placeholder-login-200
28
30
  focus:outline-none focus:border-login focus:ring-1 focus:ring-login