@clicoh/orion-library 1.2.0-beta.1 → 1.2.0-beta.11

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 (114) hide show
  1. package/dist/components/01-atoms/Button/Button.d.ts +4 -1
  2. package/dist/components/01-atoms/Button/Button.d.ts.map +1 -1
  3. package/dist/components/01-atoms/Button/Button.jsx +16 -2
  4. package/dist/components/01-atoms/Button/Button.jsx.map +1 -1
  5. package/dist/components/01-atoms/IconButton/IconButton.d.ts +28 -0
  6. package/dist/components/01-atoms/IconButton/IconButton.d.ts.map +1 -0
  7. package/dist/components/01-atoms/IconButton/IconButton.jsx +32 -0
  8. package/dist/components/01-atoms/IconButton/IconButton.jsx.map +1 -0
  9. package/dist/components/01-atoms/IconButton/index.d.ts +2 -0
  10. package/dist/components/01-atoms/IconButton/index.d.ts.map +1 -0
  11. package/dist/components/01-atoms/IconButton/index.js +2 -0
  12. package/dist/components/01-atoms/IconButton/index.js.map +1 -0
  13. package/dist/components/01-atoms/Input/Input.d.ts +1 -1
  14. package/dist/components/01-atoms/Input/Input.d.ts.map +1 -1
  15. package/dist/components/01-atoms/Input/Input.jsx +7 -4
  16. package/dist/components/01-atoms/Input/Input.jsx.map +1 -1
  17. package/dist/components/01-atoms/Input/utils/border.d.ts +2 -1
  18. package/dist/components/01-atoms/Input/utils/border.d.ts.map +1 -1
  19. package/dist/components/01-atoms/Input/utils/border.js +2 -2
  20. package/dist/components/01-atoms/Input/utils/border.js.map +1 -1
  21. package/dist/components/01-atoms/MultiSelect/MultiSelect.jsx +1 -1
  22. package/dist/components/01-atoms/MultiSelect/MultiSelect.jsx.map +1 -1
  23. package/dist/components/01-atoms/ProgressBar/ProgressBar.d.ts +12 -1
  24. package/dist/components/01-atoms/ProgressBar/ProgressBar.d.ts.map +1 -1
  25. package/dist/components/01-atoms/ProgressBar/ProgressBar.jsx +18 -2
  26. package/dist/components/01-atoms/ProgressBar/ProgressBar.jsx.map +1 -1
  27. package/dist/components/01-atoms/Radio/Radio.jsx +1 -1
  28. package/dist/components/01-atoms/Radio/Radio.jsx.map +1 -1
  29. package/dist/components/01-atoms/Select/Select.d.ts +5 -1
  30. package/dist/components/01-atoms/Select/Select.d.ts.map +1 -1
  31. package/dist/components/01-atoms/Select/Select.jsx +51 -9
  32. package/dist/components/01-atoms/Select/Select.jsx.map +1 -1
  33. package/dist/components/01-atoms/Select/SelectList.d.ts +41 -0
  34. package/dist/components/01-atoms/Select/SelectList.d.ts.map +1 -0
  35. package/dist/components/01-atoms/Select/SelectList.jsx +116 -0
  36. package/dist/components/01-atoms/Select/SelectList.jsx.map +1 -0
  37. package/dist/components/01-atoms/Switch/Switch.d.ts +5 -2
  38. package/dist/components/01-atoms/Switch/Switch.d.ts.map +1 -1
  39. package/dist/components/01-atoms/Switch/Switch.jsx +15 -12
  40. package/dist/components/01-atoms/Switch/Switch.jsx.map +1 -1
  41. package/dist/components/01-atoms/Textarea/Textarea.d.ts +38 -0
  42. package/dist/components/01-atoms/Textarea/Textarea.d.ts.map +1 -0
  43. package/dist/components/01-atoms/Textarea/Textarea.jsx +50 -0
  44. package/dist/components/01-atoms/Textarea/Textarea.jsx.map +1 -0
  45. package/dist/components/01-atoms/Textarea/index.d.ts +2 -0
  46. package/dist/components/01-atoms/Textarea/index.d.ts.map +1 -0
  47. package/dist/components/01-atoms/Textarea/index.js +2 -0
  48. package/dist/components/01-atoms/Textarea/index.js.map +1 -0
  49. package/dist/components/01-atoms/Toast/Toast.d.ts.map +1 -1
  50. package/dist/components/01-atoms/Toast/Toast.jsx +3 -1
  51. package/dist/components/01-atoms/Toast/Toast.jsx.map +1 -1
  52. package/dist/components/01-atoms/index.d.ts +2 -0
  53. package/dist/components/01-atoms/index.d.ts.map +1 -1
  54. package/dist/components/01-atoms/index.js +2 -0
  55. package/dist/components/01-atoms/index.js.map +1 -1
  56. package/dist/components/02-molecules/Accordion/Accordion.d.ts +15 -4
  57. package/dist/components/02-molecules/Accordion/Accordion.d.ts.map +1 -1
  58. package/dist/components/02-molecules/Accordion/Accordion.jsx +20 -6
  59. package/dist/components/02-molecules/Accordion/Accordion.jsx.map +1 -1
  60. package/dist/components/02-molecules/Accordion/AccordionContext.d.ts +5 -1
  61. package/dist/components/02-molecules/Accordion/AccordionContext.d.ts.map +1 -1
  62. package/dist/components/02-molecules/Accordion/AccordionContext.jsx +4 -3
  63. package/dist/components/02-molecules/Accordion/AccordionContext.jsx.map +1 -1
  64. package/dist/components/02-molecules/Accordion/AccordionSection.d.ts +2 -1
  65. package/dist/components/02-molecules/Accordion/AccordionSection.d.ts.map +1 -1
  66. package/dist/components/02-molecules/Accordion/AccordionSection.jsx +35 -8
  67. package/dist/components/02-molecules/Accordion/AccordionSection.jsx.map +1 -1
  68. package/dist/components/02-molecules/Accordion/index.d.ts +1 -0
  69. package/dist/components/02-molecules/Accordion/index.d.ts.map +1 -1
  70. package/dist/components/02-molecules/Accordion/index.js.map +1 -1
  71. package/dist/components/02-molecules/Autocomplete/Autocomplete.d.ts +10 -1
  72. package/dist/components/02-molecules/Autocomplete/Autocomplete.d.ts.map +1 -1
  73. package/dist/components/02-molecules/Autocomplete/Autocomplete.jsx +29 -10
  74. package/dist/components/02-molecules/Autocomplete/Autocomplete.jsx.map +1 -1
  75. package/dist/components/02-molecules/DatePicker/DatePicker.jsx +1 -1
  76. package/dist/components/02-molecules/DatePicker/DatePicker.jsx.map +1 -1
  77. package/dist/components/02-molecules/Filter/Filter.d.ts +1 -0
  78. package/dist/components/02-molecules/Filter/Filter.d.ts.map +1 -1
  79. package/dist/components/02-molecules/Filter/Filter.jsx +25 -4
  80. package/dist/components/02-molecules/Filter/Filter.jsx.map +1 -1
  81. package/dist/components/02-molecules/Filter/index.d.ts +1 -0
  82. package/dist/components/02-molecules/Filter/index.d.ts.map +1 -1
  83. package/dist/components/02-molecules/Filter/index.js +1 -0
  84. package/dist/components/02-molecules/Filter/index.js.map +1 -1
  85. package/dist/components/02-molecules/Filter/types.d.ts +24 -5
  86. package/dist/components/02-molecules/Filter/types.d.ts.map +1 -1
  87. package/dist/components/02-molecules/Filter/utils/pruneOrphanValues.d.ts +34 -0
  88. package/dist/components/02-molecules/Filter/utils/pruneOrphanValues.d.ts.map +1 -0
  89. package/dist/components/02-molecules/Filter/utils/pruneOrphanValues.js +70 -0
  90. package/dist/components/02-molecules/Filter/utils/pruneOrphanValues.js.map +1 -0
  91. package/dist/components/02-molecules/ImageViewer/ImageViewer.d.ts +55 -5
  92. package/dist/components/02-molecules/ImageViewer/ImageViewer.d.ts.map +1 -1
  93. package/dist/components/02-molecules/ImageViewer/ImageViewer.jsx +118 -27
  94. package/dist/components/02-molecules/ImageViewer/ImageViewer.jsx.map +1 -1
  95. package/dist/components/02-molecules/ImageViewer/ImageViewerImage.d.ts +40 -0
  96. package/dist/components/02-molecules/ImageViewer/ImageViewerImage.d.ts.map +1 -0
  97. package/dist/components/02-molecules/ImageViewer/ImageViewerImage.jsx +108 -0
  98. package/dist/components/02-molecules/ImageViewer/ImageViewerImage.jsx.map +1 -0
  99. package/dist/components/02-molecules/Modal/Modal.d.ts +5 -1
  100. package/dist/components/02-molecules/Modal/Modal.d.ts.map +1 -1
  101. package/dist/components/02-molecules/Modal/Modal.jsx +7 -5
  102. package/dist/components/02-molecules/Modal/Modal.jsx.map +1 -1
  103. package/dist/components/02-molecules/index.d.ts +1 -0
  104. package/dist/components/02-molecules/index.d.ts.map +1 -1
  105. package/dist/components/02-molecules/index.js +1 -0
  106. package/dist/components/02-molecules/index.js.map +1 -1
  107. package/dist/components/03-organisms/MapView/MapView.d.ts +14 -3
  108. package/dist/components/03-organisms/MapView/MapView.d.ts.map +1 -1
  109. package/dist/components/03-organisms/MapView/MapView.jsx +36 -7
  110. package/dist/components/03-organisms/MapView/MapView.jsx.map +1 -1
  111. package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.d.ts.map +1 -1
  112. package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.jsx +4 -1
  113. package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.jsx.map +1 -1
  114. package/package.json +3 -2
@@ -1,10 +1,11 @@
1
1
  'use client';
2
2
  import clsx from 'clsx';
3
- import { useId, } from 'react';
3
+ import { useId, useRef, useState, } from 'react';
4
4
  import { FaSortDown } from 'react-icons/fa';
5
- import { Each } from '../../00-base';
5
+ import { Each, Show } from '../../00-base';
6
6
  import { generateBorder } from '../Input/utils/border';
7
7
  import { RenderErrorOrHelperText } from '../Input/utils/RenderErrorOrHelperText';
8
+ import { SelectList } from './SelectList';
8
9
  /**
9
10
  * Select component for rendering a dropdown with customizable options, labels, helper text, and error messages.
10
11
  *
@@ -29,10 +30,12 @@ import { RenderErrorOrHelperText } from '../Input/utils/RenderErrorOrHelperText'
29
30
  * @param {string} [props.error] - Optional error message to be displayed below the select dropdown.
30
31
  * @param {boolean} [props.isMutedWhenEmpty] - Renders the border and label in gray while no option is selected.
31
32
  * @param {boolean} [props.hideLabel] - Keeps the label for assistive technology only and drops the floating label and its border notch. Use it when a heading outside the field already names it; pair it with `placeholder`.
33
+ * @param {ReactNode} [props.labelAddon] - Element rendered right after the floating label, inside the border notch — typically an info icon wrapped in a `Tooltip`. It stays interactive and is not part of the label's accessible name. Ignored with `hideLabel`.
34
+ * @param {boolean} [props.customList=false] - Opens Orion's own option list instead of the native popup, which each browser and OS paints its own way. Same `options`, `select.value` and `select.onChange`: picking an option fires the native `change` event.
32
35
  *
33
36
  * @returns {ReactNode} The rendered Select component.
34
37
  */
35
- export function Select({ label, options, select, placeholder, helperText, error, isMutedWhenEmpty, hideLabel = false, }) {
38
+ export function Select({ label, options, select, placeholder, helperText, error, isMutedWhenEmpty, hideLabel = false, labelAddon, customList = false, }) {
36
39
  const generatedId = useId();
37
40
  const id = select?.id ?? generatedId;
38
41
  const descriptionId = error || helperText ? `${id}-description` : undefined;
@@ -41,6 +44,22 @@ export function Select({ label, options, select, placeholder, helperText, error,
41
44
  const selectProps = !select || !Object.hasOwn(select, 'value')
42
45
  ? { ...select, defaultValue: '' }
43
46
  : select;
47
+ const selectRef = useRef(null);
48
+ const isControlled = Boolean(select && Object.hasOwn(select, 'value'));
49
+ const [uncontrolledValue, setUncontrolledValue] = useState(String(selectProps.defaultValue ?? ''));
50
+ const currentValue = isControlled
51
+ ? String(selectProps.value ?? '')
52
+ : uncontrolledValue;
53
+ const labelId = `${id}-label`;
54
+ const chooseFromList = (value) => {
55
+ const element = selectRef.current;
56
+ if (!element || element.value === value)
57
+ return;
58
+ element.value = value;
59
+ element.dispatchEvent(new Event('change', { bubbles: true }));
60
+ if (!isControlled)
61
+ setUncontrolledValue(value);
62
+ };
44
63
  const isMuted = Boolean(isMutedWhenEmpty && !selectProps.value && !selectProps.defaultValue);
45
64
  const selectClasses = clsx('peer disabled:text-gray-3 dark:disabled:text-gray-2 h-full w-full appearance-none rounded-full border border-none bg-transparent px-5 text-sm font-normal outline-0 transition-all dark:bg-black', isMuted ? 'text-gray-2 dark:text-gray-2' : 'text-black dark:text-white', select?.className);
46
65
  const { labelProps, legendClasses, fieldsetClasses } = generateBorder(error, {
@@ -50,7 +69,7 @@ export function Select({ label, options, select, placeholder, helperText, error,
50
69
  labelProps.htmlFor = id;
51
70
  return (<div className="w-full max-w-full">
52
71
  <div className="relative h-9">
53
- <select {...selectProps} id={id} className={selectClasses} aria-invalid={error ? true : select?.['aria-invalid']} aria-describedby={describedBy}>
72
+ <select {...selectProps} ref={selectRef} id={id} tabIndex={customList ? -1 : selectProps.tabIndex} aria-hidden={customList || undefined} className={clsx(selectClasses, customList && 'pointer-events-none')} aria-invalid={error ? true : select?.['aria-invalid']} aria-describedby={describedBy}>
54
73
  {!!placeholder && (<option value="" disabled hidden className="bg-white text-black dark:bg-black dark:text-white">
55
74
  {placeholder}
56
75
  </option>)}
@@ -58,16 +77,39 @@ export function Select({ label, options, select, placeholder, helperText, error,
58
77
  {text}
59
78
  </option>)}/>
60
79
  </select>
61
- {hideLabel ? (<label htmlFor={id} className="sr-only">
62
- {label}
63
- </label>) : (<label {...labelProps}>{label}</label>)}
64
- <FaSortDown aria-hidden="true" className={clsx('peer-disabled:text-gray-3 dark:peer-disabled:text-gray-2 absolute top-2 right-4', error
80
+ {customList && (<SelectList id={id} labelId={labelId} options={Object.entries(options)} value={currentValue} disabled={select?.disabled} invalid={Boolean(error)} describedBy={describedBy} onChoose={chooseFromList}/>)}
81
+ <Show>
82
+ <Show.When isTrue={hideLabel}>
83
+ <label id={labelId} htmlFor={id} className="sr-only">
84
+ {label}
85
+ </label>
86
+ </Show.When>
87
+ <Show.When isTrue={Boolean(labelAddon)}>
88
+ <div className={clsx(labelProps.className, 'flex items-center gap-1')}>
89
+ <label id={labelId} htmlFor={id}>
90
+ {label}
91
+ </label>
92
+ <span className="pointer-events-auto flex">{labelAddon}</span>
93
+ </div>
94
+ </Show.When>
95
+ <Show.Else>
96
+ <label {...labelProps} id={labelId}>
97
+ {label}
98
+ </label>
99
+ </Show.Else>
100
+ </Show>
101
+ <FaSortDown aria-hidden="true" className={clsx('peer-disabled:text-gray-3 dark:peer-disabled:text-gray-2 pointer-events-none absolute top-2 right-4', error
65
102
  ? 'text-error dark:text-error-dark'
66
103
  : isMuted
67
104
  ? 'text-gray-2 dark:text-gray-2'
68
105
  : 'text-black dark:text-white')}/>
69
106
  <fieldset className={fieldsetClasses}>
70
- {!hideLabel && <legend className={legendClasses}>{label}</legend>}
107
+ {!hideLabel && (<legend className={legendClasses}>
108
+ {label}
109
+ {labelAddon && (<span aria-hidden="true" className="ml-1 inline-flex">
110
+ {labelAddon}
111
+ </span>)}
112
+ </legend>)}
71
113
  </fieldset>
72
114
  </div>
73
115
  <RenderErrorOrHelperText id={descriptionId} disabled={select?.disabled} helperText={helperText} error={error} className="pl-6"/>
@@ -1 +1 @@
1
- {"version":3,"file":"Select.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Select/Select.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Select.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Select/Select.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type ReactNode } from 'react';
2
+ type SelectListProps = {
3
+ readonly id: string;
4
+ readonly labelId: string;
5
+ readonly options: [string, string][];
6
+ readonly value: string;
7
+ readonly disabled?: boolean;
8
+ readonly invalid?: boolean;
9
+ readonly describedBy?: string;
10
+ readonly onChoose: (value: string) => void;
11
+ };
12
+ /**
13
+ * SelectList draws the option list of a `Select` with `customList`, in place of the
14
+ * native popup the browser and the OS paint. A transparent button covers the field and
15
+ * owns focus and keyboard; the native `<select>` underneath keeps the value.
16
+ *
17
+ * @component
18
+ * @example
19
+ * <SelectList
20
+ * id="hour-list"
21
+ * labelId="hour-label"
22
+ * options={[['08:00', '08:00'], ['08:30', '08:30']]}
23
+ * value="08:00"
24
+ * onChoose={(value) => console.log(value)}
25
+ * />
26
+ *
27
+ * @param {SelectListProps} props - The properties of the SelectList component.
28
+ * @param {string} props.id - Base id for the listbox and its options.
29
+ * @param {string} props.labelId - Id of the visible label, which names the trigger.
30
+ * @param {[string, string][]} props.options - Value and text of each option, in order.
31
+ * @param {string} props.value - Value currently selected.
32
+ * @param {boolean} [props.disabled] - Disables the trigger.
33
+ * @param {boolean} [props.invalid] - Marks the trigger as invalid for assistive technology.
34
+ * @param {string} [props.describedBy] - Id of the helper or error text.
35
+ * @param {(value: string) => void} props.onChoose - Fired with the value the user picks.
36
+ *
37
+ * @returns {ReactNode} The trigger and, while open, the option list.
38
+ */
39
+ export declare function SelectList({ id, labelId, options, value, disabled, invalid, describedBy, onChoose, }: SelectListProps): ReactNode;
40
+ export {};
41
+ //# sourceMappingURL=SelectList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectList.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Select/SelectList.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAGf,KAAK,eAAe,GAAG;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C,CAAC;AAOF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CAAC,EACzB,EAAE,EACF,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,QAAQ,GACT,EAAE,eAAe,GAAG,SAAS,CAgI7B"}
@@ -0,0 +1,116 @@
1
+ 'use client';
2
+ import clsx from 'clsx';
3
+ import { useEffect, useRef, useState, } from 'react';
4
+ import { Each } from '../../00-base';
5
+ const listClasses = clsx('absolute top-full left-0 z-40 mt-1 max-h-[200px] min-w-full overflow-y-auto rounded-sm border py-1 shadow-md', 'border-gray-5 dark:border-gray-1 dark:bg-black-1 bg-white text-black dark:text-white');
6
+ /**
7
+ * SelectList draws the option list of a `Select` with `customList`, in place of the
8
+ * native popup the browser and the OS paint. A transparent button covers the field and
9
+ * owns focus and keyboard; the native `<select>` underneath keeps the value.
10
+ *
11
+ * @component
12
+ * @example
13
+ * <SelectList
14
+ * id="hour-list"
15
+ * labelId="hour-label"
16
+ * options={[['08:00', '08:00'], ['08:30', '08:30']]}
17
+ * value="08:00"
18
+ * onChoose={(value) => console.log(value)}
19
+ * />
20
+ *
21
+ * @param {SelectListProps} props - The properties of the SelectList component.
22
+ * @param {string} props.id - Base id for the listbox and its options.
23
+ * @param {string} props.labelId - Id of the visible label, which names the trigger.
24
+ * @param {[string, string][]} props.options - Value and text of each option, in order.
25
+ * @param {string} props.value - Value currently selected.
26
+ * @param {boolean} [props.disabled] - Disables the trigger.
27
+ * @param {boolean} [props.invalid] - Marks the trigger as invalid for assistive technology.
28
+ * @param {string} [props.describedBy] - Id of the helper or error text.
29
+ * @param {(value: string) => void} props.onChoose - Fired with the value the user picks.
30
+ *
31
+ * @returns {ReactNode} The trigger and, while open, the option list.
32
+ */
33
+ export function SelectList({ id, labelId, options, value, disabled, invalid, describedBy, onChoose, }) {
34
+ const [isOpen, setIsOpen] = useState(false);
35
+ const [activeIndex, setActiveIndex] = useState(-1);
36
+ const rootRef = useRef(null);
37
+ const listRef = useRef(null);
38
+ const listboxId = `${id}-listbox`;
39
+ const selectedIndex = options.findIndex(([optionValue]) => optionValue === value);
40
+ const open = () => {
41
+ setActiveIndex(Math.max(selectedIndex, 0));
42
+ setIsOpen(true);
43
+ };
44
+ const close = () => {
45
+ setIsOpen(false);
46
+ setActiveIndex(-1);
47
+ };
48
+ const choose = (index) => {
49
+ const option = options[index];
50
+ if (option)
51
+ onChoose(option[0]);
52
+ close();
53
+ };
54
+ useEffect(() => {
55
+ if (!isOpen)
56
+ return;
57
+ const handleOutsideClick = (event) => {
58
+ if (rootRef.current && !rootRef.current.contains(event.target)) {
59
+ close();
60
+ }
61
+ };
62
+ document.addEventListener('mousedown', handleOutsideClick);
63
+ return () => document.removeEventListener('mousedown', handleOutsideClick);
64
+ }, [isOpen]);
65
+ useEffect(() => {
66
+ if (!isOpen || activeIndex < 0)
67
+ return;
68
+ listRef.current
69
+ ?.querySelector(`#${CSS.escape(`${listboxId}-${activeIndex}`)}`)
70
+ ?.scrollIntoView({ block: 'nearest' });
71
+ }, [isOpen, activeIndex, listboxId]);
72
+ const handleKeyDown = (event) => {
73
+ const last = options.length - 1;
74
+ if (!isOpen) {
75
+ if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key)) {
76
+ event.preventDefault();
77
+ open();
78
+ }
79
+ return;
80
+ }
81
+ const moves = {
82
+ ArrowDown: Math.min(activeIndex + 1, last),
83
+ ArrowUp: Math.max(activeIndex - 1, 0),
84
+ Home: 0,
85
+ End: last,
86
+ };
87
+ if (event.key in moves) {
88
+ event.preventDefault();
89
+ setActiveIndex(moves[event.key]);
90
+ }
91
+ else if (event.key === 'Enter' || event.key === ' ') {
92
+ event.preventDefault();
93
+ choose(activeIndex);
94
+ }
95
+ else if (event.key === 'Escape') {
96
+ event.preventDefault();
97
+ close();
98
+ }
99
+ else if (event.key === 'Tab') {
100
+ close();
101
+ }
102
+ };
103
+ return (<div ref={rootRef} className="absolute inset-0">
104
+ <button type="button" disabled={disabled} aria-haspopup="listbox" aria-expanded={isOpen} aria-controls={listboxId} aria-labelledby={`${labelId} ${id}-value`} aria-describedby={describedBy} aria-invalid={invalid} aria-activedescendant={isOpen && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : undefined} onClick={() => (isOpen ? close() : open())} onKeyDown={handleKeyDown} className="h-full w-full cursor-pointer rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-black/20 disabled:cursor-not-allowed dark:focus-visible:ring-white/30">
105
+ <span id={`${id}-value`} className="sr-only">
106
+ {selectedIndex >= 0 ? options[selectedIndex][1] : ''}
107
+ </span>
108
+ </button>
109
+ {isOpen && (<ul ref={listRef} id={listboxId} role="listbox" aria-labelledby={labelId} className={listClasses}>
110
+ <Each of={options} render={([optionValue, text], index) => (<li key={optionValue} id={`${listboxId}-${index}`} role="option" aria-selected={index === selectedIndex} onMouseEnter={() => setActiveIndex(index)} onMouseDown={(event) => event.preventDefault()} onClick={() => choose(index)} className={clsx('cursor-pointer px-3 py-2 text-sm whitespace-nowrap', index === activeIndex && 'bg-gray-6 dark:bg-gray-1', index === selectedIndex && 'font-semibold')}>
111
+ {text}
112
+ </li>)}/>
113
+ </ul>)}
114
+ </div>);
115
+ }
116
+ //# sourceMappingURL=SelectList.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectList.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Select/SelectList.tsx"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ type SwitchProps = {
5
5
  onChange?: (checked: boolean) => void;
6
6
  onClick?: (rollback: () => void, commit: () => void) => void;
7
7
  label?: string;
8
+ /** Accessible name when there is no visible `label` (e.g. a switch inside a table row). */
9
+ ariaLabel?: string;
8
10
  };
9
11
  /**
10
12
  * Switch component for rendering a toggle switch with optional label.
@@ -29,11 +31,12 @@ type SwitchProps = {
29
31
  * @param {boolean} isChecked - Initial checked state of the switch.
30
32
  * @param {boolean} [isDisabled=false] - Optional boolean to disable the switch.
31
33
  * @param {string} [label] - Optional label to be displayed next to the switch.
34
+ * @param {string} [ariaLabel] - Accessible name for the control when no visible `label` is rendered.
32
35
  * @param {function} [onChange] - Optional callback function to handle change in checked state.
33
- * @param {function} [onClick] - Optional callback function to handle click events with rollback and commit actions.
36
+ * @param {function} [onClick] - Optional callback function to handle click events with rollback and commit actions. Invoked exactly once per click.
34
37
  *
35
38
  * @returns {ReactNode} The rendered Switch component.
36
39
  */
37
- export declare function Switch({ isChecked, isDisabled, label, onChange, onClick, }: SwitchProps): ReactNode;
40
+ export declare function Switch({ isChecked, isDisabled, label, ariaLabel, onChange, onClick, }: SwitchProps): ReactNode;
38
41
  export {};
39
42
  //# sourceMappingURL=Switch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Switch/Switch.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAGf,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,UAAkB,EAClB,KAAK,EACL,QAAQ,EACR,OAAO,GACR,EAAE,WAAW,GAAG,SAAS,CAsEzB"}
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Switch/Switch.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAGf,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,UAAkB,EAClB,KAAK,EACL,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,WAAW,GAAG,SAAS,CAyEzB"}
@@ -25,12 +25,13 @@ import { Paragraph } from '../Paragraph';
25
25
  * @param {boolean} isChecked - Initial checked state of the switch.
26
26
  * @param {boolean} [isDisabled=false] - Optional boolean to disable the switch.
27
27
  * @param {string} [label] - Optional label to be displayed next to the switch.
28
+ * @param {string} [ariaLabel] - Accessible name for the control when no visible `label` is rendered.
28
29
  * @param {function} [onChange] - Optional callback function to handle change in checked state.
29
- * @param {function} [onClick] - Optional callback function to handle click events with rollback and commit actions.
30
+ * @param {function} [onClick] - Optional callback function to handle click events with rollback and commit actions. Invoked exactly once per click.
30
31
  *
31
32
  * @returns {ReactNode} The rendered Switch component.
32
33
  */
33
- export function Switch({ isChecked, isDisabled = false, label, onChange, onClick, }) {
34
+ export function Switch({ isChecked, isDisabled = false, label, ariaLabel, onChange, onClick, }) {
34
35
  const [checked, setChecked] = useState(isChecked);
35
36
  const [disable, setDisable] = useState(isDisabled);
36
37
  const handleChange = (event) => {
@@ -40,15 +41,17 @@ export function Switch({ isChecked, isDisabled = false, label, onChange, onClick
40
41
  if (!onClick) {
41
42
  return setChecked((prevState) => !prevState);
42
43
  }
43
- setChecked((prevState) => {
44
- setDisable(true);
45
- onClick(() => {
46
- setChecked(prevState);
47
- setDisable(false);
48
- }, () => {
49
- setDisable(false);
50
- });
51
- return !prevState;
44
+ // `onClick` runs outside the state updater on purpose: React may invoke an
45
+ // updater more than once (Strict Mode, batching), which would fire the
46
+ // consumer's side effect several times per click.
47
+ const previous = checked;
48
+ setChecked(!previous);
49
+ setDisable(true);
50
+ onClick(() => {
51
+ setChecked(previous);
52
+ setDisable(false);
53
+ }, () => {
54
+ setDisable(false);
52
55
  });
53
56
  };
54
57
  useEffect(() => {
@@ -58,7 +61,7 @@ export function Switch({ isChecked, isDisabled = false, label, onChange, onClick
58
61
  setDisable(isDisabled);
59
62
  }, [isDisabled]);
60
63
  return (<label className={clsx('inline-flex items-center', disable ? 'select-none' : 'cursor-pointer')}>
61
- <input type="checkbox" role="switch" aria-checked={checked} className="peer sr-only" checked={checked} onChange={handleChange} onClick={handleClick} disabled={disable}/>
64
+ <input type="checkbox" role="switch" aria-checked={checked} aria-label={label ? undefined : ariaLabel} className="peer sr-only" checked={checked} onChange={handleChange} onClick={handleClick} disabled={disable}/>
62
65
  <div aria-hidden="true" className="bg-gray-3 after:border-gray-3 dark:bg-gray-1 dark:after:border-gray-2 relative h-5 w-12 rounded-full peer-checked:bg-black peer-focus-visible:ring-2 peer-focus-visible:ring-black/20 peer-disabled:opacity-80 after:absolute after:-top-0.5 after:size-6 after:rounded-full after:border after:bg-white after:shadow-sm after:shadow-[rgba(0,0,0,.5)] after:transition-all peer-checked:after:translate-x-full dark:peer-checked:bg-white dark:peer-focus-visible:ring-white/30 dark:after:bg-white dark:peer-checked:after:bg-black"/>
63
66
  <Paragraph size="subtitle-1" className={clsx('ms-2', disable
64
67
  ? 'text-gray-3 dark:text-gray-2'
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Switch/Switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAGL,SAAS,EACT,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAUzC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,MAAM,CAAC,EACrB,SAAS,EACT,UAAU,GAAG,KAAK,EAClB,KAAK,EACL,QAAQ,EACR,OAAO,GACK;IACZ,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,SAAS,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,UAAU,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAyC,CAAC,KAAK,EAAE,EAAE;QACnE,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,UAAU,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED,UAAU,CAAC,CAAC,SAAS,EAAE,EAAE;YACvB,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO,CACL,GAAG,EAAE;gBACH,UAAU,CAAC,SAAS,CAAC,CAAC;gBACtB,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC,EACD,GAAG,EAAE;gBACH,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC,CACF,CAAC;YACF,OAAO,CAAC,SAAS,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL,CAAC,KAAK,CACJ,SAAS,CAAC,CAAC,IAAI,CACb,0BAA0B,EAC1B,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAC3C,CAAC,CAEF;MAAA,CAAC,KAAK,CACJ,IAAI,CAAC,UAAU,CACf,IAAI,CAAC,QAAQ,CACb,YAAY,CAAC,CAAC,OAAO,CAAC,CACtB,SAAS,CAAC,cAAc,CACxB,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,OAAO,CAAC,CAAC,WAAW,CAAC,CACrB,QAAQ,CAAC,CAAC,OAAO,CAAC,EAEpB;MAAA,CAAC,GAAG,CACF,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,ugBAAugB,EAEnhB;MAAA,CAAC,SAAS,CACR,IAAI,CAAC,YAAY,CACjB,SAAS,CAAC,CAAC,IAAI,CACb,MAAM,EACN,OAAO;YACL,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,4BAA4B,CACjC,CAAC,CAEF;QAAA,CAAC,KAAK,CACR;MAAA,EAAE,SAAS,CACb;IAAA,EAAE,KAAK,CAAC,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Switch.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Switch/Switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAGL,SAAS,EACT,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAYzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,MAAM,CAAC,EACrB,SAAS,EACT,UAAU,GAAG,KAAK,EAClB,KAAK,EACL,SAAS,EACT,QAAQ,EACR,OAAO,GACK;IACZ,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,SAAS,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,UAAU,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAyC,CAAC,KAAK,EAAE,EAAE;QACnE,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,UAAU,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED,2EAA2E;QAC3E,uEAAuE;QACvE,kDAAkD;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC;QACzB,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,CACL,GAAG,EAAE;YACH,UAAU,CAAC,QAAQ,CAAC,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC,EACD,GAAG,EAAE;YACH,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL,CAAC,KAAK,CACJ,SAAS,CAAC,CAAC,IAAI,CACb,0BAA0B,EAC1B,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAC3C,CAAC,CAEF;MAAA,CAAC,KAAK,CACJ,IAAI,CAAC,UAAU,CACf,IAAI,CAAC,QAAQ,CACb,YAAY,CAAC,CAAC,OAAO,CAAC,CACtB,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAC1C,SAAS,CAAC,cAAc,CACxB,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,OAAO,CAAC,CAAC,WAAW,CAAC,CACrB,QAAQ,CAAC,CAAC,OAAO,CAAC,EAEpB;MAAA,CAAC,GAAG,CACF,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,ugBAAugB,EAEnhB;MAAA,CAAC,SAAS,CACR,IAAI,CAAC,YAAY,CACjB,SAAS,CAAC,CAAC,IAAI,CACb,MAAM,EACN,OAAO;YACL,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,4BAA4B,CACjC,CAAC,CAEF;QAAA,CAAC,KAAK,CACR;MAAA,EAAE,SAAS,CACb;IAAA,EAAE,KAAK,CAAC,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { type DetailedHTMLProps, type ReactNode, type TextareaHTMLAttributes } from 'react';
2
+ type TextareaProps = {
3
+ label: string;
4
+ textarea: Omit<DetailedHTMLProps<TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, 'placeholder'>;
5
+ helperText?: string;
6
+ error?: string;
7
+ placeholder?: string;
8
+ hideLabel?: boolean;
9
+ };
10
+ /**
11
+ * Textarea component for multi-line text, matching Input's border, color, disabled and error
12
+ * states. It uses a static label above the field instead of Input's floating notch: a floating
13
+ * label has no natural resting place once the field grows past one line.
14
+ *
15
+ * @component
16
+ * @example
17
+ * // Example usage of Textarea component
18
+ * <Textarea
19
+ * label="Observaciones"
20
+ * textarea={{ value: 'Texto', rows: 3, onChange: () => console.log('Textarea changed') }}
21
+ * placeholder="Notas operativas"
22
+ * helperText="Opcional"
23
+ * error="Campo requerido"
24
+ * />
25
+ *
26
+ * @param {Object} props - The properties of the Textarea component.
27
+ * @param {string} props.label - The label text shown above the field.
28
+ * @param {Object} props.textarea - Native textarea attributes (value, rows, onChange, disabled, ...).
29
+ * @param {string} [props.helperText] - Optional helper text to be displayed below the field.
30
+ * @param {string} [props.error] - Optional error message to be displayed below the field.
31
+ * @param {string} [props.placeholder] - Placeholder shown inside the field.
32
+ * @param {boolean} [props.hideLabel] - Keeps the label for assistive technology only.
33
+ *
34
+ * @returns {ReactNode} The rendered Textarea component.
35
+ */
36
+ export declare function Textarea({ label, textarea, helperText, error, placeholder, hideLabel, }: TextareaProps): ReactNode;
37
+ export {};
38
+ //# sourceMappingURL=Textarea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Textarea/Textarea.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,sBAAsB,EAE5B,MAAM,OAAO,CAAC;AAGf,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,IAAI,CACZ,iBAAiB,CACf,sBAAsB,CAAC,mBAAmB,CAAC,EAC3C,mBAAmB,CACpB,EACD,aAAa,CACd,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,SAAiB,GAClB,EAAE,aAAa,GAAG,SAAS,CA+C3B"}
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import clsx from 'clsx';
3
+ import { useId, } from 'react';
4
+ import { RenderErrorOrHelperText } from '../Input/utils/RenderErrorOrHelperText';
5
+ /**
6
+ * Textarea component for multi-line text, matching Input's border, color, disabled and error
7
+ * states. It uses a static label above the field instead of Input's floating notch: a floating
8
+ * label has no natural resting place once the field grows past one line.
9
+ *
10
+ * @component
11
+ * @example
12
+ * // Example usage of Textarea component
13
+ * <Textarea
14
+ * label="Observaciones"
15
+ * textarea={{ value: 'Texto', rows: 3, onChange: () => console.log('Textarea changed') }}
16
+ * placeholder="Notas operativas"
17
+ * helperText="Opcional"
18
+ * error="Campo requerido"
19
+ * />
20
+ *
21
+ * @param {Object} props - The properties of the Textarea component.
22
+ * @param {string} props.label - The label text shown above the field.
23
+ * @param {Object} props.textarea - Native textarea attributes (value, rows, onChange, disabled, ...).
24
+ * @param {string} [props.helperText] - Optional helper text to be displayed below the field.
25
+ * @param {string} [props.error] - Optional error message to be displayed below the field.
26
+ * @param {string} [props.placeholder] - Placeholder shown inside the field.
27
+ * @param {boolean} [props.hideLabel] - Keeps the label for assistive technology only.
28
+ *
29
+ * @returns {ReactNode} The rendered Textarea component.
30
+ */
31
+ export function Textarea({ label, textarea, helperText, error, placeholder, hideLabel = false, }) {
32
+ const generatedId = useId();
33
+ const id = textarea.id ?? generatedId;
34
+ const descriptionId = error || helperText ? `${id}-description` : undefined;
35
+ const describedBy = [textarea['aria-describedby'], descriptionId].filter(Boolean).join(' ') ||
36
+ undefined;
37
+ const textareaClasses = clsx('w-full resize-y rounded-lg border bg-transparent p-3.5 text-sm text-black transition-colors outline-none placeholder:text-gray-2 dark:text-white dark:placeholder:text-gray-2', 'disabled:border-gray-3 disabled:text-gray-3 dark:disabled:border-gray-2 dark:disabled:text-gray-2 disabled:cursor-not-allowed', error
38
+ ? 'border-error focus:border-error focus:ring-error dark:border-error-dark dark:focus:border-error-dark dark:focus:ring-error-dark focus:ring-2'
39
+ : 'border-black hover:border-gray-1 focus:border-lavender focus:ring-lavender dark:border-white dark:hover:border-gray-2 focus:ring-2', textarea.className);
40
+ return (<div className="w-full max-w-full">
41
+ {hideLabel ? (<label htmlFor={id} className="sr-only">
42
+ {label}
43
+ </label>) : (<label htmlFor={id} className="text-gray-1 mb-1.5 ml-0.5 block text-xs font-semibold">
44
+ {label}
45
+ </label>)}
46
+ <textarea {...textarea} id={id} className={textareaClasses} placeholder={placeholder} aria-invalid={error ? true : textarea['aria-invalid']} aria-describedby={describedBy}/>
47
+ <RenderErrorOrHelperText id={descriptionId} disabled={textarea.disabled} helperText={helperText} error={error}/>
48
+ </div>);
49
+ }
50
+ //# sourceMappingURL=Textarea.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Textarea/Textarea.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAIL,KAAK,GACN,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAiBjF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,SAAS,GAAG,KAAK,GACH;IACd,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,IAAI,WAAW,CAAC;IACtC,MAAM,aAAa,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,WAAW,GACf,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACvE,SAAS,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAI,CAC1B,+KAA+K,EAC/K,+HAA+H,EAC/H,KAAK;QACH,CAAC,CAAC,8IAA8I;QAChJ,CAAC,CAAC,oIAAoI,EACxI,QAAQ,CAAC,SAAS,CACnB,CAAC;IAEF,OAAO,CACL,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAChC;MAAA,CAAC,SAAS,CAAC,CAAC,CAAC,CACX,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CACrC;UAAA,CAAC,KAAK,CACR;QAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,CACF,CAAC,KAAK,CACJ,OAAO,CAAC,CAAC,EAAE,CAAC,CACZ,SAAS,CAAC,uDAAuD,CAEjE;UAAA,CAAC,KAAK,CACR;QAAA,EAAE,KAAK,CAAC,CACT,CACD;MAAA,CAAC,QAAQ,CACP,IAAI,QAAQ,CAAC,CACb,EAAE,CAAC,CAAC,EAAE,CAAC,CACP,SAAS,CAAC,CAAC,eAAe,CAAC,CAC3B,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CACtD,gBAAgB,CAAC,CAAC,WAAW,CAAC,EAEhC;MAAA,CAAC,uBAAuB,CACtB,EAAE,CAAC,CAAC,aAAa,CAAC,CAClB,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC5B,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,KAAK,CAAC,CAAC,KAAK,CAAC,EAEjB;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Textarea } from './Textarea';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Textarea/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Textarea } from './Textarea';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/01-atoms/Textarea/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Toast/Toast.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,KAAK,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AA+B5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAY9D"}
1
+ {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Toast/Toast.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,KAAK,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AA+B5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAgB9D"}
@@ -27,7 +27,9 @@ const backgroundClasses = {
27
27
  * @returns {void}
28
28
  */
29
29
  export function showToast(content, type) {
30
- toastFn(<Paragraph className="text-black dark:text-white">{content}</Paragraph>, {
30
+ // A render function instead of an element: react-toastify clones a plain element
31
+ // with `closeToast`/`toastProps`, which `Paragraph` would forward to the DOM `<p>`.
32
+ toastFn(() => (<Paragraph className="text-black dark:text-white">{content}</Paragraph>), {
31
33
  position: 'top-right',
32
34
  hideProgressBar: true,
33
35
  pauseOnFocusLoss: false,
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,MAAM,WAAW,GAAG,IAAI,CAAC,sCAAsC,CAAC,CAAC;AAEjE,MAAM,KAAK,GAA4B;IACrC,OAAO,EAAE,CACP,CAAC,OAAO,CACN,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC,EAChE,CACH;IACD,OAAO,EAAE,CACP,CAAC,SAAS,CACR,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC,EAChE,CACH;IACD,KAAK,EAAE,CACL,CAAC,OAAO,CACN,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,6BAA6B,CAAC,CAAC,EAC5D,CACH;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAyB;IAC9C,OAAO,EAAE,qCAAqC;IAC9C,OAAO,EAAE,qCAAqC;IAC9C,KAAK,EAAE,iCAAiC;CACzC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,OAAkB,EAAE,IAAU;IACtD,OAAO,CACL,CAAC,SAAS,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,EACvE;QACE,QAAQ,EAAE,WAAW;QACrB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,KAAK;QACvB,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QACvB,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC;KACnC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Toast.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,MAAM,WAAW,GAAG,IAAI,CAAC,sCAAsC,CAAC,CAAC;AAEjE,MAAM,KAAK,GAA4B;IACrC,OAAO,EAAE,CACP,CAAC,OAAO,CACN,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC,EAChE,CACH;IACD,OAAO,EAAE,CACP,CAAC,SAAS,CACR,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC,EAChE,CACH;IACD,KAAK,EAAE,CACL,CAAC,OAAO,CACN,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,6BAA6B,CAAC,CAAC,EAC5D,CACH;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAyB;IAC9C,OAAO,EAAE,qCAAqC;IAC9C,OAAO,EAAE,qCAAqC;IAC9C,KAAK,EAAE,iCAAiC;CACzC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,OAAkB,EAAE,IAAU;IACtD,iFAAiF;IACjF,oFAAoF;IACpF,OAAO,CACL,GAAG,EAAE,CAAC,CACJ,CAAC,SAAS,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,CACxE,EACD;QACE,QAAQ,EAAE,WAAW;QACrB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,KAAK;QACvB,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QACvB,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC;KACnC,CACF,CAAC;AACJ,CAAC"}
@@ -2,8 +2,10 @@ export * from './List';
2
2
  export * from './Logo';
3
3
  export * from './Badge';
4
4
  export * from './Input';
5
+ export * from './Textarea';
5
6
  export * from './Radio';
6
7
  export * from './Button';
8
+ export * from './IconButton';
7
9
  export * from './Select';
8
10
  export * from './Heading';
9
11
  export * from './Checkbox';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
@@ -2,8 +2,10 @@ export * from './List';
2
2
  export * from './Logo';
3
3
  export * from './Badge';
4
4
  export * from './Input';
5
+ export * from './Textarea';
5
6
  export * from './Radio';
6
7
  export * from './Button';
8
+ export * from './IconButton';
7
9
  export * from './Select';
8
10
  export * from './Heading';
9
11
  export * from './Checkbox';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}