karsten-design-system 1.1.72 → 1.1.74

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.
package/dist/index.js CHANGED
@@ -346,11 +346,12 @@ function CalendarInput({ error, placeholder = 'Selecione uma data', label, disab
346
346
  return (jsx("div", { className: "relative flex flex-col w-full min-w-full", children: jsxs("div", { onClick: handleInputClick, children: [jsx(FloatingLabel, { value: props?.value ? props.value.toString() : '', label: label, disabled: disabled, error: error }), jsxs("div", { className: "relative w-full min-w-full", children: [jsx(Calendar, { ...props, disabled: disabled, placeholder: placeholder, ref: calendarRef, panelStyle: { width: '530px', height: '500px' }, className: clsx('w-full min-w-full focus:shadow-none border-none z-0 font-roboto border rounded-md', hasError
347
347
  ? 'border-redError placeholder:!text-redError p-invalid'
348
348
  : 'border-gray focus:border-primary', disabled && 'border-stoneDark text-disabled', error && 'border-redError text-redError p-invalid', !error && 'border-gray p-custom'), dateFormat: "dd/mm/yy", inputStyle: {
349
- border: `1px solid ${error && !props.value ? '#EC4A54' : '#a0a4b3'}`,
349
+ border: `0.3px solid ${error && !props.value ? '#EC4A54' : '#A0A4B3'}`,
350
350
  boxShadow: 'none',
351
351
  color: hasError ? '#EC4A54' : '',
352
- height: '42px',
352
+ borderRadius: '6px',
353
353
  fontSize: '16px',
354
+ height: '42px',
354
355
  }, hideOnDateTimeSelect: true, hideOnRangeSelection: true, todayButtonClassName: "bg-primary text-background", dateTemplate: dateTemplate, invalid: hasError, locale: "pt-BR" }), jsx(InputIcon, { className: clsx(`pi pi-calendar text-gray cursor-pointer absolute right-3 top-1/2 transform -translate-y-1/2`, disabled && 'text-disabled', hasError && 'text-redError') })] }), hasError && (jsx("div", { className: "mb-4", children: jsx("span", { className: "absolute text-redError text-xs px-2", children: error }) }))] }) }));
355
356
  }
356
357
 
@@ -703,12 +704,13 @@ function Modal({ title, size = 'md', onClose, onConfirm, labelCloseButton = 'Fec
703
704
  }
704
705
 
705
706
  function MultiSelect(props) {
706
- const { options, placeholder = 'Selecione uma opção', label = 'Opção', disabled = false, error, isLoading = false, isReadOnly = true, ariaLabel = 'Selecione uma ou mais opções', } = props;
707
+ const { options, placeholder = 'Selecione uma opção', label = 'Opção', disabled = false, error, isLoading = false, isReadOnly = true, ariaLabel = 'Selecione uma ou mais opções', isLoadingOptions = false, } = props;
707
708
  const [isOpen, setIsOpen] = useState(false);
708
709
  const [visibleText, setVisibleText] = useState('');
709
710
  const [searchText, setSearchText] = useState('');
710
711
  const [highlightedIndex, setHighlightedIndex] = useState(-1);
711
712
  const containerRef = useRef(null);
713
+ const inputRef = useRef(null);
712
714
  const normalize = (str) => str
713
715
  .normalize('NFD')
714
716
  .replace(/[\u0300-\u036f]/g, '')
@@ -722,6 +724,11 @@ function MultiSelect(props) {
722
724
  setSearchText('');
723
725
  setHighlightedIndex(-1);
724
726
  }
727
+ else {
728
+ setTimeout(() => {
729
+ inputRef.current?.focus();
730
+ }, 0);
731
+ }
725
732
  }
726
733
  };
727
734
  const handleSelect = (option) => {
@@ -732,12 +739,17 @@ function MultiSelect(props) {
732
739
  : [...currentValues, option];
733
740
  props.onChange(newValues.length > 0 ? newValues : null);
734
741
  setSearchText('');
735
- const newFiltered = options.filter((opt) => normalize(opt.label).includes(normalize('')));
742
+ const newFiltered = options.filter((opt) => normalize(opt.label).includes(''));
736
743
  const newIndex = newFiltered.findIndex((o) => o.value === option.value);
737
744
  setHighlightedIndex(newIndex);
738
745
  };
739
746
  const hasError = !!error && !disabled;
740
747
  const isInputDisabled = disabled || isLoading;
748
+ useEffect(() => {
749
+ if (isOpen) {
750
+ inputRef.current?.focus();
751
+ }
752
+ }, [isOpen, options]);
741
753
  useEffect(() => {
742
754
  const handleClickOutside = (event) => {
743
755
  if (containerRef.current &&
@@ -773,49 +785,48 @@ function MultiSelect(props) {
773
785
  setVisibleText(`${count} itens selecionados`);
774
786
  }
775
787
  }, [props.value]);
776
- return (jsx(Fragment, { children: jsxs("div", { ref: containerRef, className: "relative flex flex-col w-100", children: [jsxs("div", { className: "relative w-full cursor-pointer", onClick: toggleDropdown, children: [jsx(FloatingLabel, { value: selectedText(), label: label, disabled: isInputDisabled, error: error }), jsxs(IconField, { className: "w-full", children: [jsx(InputText, { placeholder: placeholder, type: "text", value: isLoading
777
- ? 'Carregando...'
778
- : isOpen && !isReadOnly
779
- ? searchText
780
- : visibleText, onChange: (e) => {
781
- setSearchText(e.target.value);
782
- props.onInputChange?.(e.target.value);
783
- if (!isOpen)
784
- setIsOpen(true);
785
- setHighlightedIndex(-1);
786
- }, onKeyDown: (e) => {
787
- if (!isOpen)
788
- return;
789
- if (e.key === 'ArrowDown') {
790
- e.preventDefault();
791
- setHighlightedIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : 0);
792
- }
793
- if (e.key === 'ArrowUp') {
794
- e.preventDefault();
795
- setHighlightedIndex((prev) => prev > 0 ? prev - 1 : filteredOptions.length - 1);
796
- }
797
- if (e.key === 'Enter') {
798
- e.preventDefault();
799
- if (highlightedIndex >= 0 &&
800
- highlightedIndex < filteredOptions.length) {
801
- handleSelect(filteredOptions[highlightedIndex]);
802
- }
803
- }
804
- if (e.key === 'Escape') {
805
- e.preventDefault();
806
- setIsOpen(false);
807
- setSearchText('');
808
- setHighlightedIndex(-1);
788
+ return (jsxs("div", { ref: containerRef, className: "relative flex flex-col w-100", children: [jsxs("div", { className: "relative w-full cursor-pointer", onClick: toggleDropdown, children: [jsx(FloatingLabel, { value: selectedText(), label: label, disabled: isInputDisabled, error: error }), jsxs(IconField, { className: "w-full", children: [jsx(InputText, { ref: inputRef, placeholder: placeholder, type: "text", value: isLoading
789
+ ? 'Carregando...'
790
+ : isOpen && !isReadOnly
791
+ ? searchText
792
+ : visibleText, onChange: (e) => {
793
+ setSearchText(e.target.value);
794
+ props.onInputChange?.(e.target.value);
795
+ if (!isOpen)
796
+ setIsOpen(true);
797
+ setHighlightedIndex(-1);
798
+ }, onKeyDown: (e) => {
799
+ if (!isOpen)
800
+ return;
801
+ if (e.key === 'ArrowDown') {
802
+ e.preventDefault();
803
+ setHighlightedIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : 0);
804
+ }
805
+ if (e.key === 'ArrowUp') {
806
+ e.preventDefault();
807
+ setHighlightedIndex((prev) => prev > 0 ? prev - 1 : filteredOptions.length - 1);
808
+ }
809
+ if (e.key === 'Enter') {
810
+ e.preventDefault();
811
+ if (highlightedIndex >= 0 &&
812
+ highlightedIndex < filteredOptions.length) {
813
+ handleSelect(filteredOptions[highlightedIndex]);
809
814
  }
810
- }, onClick: toggleDropdown, className: clsx('focus:shadow-none text-base w-100 font-roboto border !p-2 rounded-md', hasError
811
- ? 'border-redError placeholder:text-redError'
812
- : 'border-gray focus:border-primary', isInputDisabled && 'border-stoneDark text-disabled', error && 'border-redError text-redError', !error && 'border-gray placeholder:text-gray', isLoading && 'text-gray', 'truncate'), invalid: hasError, readOnly: !isOpen || isReadOnly, style: { height: '42px', fontSize: '16px' }, disabled: isInputDisabled, "aria-label": ariaLabel }), jsx(InputIcon, { className: clsx(isLoading
813
- ? 'pi pi-spinner pi-spin'
814
- : isOpen
815
- ? 'pi pi-angle-up'
816
- : 'pi pi-angle-down', 'text-gray px-2 flex items-center cursor-pointer', isInputDisabled && 'text-disabled', error && 'text-redError'), onClick: toggleDropdown })] })] }), isOpen && !isLoading && (jsx("div", { className: clsx('absolute w-full bg-background border shadow-md z-40 rounded-md -bottom-1 translate-y-full', error ? 'border-redError' : 'border-gray'), children: jsx("div", { children: jsx("ul", { className: "max-h-60 overflow-y-auto", children: filteredOptions.map((option, index) => (jsxs("li", { onClick: () => handleSelect(option), className: clsx('p-2 flex justify-between items-center cursor-pointer', 'hover:bg-stoneBackground hover:font-bold', index === highlightedIndex &&
817
- 'bg-stoneBackground font-bold'), title: option.label, children: [jsx("span", { className: "truncate max-w-[calc(100%-20px)]", children: option.label }), jsx("input", { type: 'checkbox', checked: Array.isArray(props.value) &&
818
- props.value.some((v) => v.value === option.value), onChange: () => handleSelect(option), className: clsx('appearance-none w-2 h-2 ring-1 ring-offset-2 ring-offset-background ring-gray checked:bg-primary cursor-pointer rounded-md') })] }, option.value))) }) }) })), hasError && (jsx("span", { className: "text-redError text-xs px-2", children: error }))] }) }));
815
+ }
816
+ if (e.key === 'Escape') {
817
+ e.preventDefault();
818
+ setIsOpen(false);
819
+ setSearchText('');
820
+ setHighlightedIndex(-1);
821
+ }
822
+ }, onClick: toggleDropdown, className: clsx('focus:shadow-none text-base w-100 font-roboto border !p-2 rounded-md', hasError
823
+ ? 'border-redError placeholder:text-redError'
824
+ : 'border-gray focus:border-primary', isInputDisabled && 'border-stoneDark text-disabled', error && 'border-redError text-redError', !error && 'border-gray placeholder:text-gray', isLoading && 'text-gray', 'truncate'), invalid: hasError, readOnly: !isOpen || isReadOnly, style: { height: '42px', fontSize: '16px' }, disabled: isInputDisabled, "aria-label": ariaLabel }), jsx(InputIcon, { className: clsx(isLoading
825
+ ? 'pi pi-spinner pi-spin'
826
+ : isOpen
827
+ ? 'pi pi-angle-up'
828
+ : 'pi pi-angle-down', 'text-gray px-2 flex items-center cursor-pointer', isInputDisabled && 'text-disabled', error && 'text-redError'), onClick: toggleDropdown })] })] }), isOpen && (jsx("div", { className: clsx('absolute w-full bg-background border shadow-md z-40 rounded-md -bottom-1 translate-y-full', error ? 'border-redError' : 'border-gray'), children: isLoadingOptions ? (jsxs("div", { className: "p-4 text-center text-gray flex items-center justify-center gap-2", children: ["Carregando", jsx("i", { className: "pi pi-spinner pi-spin" })] })) : props.onInputChange && searchText.length === 0 ? (jsx("div", { className: "p-4 text-center text-gray", children: "Digite para pesquisar" })) : filteredOptions.length > 0 ? (jsx("ul", { className: "max-h-60 overflow-y-auto", children: filteredOptions.map((option, index) => (jsxs("li", { onClick: () => handleSelect(option), className: clsx('p-2 flex justify-between items-center cursor-pointer', 'hover:bg-stoneBackground hover:font-bold', index === highlightedIndex && 'bg-stoneBackground font-bold'), title: option.label, children: [jsx("span", { className: "truncate max-w-[calc(100%-20px)]", children: option.label }), jsx("input", { type: 'checkbox', checked: Array.isArray(props.value) &&
829
+ props.value.some((v) => v.value === option.value), onChange: () => handleSelect(option), className: clsx('appearance-none w-2 h-2 ring-1 ring-offset-2 ring-offset-background ring-gray checked:bg-primary cursor-pointer rounded-md') })] }, option.value))) })) : (jsx("div", { className: "p-4 text-center text-gray", children: "Nenhum resultado encontrado" })) })), hasError && jsx("span", { className: "text-redError text-xs px-2", children: error })] }));
819
830
  }
820
831
 
821
832
  function FilterIcon({ color }) {
@@ -4143,11 +4154,12 @@ function RadioButton({ label, value, checked, onChange, disabled = false, error
4143
4154
  }
4144
4155
 
4145
4156
  function Select(props) {
4146
- const { options, placeholder = 'Selecione uma opção', label = 'Opção', disabled = false, error, isLoading = false, isReadOnly = true, ariaLabel = 'Selecione uma opção', } = props;
4157
+ const { options, placeholder = 'Selecione uma opção', label = 'Opção', disabled = false, error, isLoading = false, isReadOnly = true, ariaLabel = 'Selecione uma opção', isLoadingOptions = false, } = props;
4147
4158
  const [isOpen, setIsOpen] = useState(false);
4148
4159
  const [searchText, setSearchText] = useState('');
4149
4160
  const [highlightedIndex, setHighlightedIndex] = useState(-1);
4150
4161
  const containerRef = useRef(null);
4162
+ const inputRef = useRef(null);
4151
4163
  const normalize = (str) => str
4152
4164
  .normalize('NFD')
4153
4165
  .replace(/[\u0300-\u036f]/g, '')
@@ -4159,6 +4171,11 @@ function Select(props) {
4159
4171
  setIsOpen(newState);
4160
4172
  setSearchText('');
4161
4173
  setHighlightedIndex(-1);
4174
+ if (newState) {
4175
+ setTimeout(() => {
4176
+ inputRef.current?.focus();
4177
+ }, 0);
4178
+ }
4162
4179
  }
4163
4180
  };
4164
4181
  const handleSelect = (option) => {
@@ -4174,6 +4191,11 @@ function Select(props) {
4174
4191
  };
4175
4192
  const hasError = !!error && !disabled;
4176
4193
  const isInputDisabled = disabled || isLoading;
4194
+ useEffect(() => {
4195
+ if (isOpen) {
4196
+ inputRef.current?.focus();
4197
+ }
4198
+ }, [options, isOpen]);
4177
4199
  useEffect(() => {
4178
4200
  const handleClickOutside = (event) => {
4179
4201
  if (containerRef.current &&
@@ -4188,7 +4210,7 @@ function Select(props) {
4188
4210
  document.removeEventListener('mousedown', handleClickOutside);
4189
4211
  };
4190
4212
  }, []);
4191
- return (jsxs("div", { ref: containerRef, className: "relative flex flex-col w-100", children: [jsxs("div", { className: "relative w-full cursor-pointer", onClick: toggleDropdown, children: [jsx(FloatingLabel, { value: props.value ? props.value.label : '', label: label, disabled: isInputDisabled, error: error }), jsxs(IconField, { className: "w-full", children: [jsx(InputText, { placeholder: placeholder, type: "text", value: isLoading
4213
+ return (jsxs("div", { ref: containerRef, className: "relative flex flex-col w-100", children: [jsxs("div", { className: "relative w-full cursor-pointer", onClick: toggleDropdown, children: [jsx(FloatingLabel, { value: props.value ? props.value.label : '', label: label, disabled: isInputDisabled, error: error }), jsxs(IconField, { className: "w-full", children: [jsx(InputText, { ref: inputRef, placeholder: placeholder, type: "text", value: isLoading
4192
4214
  ? 'Carregando...'
4193
4215
  : isOpen
4194
4216
  ? searchText
@@ -4228,7 +4250,7 @@ function Select(props) {
4228
4250
  ? 'pi pi-spinner pi-spin'
4229
4251
  : isOpen
4230
4252
  ? 'pi pi-angle-up'
4231
- : 'pi pi-angle-down', 'text-gray px-2 flex items-center cursor-pointer', isInputDisabled && 'text-disabled', error && 'text-redError'), onClick: toggleDropdown })] })] }), isOpen && !isLoading && (jsx("div", { className: clsx('absolute w-full bg-background border shadow-md z-40 rounded-md p-2 -bottom-1 translate-y-full', error ? 'border-redError' : 'border-gray'), children: jsx("ul", { className: "max-h-60 overflow-y-auto", children: filteredOptions.map((option, index) => (jsxs("li", { onClick: () => handleSelect(option), className: clsx('p-2 flex justify-between items-center cursor-pointer', 'hover:bg-stoneBackground hover:font-bold', index === highlightedIndex && 'bg-stoneBackground font-bold'), children: [jsx("span", { className: "truncate max-w-[calc(100%-20px)]", children: option.label }), jsx("input", { type: 'radio', checked: props.value?.value === option.value, onChange: () => handleSelect(option), className: clsx('appearance-none w-2 h-2 rounded-full ring-1 ring-offset-2 ring-offset-background ring-gray checked:bg-primary cursor-pointer') })] }, option.value))) }) })), hasError && jsx("span", { className: "text-redError text-xs px-2", children: error })] }));
4253
+ : 'pi pi-angle-down', 'text-gray px-2 flex items-center cursor-pointer', isInputDisabled && 'text-disabled', error && 'text-redError'), onClick: toggleDropdown })] })] }), isOpen && (jsx("div", { className: clsx('absolute w-full bg-background border shadow-md z-40 rounded-md p-2 -bottom-1 translate-y-full', error ? 'border-redError' : 'border-gray'), children: isLoadingOptions ? (jsxs("div", { className: "p-4 text-center text-gray flex items-center justify-center gap-2", children: ["Carregando", jsx("i", { className: "pi pi-spinner pi-spin" })] })) : props.onInputChange && searchText.length === 0 ? (jsx("div", { className: "p-4 text-center text-gray", children: "Digite para pesquisar" })) : filteredOptions.length > 0 ? (jsx("ul", { className: "max-h-60 overflow-y-auto", children: filteredOptions.map((option, index) => (jsxs("li", { onClick: () => handleSelect(option), className: clsx('p-2 flex justify-between items-center cursor-pointer', 'hover:bg-stoneBackground hover:font-bold', index === highlightedIndex && 'bg-stoneBackground font-bold'), children: [jsx("span", { className: "truncate max-w-[calc(100%-20px)]", children: option.label }), jsx("input", { type: 'radio', checked: props.value?.value === option.value, onChange: () => handleSelect(option), className: clsx('appearance-none w-2 h-2 rounded-full ring-1 ring-offset-2 ring-offset-background ring-gray checked:bg-primary cursor-pointer') })] }, option.value))) })) : (jsx("div", { className: "p-4 text-center text-gray", children: "Nenhum resultado encontrado" })) })), hasError && jsx("span", { className: "text-redError text-xs px-2", children: error })] }));
4232
4254
  }
4233
4255
 
4234
4256
  function Skeleton({ shape = 'rectangle', width = '100%', height = '1rem', borderRadius, animation = 'wave', size, className, }) {