uibee 2.10.5 → 2.11.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 (32) hide show
  1. package/dist/src/components/inputs/checkbox.d.ts +1 -0
  2. package/dist/src/components/inputs/checkbox.js +2 -2
  3. package/dist/src/components/inputs/input.d.ts +1 -0
  4. package/dist/src/components/inputs/input.js +2 -2
  5. package/dist/src/components/inputs/radio.d.ts +1 -0
  6. package/dist/src/components/inputs/radio.js +2 -2
  7. package/dist/src/components/inputs/range.d.ts +1 -0
  8. package/dist/src/components/inputs/range.js +2 -2
  9. package/dist/src/components/inputs/select.d.ts +2 -1
  10. package/dist/src/components/inputs/select.js +2 -2
  11. package/dist/src/components/inputs/shared/fieldWrapper.d.ts +2 -1
  12. package/dist/src/components/inputs/shared/fieldWrapper.js +2 -2
  13. package/dist/src/components/inputs/shared/selectionWrapper.d.ts +2 -1
  14. package/dist/src/components/inputs/shared/selectionWrapper.js +2 -2
  15. package/dist/src/components/inputs/switch.d.ts +1 -0
  16. package/dist/src/components/inputs/switch.js +2 -2
  17. package/dist/src/components/inputs/tagInput.d.ts +2 -1
  18. package/dist/src/components/inputs/tagInput.js +2 -2
  19. package/dist/src/components/inputs/textarea.d.ts +1 -0
  20. package/dist/src/components/inputs/textarea.js +2 -2
  21. package/dist/src/globals.css +6 -0
  22. package/package.json +1 -1
  23. package/src/components/inputs/checkbox.tsx +3 -1
  24. package/src/components/inputs/input.tsx +3 -1
  25. package/src/components/inputs/radio.tsx +3 -1
  26. package/src/components/inputs/range.tsx +3 -1
  27. package/src/components/inputs/select.tsx +3 -0
  28. package/src/components/inputs/shared/fieldWrapper.tsx +7 -0
  29. package/src/components/inputs/shared/selectionWrapper.tsx +8 -1
  30. package/src/components/inputs/switch.tsx +3 -1
  31. package/src/components/inputs/tagInput.tsx +3 -0
  32. package/src/components/inputs/textarea.tsx +3 -1
@@ -3,6 +3,7 @@ export type CheckboxProps = Omit<React.ComponentProps<'input'>, 'name'> & {
3
3
  label?: string;
4
4
  error?: string;
5
5
  info?: string;
6
+ description?: string;
6
7
  className?: string;
7
8
  };
8
9
  export default function Checkbox(props: CheckboxProps): import("react/jsx-runtime").JSX.Element;
@@ -2,8 +2,8 @@ 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
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: `
5
+ const { name, label, error, info, description, className, ...inputProps } = props;
6
+ return (_jsx(SelectionWrapper, { label: label, name: name, required: inputProps.required, info: info, description: description, 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: `
7
7
  peer appearance-none h-5 w-5 rounded border border-login-500 bg-login-500/50
8
8
  checked:bg-login checked:border-login
9
9
  focus:outline-none focus:ring-2 focus:ring-login/50
@@ -6,5 +6,6 @@ export type InputProps = Omit<React.ComponentProps<'input'>, 'name'> & {
6
6
  className?: string;
7
7
  icon?: JSX.Element;
8
8
  info?: string;
9
+ description?: string;
9
10
  };
10
11
  export default function Input(props: InputProps): import("react/jsx-runtime").JSX.Element;
@@ -6,7 +6,7 @@ import DateTimePickerPopup from './shared/dateTimePickerPopup';
6
6
  import ColorPickerPopup from './shared/colorPickerPopup';
7
7
  import useClickOutside from '../../hooks/useClickOutside';
8
8
  export default function Input(props) {
9
- const { name, label, error, className, icon, info, ...inputProps } = props;
9
+ const { name, label, error, className, icon, info, description, ...inputProps } = props;
10
10
  const { type = 'text', value } = inputProps;
11
11
  const localRef = useRef(null);
12
12
  const [isOpen, setIsOpen] = useState(false);
@@ -105,7 +105,7 @@ export default function Input(props) {
105
105
  return `${dd}.${MM}.${yyyy} ${hh}:${mm}`;
106
106
  return value;
107
107
  }
108
- 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: `
108
+ return (_jsx(FieldWrapper, { label: label, name: name, required: inputProps.required, info: info, error: error, description: description, className: className, children: _jsxs("div", { className: 'relative flex items-center', ref: containerRef, children: [displayIcon && (_jsx("div", { className: `
109
109
  absolute left-3 text-login-200
110
110
  ${isClickableType && !inputProps.disabled ? 'cursor-pointer hover:text-login-text' : 'pointer-events-none'}
111
111
  `, onClick: handleIconClick, children: displayIcon })), _jsx("input", { ...inputProps, ref: localRef, id: name, name: isClickableType ? undefined : name, type: isClickableType ? 'text' : type, value: isDateType ? getDateDisplayValue() : value, readOnly: isClickableType, onClick: () => isClickableType && !inputProps.disabled && setIsOpen(true), title: label, "aria-invalid": !!error, "aria-describedby": error ? `${name}-error` : undefined, className: `
@@ -3,6 +3,7 @@ export type RadioProps = Omit<React.ComponentProps<'input'>, 'name'> & {
3
3
  label?: string;
4
4
  error?: string;
5
5
  info?: string;
6
+ description?: string;
6
7
  className?: string;
7
8
  };
8
9
  export default function Radio(props: RadioProps): import("react/jsx-runtime").JSX.Element;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SelectionWrapper } from './shared';
3
3
  export default function Radio(props) {
4
- const { name, label, error, info, className, ...inputProps } = props;
4
+ const { name, label, error, info, description, className, ...inputProps } = props;
5
5
  const { value } = inputProps;
6
6
  const id = `${name}-${value}`;
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: `
7
+ return (_jsx(SelectionWrapper, { label: label, name: id, required: inputProps.required, info: info, description: description, 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: `
8
8
  peer appearance-none h-5 w-5 rounded-full border border-login-500 bg-login-500/50
9
9
  checked:bg-login checked:border-login
10
10
  focus:outline-none focus:ring-2 focus:ring-login/50
@@ -4,6 +4,7 @@ export type RangeProps = Omit<React.ComponentProps<'input'>, 'name'> & {
4
4
  error?: string;
5
5
  className?: string;
6
6
  info?: string;
7
+ description?: string;
7
8
  showValue?: boolean;
8
9
  };
9
10
  export default function Range(props: RangeProps): import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { FieldWrapper } from './shared';
3
3
  export default function Range(props) {
4
- const { name, label, error, className, info, showValue = true, ...inputProps } = props;
4
+ const { name, label, error, className, info, description, showValue = true, ...inputProps } = props;
5
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: `
6
+ return (_jsx(FieldWrapper, { label: label, name: name, required: inputProps.required, info: info, description: description, 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: `
7
7
  flex-1 h-2 bg-login-500 rounded-lg appearance-none cursor-pointer
8
8
  accent-login
9
9
  [&::-webkit-slider-thumb]:appearance-none
@@ -15,7 +15,8 @@ export type SelectProps = {
15
15
  required?: boolean;
16
16
  placeholder?: string;
17
17
  info?: string;
18
+ description?: string;
18
19
  clearable?: boolean;
19
20
  searchable?: boolean;
20
21
  };
21
- export default function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder, info, clearable, searchable, }: SelectProps): import("react/jsx-runtime").JSX.Element;
22
+ export default function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder, info, description, clearable, searchable, }: SelectProps): import("react/jsx-runtime").JSX.Element;
@@ -5,7 +5,7 @@ import Image from 'next/image';
5
5
  import { useClickOutside } from '../../hooks';
6
6
  import { ChevronDown, X, Search } from 'lucide-react';
7
7
  import { FieldWrapper } from './shared';
8
- export default function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder = 'Select an option', info, clearable = true, searchable = true, }) {
8
+ export default function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder = 'Select an option', info, description, clearable = true, searchable = true, }) {
9
9
  const [isOpen, setIsOpen] = useState(false);
10
10
  const [searchTerm, setSearchTerm] = useState('');
11
11
  const [selectedOption, setSelectedOption] = useState(options.find(opt => opt.value === value));
@@ -37,7 +37,7 @@ export default function Select({ label, name, value, onChange, options, error, c
37
37
  }
38
38
  }
39
39
  const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchTerm.toLowerCase()));
40
- return (_jsxs(FieldWrapper, { label: label, name: name, required: required, info: info, error: error, className: className, children: [_jsxs("div", { className: 'relative', ref: containerRef, children: [_jsxs("button", { type: 'button', onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, "aria-haspopup": 'listbox', "aria-expanded": isOpen, "aria-labelledby": label ? undefined : name, className: `
40
+ return (_jsxs(FieldWrapper, { label: label, name: name, required: required, info: info, description: description, error: error, className: className, children: [_jsxs("div", { className: 'relative', ref: containerRef, children: [_jsxs("button", { type: 'button', onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, "aria-haspopup": 'listbox', "aria-expanded": isOpen, "aria-labelledby": label ? undefined : name, className: `
41
41
  w-full rounded-md bg-login-500/50 border border-login-500
42
42
  text-login-text text-left
43
43
  focus:outline-none focus:border-login focus:ring-1 focus:ring-login
@@ -5,8 +5,9 @@ interface FieldWrapperProps {
5
5
  required?: boolean;
6
6
  info?: string;
7
7
  error?: string;
8
+ description?: string;
8
9
  children: ReactNode;
9
10
  className?: string;
10
11
  }
11
- export default function FieldWrapper({ label, name, required, info, error, children, className, }: FieldWrapperProps): import("react/jsx-runtime").JSX.Element;
12
+ export default function FieldWrapper({ label, name, required, info, error, description, children, className, }: FieldWrapperProps): import("react/jsx-runtime").JSX.Element;
12
13
  export {};
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import InputLabel from './inputLabel';
3
3
  import InputInfo from './inputInfo';
4
4
  import InputError from './inputError';
5
- export default function FieldWrapper({ label, name, required, info, error, children, className, }) {
6
- return (_jsxs("div", { className: `flex flex-col gap-1 w-full relative ${className || ''}`, children: [(label || info) && (_jsxs("div", { className: 'flex items-center justify-between mb-1', children: [label && (_jsx(InputLabel, { label: label, name: name, required: required, className: 'ml-1' })), info && _jsx(InputInfo, { info: info })] })), children, _jsx(InputError, { error: error, id: `${name}-error` })] }));
5
+ export default function FieldWrapper({ label, name, required, info, error, description, children, className, }) {
6
+ return (_jsxs("div", { className: `flex flex-col gap-1 w-full relative ${className || ''}`, children: [(label || info) && (_jsxs("div", { className: 'flex items-center justify-between mb-1', children: [label && (_jsx(InputLabel, { label: label, name: name, required: required, className: 'ml-1' })), info && _jsx(InputInfo, { info: info })] })), description && (_jsx("p", { className: 'text-sm text-login-100 ml-1 mb-1', children: description })), children, _jsx(InputError, { error: error, id: `${name}-error` })] }));
7
7
  }
@@ -5,10 +5,11 @@ interface SelectionWrapperProps {
5
5
  required?: boolean;
6
6
  info?: string;
7
7
  error?: string;
8
+ description?: string;
8
9
  children: ReactNode;
9
10
  className?: string;
10
11
  disabled?: boolean;
11
12
  hideError?: boolean;
12
13
  }
13
- export default function SelectionWrapper({ label, name, required, info, error, children, className, disabled, hideError, }: SelectionWrapperProps): import("react/jsx-runtime").JSX.Element;
14
+ export default function SelectionWrapper({ label, name, required, info, error, description, children, className, disabled, hideError, }: SelectionWrapperProps): import("react/jsx-runtime").JSX.Element;
14
15
  export {};
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import InputLabel from './inputLabel';
3
3
  import InputInfo from './inputInfo';
4
4
  import InputError from './inputError';
5
- export default function SelectionWrapper({ label, name, required, info, error, children, className, disabled, hideError, }) {
6
- return (_jsxs("div", { className: `flex flex-col gap-1 ${className || ''}`, children: [_jsxs("div", { className: 'flex items-center justify-between mb-1', children: [_jsxs("div", { className: 'flex items-center gap-2', children: [children, label && (_jsx(InputLabel, { label: label, name: name, required: required, disabled: disabled, className: 'select-none cursor-pointer' }))] }), info && _jsx(InputInfo, { info: info })] }), !hideError && _jsx(InputError, { error: error })] }));
5
+ export default function SelectionWrapper({ label, name, required, info, error, description, children, className, disabled, hideError, }) {
6
+ return (_jsxs("div", { className: `flex flex-col gap-1 ${className || ''}`, children: [_jsxs("div", { className: 'flex items-start justify-between mb-1', children: [_jsxs("div", { className: 'flex items-center gap-2', children: [children, label && (_jsx(InputLabel, { label: label, name: name, required: required, disabled: disabled, className: 'select-none cursor-pointer' }))] }), info && _jsx(InputInfo, { info: info })] }), description && (_jsx("p", { className: 'text-xs text-login-200 ml-7 -mt-1 mb-1', children: description })), !hideError && _jsx(InputError, { error: error })] }));
7
7
  }
@@ -3,6 +3,7 @@ export type SwitchProps = Omit<React.ComponentProps<'input'>, 'name'> & {
3
3
  label?: string;
4
4
  error?: string;
5
5
  info?: string;
6
+ description?: string;
6
7
  className?: string;
7
8
  switchOnly?: boolean;
8
9
  };
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SelectionWrapper } from './shared';
3
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: `
4
+ const { name, label, error, info, description, className, switchOnly, ...inputProps } = props;
5
+ return (_jsx(SelectionWrapper, { label: label, name: name, required: inputProps.required, info: info, description: description, 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: `
6
6
  w-11 h-6 bg-login-500/50 rounded-full peer
7
7
  peer-checked:after:translate-x-full peer-checked:after:border-white
8
8
  after:content-[''] after:absolute ${switchOnly ? 'after:top-0.5' : 'after:top-2.75'} after:left-0.5
@@ -9,5 +9,6 @@ export type TagInputProps = {
9
9
  disabled?: boolean;
10
10
  required?: boolean;
11
11
  info?: string;
12
+ description?: string;
12
13
  };
13
- export default function TagInput({ label, name, value, onChange, placeholder, error, className, disabled, required, info, }: TagInputProps): import("react/jsx-runtime").JSX.Element;
14
+ export default function TagInput({ label, name, value, onChange, placeholder, error, className, disabled, required, info, description, }: TagInputProps): import("react/jsx-runtime").JSX.Element;
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from 'react';
4
4
  import { X } from 'lucide-react';
5
5
  import { FieldWrapper } from './shared';
6
- export default function TagInput({ label, name, value = [], onChange, placeholder = 'Add...', error, className, disabled, required, info, }) {
6
+ export default function TagInput({ label, name, value = [], onChange, placeholder = 'Add...', error, className, disabled, required, info, description, }) {
7
7
  const [inputValue, setInputValue] = useState('');
8
8
  function handleKeyDown(e) {
9
9
  if ((e.key === 'Enter' || e.key === ',') && inputValue.trim()) {
@@ -29,7 +29,7 @@ export default function TagInput({ label, name, value = [], onChange, placeholde
29
29
  if (onChange)
30
30
  onChange(newValue);
31
31
  }
32
- return (_jsxs(FieldWrapper, { label: label, name: name, required: required, info: info, error: error, className: className, children: [_jsxs("div", { className: `
32
+ return (_jsxs(FieldWrapper, { label: label, name: name, required: required, info: info, description: description, error: error, className: className, children: [_jsxs("div", { className: `
33
33
  flex flex-wrap gap-2 p-2 rounded-md bg-login-500/50 border border-login-500
34
34
  text-login-text min-h-10.5
35
35
  focus-within:border-login focus-within:ring-1 focus-within:ring-login
@@ -4,6 +4,7 @@ export type TextareaProps = Omit<React.ComponentProps<'textarea'>, 'name'> & {
4
4
  error?: string;
5
5
  className?: string;
6
6
  info?: string;
7
+ description?: string;
7
8
  type?: 'markdown' | 'json' | 'text';
8
9
  };
9
10
  export default function Textarea(props: TextareaProps): import("react/jsx-runtime").JSX.Element;
@@ -13,12 +13,12 @@ function isValidJson(str) {
13
13
  }
14
14
  }
15
15
  export default function Textarea(props) {
16
- const { name, label, error, className, info, type = 'text', rows = 4, ...textareaProps } = props;
16
+ const { name, label, error, className, info, description, type = 'text', rows = 4, ...textareaProps } = props;
17
17
  const { value } = textareaProps;
18
18
  const [preview, setPreview] = useState(false);
19
19
  const jsonError = type === 'json' && value ? isValidJson(value) : undefined;
20
20
  const displayError = jsonError || error;
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: `
21
+ return (_jsx(FieldWrapper, { label: label, name: name, required: textareaProps.required, info: info, description: description, 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: `
22
22
  w-full rounded-md bg-login-500/50 border border-login-500
23
23
  text-login-text
24
24
  p-3
@@ -1028,6 +1028,9 @@
1028
1028
  .-mt-0\.5 {
1029
1029
  margin-top: calc(var(--spacing) * -0.5);
1030
1030
  }
1031
+ .-mt-1 {
1032
+ margin-top: calc(var(--spacing) * -1);
1033
+ }
1031
1034
  .mt-1 {
1032
1035
  margin-top: calc(var(--spacing) * 1);
1033
1036
  }
@@ -1058,6 +1061,9 @@
1058
1061
  .ml-1 {
1059
1062
  margin-left: calc(var(--spacing) * 1);
1060
1063
  }
1064
+ .ml-7 {
1065
+ margin-left: calc(var(--spacing) * 7);
1066
+ }
1061
1067
  .page-container {
1062
1068
  display: grid;
1063
1069
  grid-template-columns: 1fr 1rem minmax(0, 72rem) 1rem 1fr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uibee",
3
- "version": "2.10.5",
3
+ "version": "2.11.0",
4
4
  "description": "Shared components, functions and hooks for reuse across Login projects",
5
5
  "homepage": "https://github.com/Login-Linjeforening-for-IT/uibee#readme",
6
6
  "bugs": {
@@ -6,11 +6,12 @@ export type CheckboxProps = Omit<React.ComponentProps<'input'>, 'name'> & {
6
6
  label?: string
7
7
  error?: string
8
8
  info?: string
9
+ description?: string
9
10
  className?: string
10
11
  }
11
12
 
12
13
  export default function Checkbox(props: CheckboxProps) {
13
- const { name, label, error, info, className, ...inputProps } = props
14
+ const { name, label, error, info, description, className, ...inputProps } = props
14
15
 
15
16
  return (
16
17
  <SelectionWrapper
@@ -18,6 +19,7 @@ export default function Checkbox(props: CheckboxProps) {
18
19
  name={name}
19
20
  required={inputProps.required}
20
21
  info={info}
22
+ description={description}
21
23
  error={error}
22
24
  className={className}
23
25
  disabled={inputProps.disabled}
@@ -12,10 +12,11 @@ export type InputProps = Omit<React.ComponentProps<'input'>, 'name'> & {
12
12
  className?: string
13
13
  icon?: JSX.Element
14
14
  info?: string
15
+ description?: string
15
16
  }
16
17
 
17
18
  export default function Input(props: InputProps) {
18
- const { name, label, error, className, icon, info, ...inputProps } = props
19
+ const { name, label, error, className, icon, info, description, ...inputProps } = props
19
20
  const { type = 'text', value } = inputProps
20
21
  const localRef = useRef<HTMLInputElement>(null)
21
22
  const [isOpen, setIsOpen] = useState(false)
@@ -130,6 +131,7 @@ export default function Input(props: InputProps) {
130
131
  required={inputProps.required}
131
132
  info={info}
132
133
  error={error}
134
+ description={description}
133
135
  className={className}
134
136
  >
135
137
  <div className='relative flex items-center' ref={containerRef}>
@@ -5,11 +5,12 @@ export type RadioProps = Omit<React.ComponentProps<'input'>, 'name'> & {
5
5
  label?: string
6
6
  error?: string
7
7
  info?: string
8
+ description?: string
8
9
  className?: string
9
10
  }
10
11
 
11
12
  export default function Radio(props: RadioProps) {
12
- const { name, label, error, info, className, ...inputProps } = props
13
+ const { name, label, error, info, description, className, ...inputProps } = props
13
14
  const { value } = inputProps
14
15
  const id = `${name}-${value}`
15
16
 
@@ -19,6 +20,7 @@ export default function Radio(props: RadioProps) {
19
20
  name={id}
20
21
  required={inputProps.required}
21
22
  info={info}
23
+ description={description}
22
24
  error={error}
23
25
  className={className}
24
26
  disabled={inputProps.disabled}
@@ -6,11 +6,12 @@ export type RangeProps = Omit<React.ComponentProps<'input'>, 'name'> & {
6
6
  error?: string
7
7
  className?: string
8
8
  info?: string
9
+ description?: string
9
10
  showValue?: boolean
10
11
  }
11
12
 
12
13
  export default function Range(props: RangeProps) {
13
- const { name, label, error, className, info, showValue = true, ...inputProps } = props
14
+ const { name, label, error, className, info, description, showValue = true, ...inputProps } = props
14
15
  const { min = 0, max = 100, step = 1, value = 0 } = inputProps
15
16
 
16
17
  return (
@@ -19,6 +20,7 @@ export default function Range(props: RangeProps) {
19
20
  name={name}
20
21
  required={inputProps.required}
21
22
  info={info}
23
+ description={description}
22
24
  error={error}
23
25
  className={className}
24
26
  >
@@ -24,6 +24,7 @@ export type SelectProps = {
24
24
  required?: boolean
25
25
  placeholder?: string
26
26
  info?: string
27
+ description?: string
27
28
  clearable?: boolean
28
29
  searchable?: boolean
29
30
  }
@@ -40,6 +41,7 @@ export default function Select({
40
41
  required,
41
42
  placeholder = 'Select an option',
42
43
  info,
44
+ description,
43
45
  clearable = true,
44
46
  searchable = true,
45
47
  }: SelectProps) {
@@ -89,6 +91,7 @@ export default function Select({
89
91
  name={name}
90
92
  required={required}
91
93
  info={info}
94
+ description={description}
92
95
  error={error}
93
96
  className={className}
94
97
  >
@@ -9,6 +9,7 @@ interface FieldWrapperProps {
9
9
  required?: boolean
10
10
  info?: string
11
11
  error?: string
12
+ description?: string
12
13
  children: ReactNode
13
14
  className?: string
14
15
  }
@@ -19,6 +20,7 @@ export default function FieldWrapper({
19
20
  required,
20
21
  info,
21
22
  error,
23
+ description,
22
24
  children,
23
25
  className,
24
26
  }: FieldWrapperProps) {
@@ -37,6 +39,11 @@ export default function FieldWrapper({
37
39
  {info && <InputInfo info={info} />}
38
40
  </div>
39
41
  )}
42
+ {description && (
43
+ <p className='text-sm text-login-100 ml-1 mb-1'>
44
+ {description}
45
+ </p>
46
+ )}
40
47
  {children}
41
48
  <InputError error={error} id={`${name}-error`} />
42
49
  </div>
@@ -9,6 +9,7 @@ interface SelectionWrapperProps {
9
9
  required?: boolean
10
10
  info?: string
11
11
  error?: string
12
+ description?: string
12
13
  children: ReactNode
13
14
  className?: string
14
15
  disabled?: boolean
@@ -21,6 +22,7 @@ export default function SelectionWrapper({
21
22
  required,
22
23
  info,
23
24
  error,
25
+ description,
24
26
  children,
25
27
  className,
26
28
  disabled,
@@ -28,7 +30,7 @@ export default function SelectionWrapper({
28
30
  }: SelectionWrapperProps) {
29
31
  return (
30
32
  <div className={`flex flex-col gap-1 ${className || ''}`}>
31
- <div className='flex items-center justify-between mb-1'>
33
+ <div className='flex items-start justify-between mb-1'>
32
34
  <div className='flex items-center gap-2'>
33
35
  {children}
34
36
  {label && (
@@ -43,6 +45,11 @@ export default function SelectionWrapper({
43
45
  </div>
44
46
  {info && <InputInfo info={info} />}
45
47
  </div>
48
+ {description && (
49
+ <p className='text-xs text-login-200 ml-7 -mt-1 mb-1'>
50
+ {description}
51
+ </p>
52
+ )}
46
53
  {!hideError && <InputError error={error} />}
47
54
  </div>
48
55
  )
@@ -5,12 +5,13 @@ export type SwitchProps = Omit<React.ComponentProps<'input'>, 'name'> & {
5
5
  label?: string
6
6
  error?: string
7
7
  info?: string
8
+ description?: string
8
9
  className?: string
9
10
  switchOnly?: boolean
10
11
  }
11
12
 
12
13
  export default function Switch(props: SwitchProps) {
13
- const { name, label, error, info, className, switchOnly, ...inputProps } = props
14
+ const { name, label, error, info, description, className, switchOnly, ...inputProps } = props
14
15
 
15
16
  return (
16
17
  <SelectionWrapper
@@ -18,6 +19,7 @@ export default function Switch(props: SwitchProps) {
18
19
  name={name}
19
20
  required={inputProps.required}
20
21
  info={info}
22
+ description={description}
21
23
  error={error}
22
24
  hideError={switchOnly}
23
25
  className={className}
@@ -15,6 +15,7 @@ export type TagInputProps = {
15
15
  disabled?: boolean
16
16
  required?: boolean
17
17
  info?: string
18
+ description?: string
18
19
  }
19
20
 
20
21
  export default function TagInput({
@@ -28,6 +29,7 @@ export default function TagInput({
28
29
  disabled,
29
30
  required,
30
31
  info,
32
+ description,
31
33
  }: TagInputProps) {
32
34
  const [inputValue, setInputValue] = useState('')
33
35
 
@@ -58,6 +60,7 @@ export default function TagInput({
58
60
  name={name}
59
61
  required={required}
60
62
  info={info}
63
+ description={description}
61
64
  error={error}
62
65
  className={className}
63
66
  >
@@ -9,6 +9,7 @@ export type TextareaProps = Omit<React.ComponentProps<'textarea'>, 'name'> & {
9
9
  error?: string
10
10
  className?: string
11
11
  info?: string
12
+ description?: string
12
13
  type?: 'markdown' | 'json' | 'text'
13
14
  }
14
15
 
@@ -22,7 +23,7 @@ function isValidJson(str: string): string | null {
22
23
  }
23
24
 
24
25
  export default function Textarea(props: TextareaProps) {
25
- const { name, label, error, className, info, type = 'text', rows = 4, ...textareaProps } = props
26
+ const { name, label, error, className, info, description, type = 'text', rows = 4, ...textareaProps } = props
26
27
  const { value } = textareaProps
27
28
  const [preview, setPreview] = useState(false)
28
29
 
@@ -35,6 +36,7 @@ export default function Textarea(props: TextareaProps) {
35
36
  name={name}
36
37
  required={textareaProps.required}
37
38
  info={info}
39
+ description={description}
38
40
  error={displayError}
39
41
  className={className}
40
42
  >