uibee 2.6.0 → 2.7.1
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/src/components/buttons/button.js +1 -1
- package/dist/src/components/index.d.ts +5 -3
- package/dist/src/components/index.js +5 -3
- package/dist/src/components/inputs/checkbox.d.ts +13 -0
- package/dist/src/components/inputs/checkbox.js +17 -0
- package/dist/src/components/inputs/input.d.ts +11 -9
- package/dist/src/components/inputs/input.js +76 -9
- package/dist/src/components/inputs/radio.d.ts +14 -0
- package/dist/src/components/inputs/radio.js +17 -0
- package/dist/src/components/inputs/range.d.ts +17 -0
- package/dist/src/components/inputs/range.js +20 -0
- package/dist/src/components/inputs/select.d.ts +11 -11
- package/dist/src/components/inputs/select.js +54 -50
- package/dist/src/components/inputs/shared/dateTimePickerPopup.d.ts +8 -0
- package/dist/src/components/inputs/shared/dateTimePickerPopup.js +117 -0
- package/dist/src/components/inputs/shared/fieldWrapper.d.ts +12 -0
- package/dist/src/components/inputs/shared/fieldWrapper.js +7 -0
- package/dist/src/components/inputs/shared/index.d.ts +5 -0
- package/dist/src/components/inputs/shared/index.js +5 -0
- package/dist/src/components/inputs/shared/inputError.d.ts +6 -0
- package/dist/src/components/inputs/shared/inputError.js +6 -0
- package/dist/src/components/inputs/shared/inputInfo.d.ts +5 -0
- package/dist/src/components/inputs/shared/inputInfo.js +5 -0
- package/dist/src/components/inputs/shared/inputLabel.d.ts +9 -0
- package/dist/src/components/inputs/shared/inputLabel.js +4 -0
- package/dist/src/components/inputs/shared/selectionWrapper.d.ts +13 -0
- package/dist/src/components/inputs/shared/selectionWrapper.js +7 -0
- package/dist/src/components/inputs/switch.d.ts +10 -7
- package/dist/src/components/inputs/switch.js +13 -5
- package/dist/src/components/inputs/textarea.d.ts +15 -0
- package/dist/src/components/inputs/textarea.js +14 -0
- package/dist/src/components/logo/logo.js +1 -1
- package/dist/src/globals.css +386 -161
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/index.js +1 -0
- package/dist/src/hooks/useClickOutside.d.ts +1 -0
- package/dist/src/hooks/useClickOutside.js +20 -0
- package/eslint.config.js +1 -0
- package/package.json +3 -2
- package/src/components/buttons/button.tsx +1 -1
- package/src/components/index.ts +5 -3
- package/src/components/inputs/checkbox.tsx +66 -0
- package/src/components/inputs/input.tsx +137 -35
- package/src/components/inputs/radio.tsx +67 -0
- package/src/components/inputs/range.tsx +84 -0
- package/src/components/inputs/select.tsx +137 -172
- package/src/components/inputs/shared/dateTimePickerPopup.tsx +219 -0
- package/src/components/inputs/shared/fieldWrapper.tsx +44 -0
- package/src/components/inputs/shared/index.ts +5 -0
- package/src/components/inputs/shared/inputError.tsx +21 -0
- package/src/components/inputs/shared/inputInfo.tsx +17 -0
- package/src/components/inputs/shared/inputLabel.tsx +19 -0
- package/src/components/inputs/shared/selectionWrapper.tsx +47 -0
- package/src/components/inputs/switch.tsx +48 -25
- package/src/components/inputs/textarea.tsx +65 -0
- package/src/components/logo/logo.tsx +1 -1
- package/src/globals.css +36 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useClickOutside.ts +27 -0
- package/dist/src/components/inputs/erase.d.ts +0 -3
- package/dist/src/components/inputs/erase.js +0 -5
- package/dist/src/components/inputs/label.d.ts +0 -10
- package/dist/src/components/inputs/label.js +0 -13
- package/dist/src/components/inputs/markdown.d.ts +0 -15
- package/dist/src/components/inputs/markdown.js +0 -32
- package/dist/src/components/inputs/tag.d.ts +0 -11
- package/dist/src/components/inputs/tag.js +0 -44
- package/dist/src/components/inputs/tooltip.d.ts +0 -4
- package/dist/src/components/inputs/tooltip.js +0 -4
- package/src/components/inputs/erase.tsx +0 -13
- package/src/components/inputs/label.tsx +0 -31
- package/src/components/inputs/markdown.tsx +0 -129
- package/src/components/inputs/tag.tsx +0 -137
- package/src/components/inputs/tooltip.tsx +0 -12
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
import InputLabel from './inputLabel'
|
|
3
|
+
import InputInfo from './inputInfo'
|
|
4
|
+
import InputError from './inputError'
|
|
5
|
+
|
|
6
|
+
interface SelectionWrapperProps {
|
|
7
|
+
label?: string
|
|
8
|
+
name: string
|
|
9
|
+
required?: boolean
|
|
10
|
+
info?: string
|
|
11
|
+
error?: string
|
|
12
|
+
children: ReactNode
|
|
13
|
+
className?: string
|
|
14
|
+
disabled?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function SelectionWrapper({
|
|
18
|
+
label,
|
|
19
|
+
name,
|
|
20
|
+
required,
|
|
21
|
+
info,
|
|
22
|
+
error,
|
|
23
|
+
children,
|
|
24
|
+
className,
|
|
25
|
+
disabled,
|
|
26
|
+
}: SelectionWrapperProps) {
|
|
27
|
+
return (
|
|
28
|
+
<div className={`flex flex-col gap-1 ${className || ''}`}>
|
|
29
|
+
<div className='flex items-center justify-between mb-1'>
|
|
30
|
+
<div className='flex items-center gap-2'>
|
|
31
|
+
{children}
|
|
32
|
+
{label && (
|
|
33
|
+
<InputLabel
|
|
34
|
+
label={label}
|
|
35
|
+
name={name}
|
|
36
|
+
required={required}
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
className='select-none cursor-pointer'
|
|
39
|
+
/>
|
|
40
|
+
)}
|
|
41
|
+
</div>
|
|
42
|
+
{info && <InputInfo info={info} />}
|
|
43
|
+
</div>
|
|
44
|
+
<InputError error={error} />
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -1,39 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ChangeEvent } from 'react'
|
|
2
|
+
import { SelectionWrapper } from './shared'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type SwitchProps = {
|
|
4
|
+
export type SwitchProps = {
|
|
5
|
+
label?: string
|
|
6
6
|
name: string
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
setValue: (_: boolean) => void
|
|
7
|
+
checked?: boolean
|
|
8
|
+
onChange?: (e: ChangeEvent<HTMLInputElement>) => void
|
|
10
9
|
className?: string
|
|
11
|
-
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
error?: string
|
|
12
|
+
info?: string
|
|
13
|
+
required?: boolean
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
export default function Switch({
|
|
16
|
+
export default function Switch({
|
|
17
|
+
label,
|
|
18
|
+
name,
|
|
19
|
+
checked,
|
|
20
|
+
onChange,
|
|
21
|
+
className,
|
|
22
|
+
disabled,
|
|
23
|
+
error,
|
|
24
|
+
info,
|
|
25
|
+
required,
|
|
26
|
+
}: SwitchProps) {
|
|
15
27
|
return (
|
|
16
|
-
<
|
|
17
|
-
|
|
28
|
+
<SelectionWrapper
|
|
29
|
+
label={label}
|
|
30
|
+
name={name}
|
|
31
|
+
required={required}
|
|
32
|
+
info={info}
|
|
33
|
+
error={error}
|
|
34
|
+
className={className}
|
|
35
|
+
disabled={disabled}
|
|
18
36
|
>
|
|
19
|
-
<label className='flex items-center cursor-pointer'>
|
|
37
|
+
<label className='relative inline-flex items-center cursor-pointer'>
|
|
20
38
|
<input
|
|
21
39
|
type='checkbox'
|
|
40
|
+
id={name}
|
|
22
41
|
name={name}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
42
|
+
checked={checked}
|
|
43
|
+
onChange={onChange}
|
|
44
|
+
disabled={disabled}
|
|
45
|
+
required={required}
|
|
46
|
+
className='sr-only peer'
|
|
26
47
|
/>
|
|
27
|
-
<div className={`
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
<div className={`
|
|
49
|
+
w-11 h-6 bg-login-500/50 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-login/50
|
|
50
|
+
rounded-full peer
|
|
51
|
+
peer-checked:after:translate-x-full peer-checked:after:border-white
|
|
52
|
+
after:content-[''] after:absolute after:top-0.5 after:left-0.5
|
|
53
|
+
after:bg-white after:border-gray-300 after:border after:rounded-full
|
|
54
|
+
after:h-5 after:w-5 after:transition-all
|
|
55
|
+
peer-checked:bg-login
|
|
56
|
+
${disabled ? 'opacity-50 cursor-not-allowed' : ''}
|
|
57
|
+
${error ? 'ring-1 ring-red-500' : ''}
|
|
58
|
+
`}></div>
|
|
32
59
|
</label>
|
|
33
|
-
|
|
34
|
-
{label}
|
|
35
|
-
</span>
|
|
36
|
-
{tooltip && <ToolTip info={tooltip} />}
|
|
37
|
-
</div>
|
|
60
|
+
</SelectionWrapper>
|
|
38
61
|
)
|
|
39
62
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type ChangeEvent } from 'react'
|
|
2
|
+
import { FieldWrapper } from './shared'
|
|
3
|
+
|
|
4
|
+
export type TextareaProps = {
|
|
5
|
+
label?: string
|
|
6
|
+
name: string
|
|
7
|
+
placeholder?: string
|
|
8
|
+
value?: string
|
|
9
|
+
onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void
|
|
10
|
+
error?: string
|
|
11
|
+
className?: string
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
required?: boolean
|
|
14
|
+
rows?: number
|
|
15
|
+
info?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function Textarea({
|
|
19
|
+
label,
|
|
20
|
+
name,
|
|
21
|
+
placeholder,
|
|
22
|
+
value,
|
|
23
|
+
onChange,
|
|
24
|
+
error,
|
|
25
|
+
className,
|
|
26
|
+
disabled,
|
|
27
|
+
required,
|
|
28
|
+
rows = 4,
|
|
29
|
+
info,
|
|
30
|
+
}: TextareaProps) {
|
|
31
|
+
return (
|
|
32
|
+
<FieldWrapper
|
|
33
|
+
label={label}
|
|
34
|
+
name={name}
|
|
35
|
+
required={required}
|
|
36
|
+
info={info}
|
|
37
|
+
error={error}
|
|
38
|
+
className={className}
|
|
39
|
+
>
|
|
40
|
+
<textarea
|
|
41
|
+
id={name}
|
|
42
|
+
name={name}
|
|
43
|
+
placeholder={placeholder}
|
|
44
|
+
value={value}
|
|
45
|
+
onChange={onChange}
|
|
46
|
+
disabled={disabled}
|
|
47
|
+
required={required}
|
|
48
|
+
rows={rows}
|
|
49
|
+
title={label}
|
|
50
|
+
aria-invalid={!!error}
|
|
51
|
+
aria-describedby={error ? `${name}-error` : undefined}
|
|
52
|
+
className={`
|
|
53
|
+
w-full rounded-md bg-login-500/50 border border-login-500
|
|
54
|
+
text-login-text placeholder-login-200
|
|
55
|
+
focus:outline-none focus:border-login focus:ring-1 focus:ring-login
|
|
56
|
+
disabled:opacity-50 disabled:cursor-not-allowed
|
|
57
|
+
p-3
|
|
58
|
+
transition-all duration-200
|
|
59
|
+
resize-y
|
|
60
|
+
${error ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
|
61
|
+
`}
|
|
62
|
+
/>
|
|
63
|
+
</FieldWrapper>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -35,7 +35,7 @@ export default function Logo({ className }: LogoProps) {
|
|
|
35
35
|
<polyline className={letter} style={{strokeMiterlimit: 10}} points='161.983 98.122 176.665 98.122 176.665 83.44' transform='translate(-31.392,-41.894)' />
|
|
36
36
|
<polyline className={letter} style={{strokeMiterlimit: 10}} points='176.665 58.372 176.665 43.69 161.983 43.69' transform='translate(-31.392,-41.894)' />
|
|
37
37
|
<path className={corner} d='m 30.02449,40.19351 v 4.12842 H 12.4991 V 13.99038 h 4.92871 v 26.20313 z' />
|
|
38
|
-
<path className=
|
|
38
|
+
<path className='fill-login transition-all duration-1000' d='m 61.53523,29.1564 a 17.15942,17.15942 0 0 1 -1.09473,6.21338 14.35971,14.35971 0 0 1 -3.08593,4.89746 14.091,14.091 0 0 1 -4.78125,3.21191 17.1289,17.1289 0 0 1 -12.38575,0 13.98317,13.98317 0 0 1 -7.88867,-8.10937 18.18161,18.18161 0 0 1 0,-12.42725 14.39119,14.39119 0 0 1 3.09668,-4.90771 14.13157,14.13157 0 0 1 4.792,-3.22315 17.13565,17.13565 0 0 1 12.38575,0 14.02046,14.02046 0 0 1 4.78125,3.22315 14.47032,14.47032 0 0 1 3.08593,4.90771 17.16209,17.16209 0 0 1 1.09472,6.21387 z m -5.03418,0 a 14.62587,14.62587 0 0 0 -0.70508,-4.69727 9.9446,9.9446 0 0 0 -2.02246,-3.53906 8.80545,8.80545 0 0 0 -3.1914,-2.23242 11.719,11.719 0 0 0 -8.4043,0 8.90077,8.90077 0 0 0 -3.20117,2.23242 9.96735,9.96735 0 0 0 -2.043,3.53906 15.81644,15.81644 0 0 0 0,9.415 9.847,9.847 0 0 0 2.043,3.52832 8.85094,8.85094 0 0 0 3.20117,2.21192 11.87213,11.87213 0 0 0 8.4043,0 8.75623,8.75623 0 0 0 3.1914,-2.21192 9.82454,9.82454 0 0 0 2.02249,-3.52828 14.69371,14.69371 0 0 0 0.70505,-4.71777 z' />
|
|
39
39
|
<path className={corner} d='m 91.76082,29.38784 v 12.00635 a 17.5354,17.5354 0 0 1 -10.53125,3.26465 18.41512,18.41512 0 0 1 -6.667,-1.148 14.80254,14.80254 0 0 1 -5.08691,-3.20166 14.0148,14.0148 0 0 1 -3.24316,-4.897 16.691,16.691 0 0 1 -1.1377,-6.25586 17.42935,17.42935 0 0 1 1.09473,-6.2876 13.74023,13.74023 0 0 1 8.06738,-8.08838 17.7222,17.7222 0 0 1 6.48828,-1.127 19.10354,19.10354 0 0 1 3.40137,0.28418 16.85244,16.85244 0 0 1 2.917,0.79 13.68442,13.68442 0 0 1 2.48633,1.22168 13.95372,13.95372 0 0 1 2.085,1.60058 l -1.41113,2.25391 a 1.40229,1.40229 0 0 1 -0.86426,0.65283 1.47784,1.47784 0 0 1 -1.13672,-0.25244 q -0.6123,-0.35816 -1.2959,-0.7583 a 11.33129,11.33129 0 0 0 -1.56933,-0.748 11.53387,11.53387 0 0 0 -2.043,-0.56836 14.78335,14.78335 0 0 0 -2.73828,-0.22119 11.32128,11.32128 0 0 0 -4.32813,0.78955 9.26752,9.26752 0 0 0 -3.29687,2.25391 9.99164,9.99164 0 0 0 -2.10645,3.54931 13.90267,13.90267 0 0 0 -0.7373,4.65528 14.11731,14.11731 0 0 0 0.77929,4.855 10.1425,10.1425 0 0 0 2.21192,3.62305 9.43419,9.43419 0 0 0 3.46484,2.26416 13.81975,13.81975 0 0 0 7.87793,0.3789 15.14816,15.14816 0 0 0 2.875,-1.11621 v -6.02383 h -4.2334 a 1.04883,1.04883 0 0 1 -0.75879,-0.26367 0.90553,0.90553 0 0 1 -0.27343,-0.68457 v -2.80127 z' />
|
|
40
40
|
<path className={corner} d='M 102.546,44.32193 H 97.59581 V 13.99038 h 4.95019 z' />
|
|
41
41
|
<path className={corner} d='m 134.8575,13.99038 v 30.33155 h -2.50684 a 2.14219,2.14219 0 0 1 -0.96875,-0.2002 2.26108,2.26108 0 0 1 -0.75879,-0.66357 L 113.962,22.05777 q 0.063,0.61083 0.0947,1.21093 0.0322,0.60058 0.0322,1.106 v 19.94723 h -4.3398 V 13.99038 h 2.57031 a 3.89092,3.89092 0 0 1 0.53711,0.03174 1.53328,1.53328 0 0 1 0.41016,0.11572 1.18964,1.18964 0 0 1 0.35839,0.25293 4.01792,4.01792 0 0 1 0.3584,0.4209 l 16.68164,21.42188 q -0.063,-0.65259 -0.0947,-1.28467 -0.0308,-0.63208 -0.0312,-1.17969 V 13.99038 Z' />
|
package/src/globals.css
CHANGED
|
@@ -184,3 +184,39 @@
|
|
|
184
184
|
font-size: 1.2rem;
|
|
185
185
|
font-weight: 500;
|
|
186
186
|
}
|
|
187
|
+
|
|
188
|
+
/* Hide default browser icons/buttons for inputs */
|
|
189
|
+
input::-webkit-calendar-picker-indicator {
|
|
190
|
+
display: none !important;
|
|
191
|
+
-webkit-appearance: none !important;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
input::-webkit-outer-spin-button,
|
|
195
|
+
input::-webkit-inner-spin-button {
|
|
196
|
+
-webkit-appearance: none !important;
|
|
197
|
+
margin: 0 !important;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
input[type='number'] {
|
|
201
|
+
-moz-appearance: textfield !important;
|
|
202
|
+
appearance: textfield !important;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
input::-webkit-search-decoration,
|
|
206
|
+
input::-webkit-search-cancel-button,
|
|
207
|
+
input::-webkit-search-results-button,
|
|
208
|
+
input::-webkit-search-results-decoration {
|
|
209
|
+
-webkit-appearance: none !important;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
input::-webkit-contacts-auto-fill-button,
|
|
213
|
+
input::-webkit-credentials-auto-fill-button {
|
|
214
|
+
visibility: hidden !important;
|
|
215
|
+
display: none !important;
|
|
216
|
+
pointer-events: none !important;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
input::-ms-reveal,
|
|
220
|
+
input::-ms-clear {
|
|
221
|
+
display: none !important;
|
|
222
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function useClickOutside<T extends HTMLElement>(
|
|
4
|
+
handler: (event: MouseEvent | TouchEvent) => void
|
|
5
|
+
) {
|
|
6
|
+
const ref = useRef<T>(null)
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const listener = (event: MouseEvent | TouchEvent) => {
|
|
10
|
+
const el = ref.current
|
|
11
|
+
if (!el || el.contains(event.target as Node)) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
handler(event)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
document.addEventListener('mousedown', listener)
|
|
18
|
+
document.addEventListener('touchstart', listener)
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
document.removeEventListener('mousedown', listener)
|
|
22
|
+
document.removeEventListener('touchstart', listener)
|
|
23
|
+
}
|
|
24
|
+
}, [handler])
|
|
25
|
+
|
|
26
|
+
return ref
|
|
27
|
+
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Eraser } from 'lucide-react';
|
|
3
|
-
export default function EraseButton({ setData }) {
|
|
4
|
-
return (_jsx("button", { type: 'button', onClick: () => setData(''), className: 'absolute right-1 cursor-pointer px-2 py-1 bg-login-800 hover:bg-login-600 rounded-md', children: _jsx(Eraser, { className: 'w-5' }) }));
|
|
5
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
type labelProps = {
|
|
2
|
-
label: string;
|
|
3
|
-
value: any;
|
|
4
|
-
required?: boolean;
|
|
5
|
-
showRequired?: boolean;
|
|
6
|
-
className?: string;
|
|
7
|
-
color?: string;
|
|
8
|
-
};
|
|
9
|
-
export default function Label({ label, value, required, showRequired, className, color }: labelProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
export {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
export default function Label({ label, value, required, showRequired, className, color }) {
|
|
3
|
-
return (_jsx("label", { className: 'w-[calc(100%-10px)] truncate pointer-events-none absolute text-sm duration-300 transform z-10 ' +
|
|
4
|
-
'peer-focus:px-2 peer-focus:top-2 origin-left px-2 pt-1 peer-focus:scale-75 peer-focus:-translate-y-5 start-2 ' +
|
|
5
|
-
`${color ? color : 'bg-login-800'} ` +
|
|
6
|
-
`${value ? '-translate-y-5 scale-75 top-2 w-fit '
|
|
7
|
-
: '-translate-y-1/2 scale-100 top-1/2 '
|
|
8
|
-
+ 'peer-focus:w-fit '} ${showRequired ? 'text-red-500/50 ' : ''}
|
|
9
|
-
${!value &&
|
|
10
|
-
required ? 'group-[.submitPressed]:text-red-500/50 ' : ''}
|
|
11
|
-
${required ? 'after:content-["_*"] ' : ''}
|
|
12
|
-
${className}`, children: label }));
|
|
13
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
type MarkdownProps = {
|
|
2
|
-
name: string;
|
|
3
|
-
label: string;
|
|
4
|
-
value: string;
|
|
5
|
-
setValue: (_: string | number) => void;
|
|
6
|
-
className?: string;
|
|
7
|
-
tooltip?: string;
|
|
8
|
-
required?: boolean;
|
|
9
|
-
rows?: number;
|
|
10
|
-
color?: string;
|
|
11
|
-
buttonColor?: string;
|
|
12
|
-
buttonColorHighlighted?: string;
|
|
13
|
-
};
|
|
14
|
-
export default function Markdown({ name, label, value, className, tooltip, required, rows, setValue, color, buttonColor, buttonColorHighlighted }: MarkdownProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
-
export {};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useRef, useState } from 'react';
|
|
4
|
-
import Label from './label';
|
|
5
|
-
import ToolTip from './tooltip';
|
|
6
|
-
export default function Markdown({ name, label, value, className, tooltip, required, rows = 6, setValue, color, buttonColor, buttonColorHighlighted }) {
|
|
7
|
-
const [hasBlured, setHasBlured] = useState(false);
|
|
8
|
-
const textareaRef = useRef(null);
|
|
9
|
-
const smallButtonStyle = `px-2 py-1 rounded
|
|
10
|
-
${buttonColorHighlighted ? `hover:${buttonColorHighlighted}` : 'hover:bg-login-500'}
|
|
11
|
-
${' '}${buttonColor ? buttonColor : 'bg-login-600'}`;
|
|
12
|
-
function wrapSelection(before, after = before, placeHolder = '') {
|
|
13
|
-
const textarea = textareaRef.current;
|
|
14
|
-
if (!textarea)
|
|
15
|
-
return;
|
|
16
|
-
const start = textarea.selectionStart;
|
|
17
|
-
const end = textarea.selectionEnd;
|
|
18
|
-
const selected = value.slice(start, end) || placeHolder;
|
|
19
|
-
const newValue = value.slice(0, start) + before + selected + after + value.slice(end);
|
|
20
|
-
setValue(newValue);
|
|
21
|
-
requestAnimationFrame(() => {
|
|
22
|
-
const pos = start + before.length;
|
|
23
|
-
textarea.focus();
|
|
24
|
-
textarea.setSelectionRange(pos, pos + selected.length);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return (_jsxs("div", { className: `w-full ${className ?? ''}`, children: [_jsxs("div", { className: 'relative', children: [_jsx("textarea", { name: name, ref: textareaRef, value: value, onChange: (e) => setValue(e.target.value), onBlur: () => setHasBlured(true), rows: rows, required: required, className: 'block px-2.5 pb-2.5 pt-4 w-full text-sm ' +
|
|
28
|
-
'rounded-lg border-[0.10rem] appearance-none ' +
|
|
29
|
-
'border-login-200 focus:outline-none focus:ring-0' +
|
|
30
|
-
' focus:border-login-50 peer resize-vertical ' +
|
|
31
|
-
`${color ? color : 'bg-login-800'}` }), _jsx(Label, { label: label, value: value, color: color, required: required, showRequired: required && !value && hasBlured }), tooltip && _jsx(ToolTip, { info: tooltip })] }), _jsx("div", { className: 'flex items-center justify-between gap-2 mt-2', children: _jsxs("div", { className: 'flex gap-2', children: [_jsx("button", { type: 'button', className: smallButtonStyle, onClick: () => wrapSelection('**', '**', 'bold'), children: "B" }), _jsx("button", { type: 'button', className: smallButtonStyle, onClick: () => wrapSelection('*', '*', 'italic'), children: "I" }), _jsx("button", { type: 'button', className: smallButtonStyle, onClick: () => wrapSelection('\n```\n', '\n```\n', 'code block'), children: "CB" }), _jsx("button", { type: 'button', className: smallButtonStyle, onClick: () => wrapSelection('[', '](url)', 'text'), children: "Link" }), _jsx("button", { type: 'button', className: smallButtonStyle, onClick: () => wrapSelection('\n- ', '', 'list item'), children: "UL" })] }) })] }));
|
|
32
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
type TagInputProps = {
|
|
2
|
-
name: string;
|
|
3
|
-
label: string;
|
|
4
|
-
value?: string[];
|
|
5
|
-
setValue: (_: string[]) => void;
|
|
6
|
-
className?: string;
|
|
7
|
-
tooltip?: string;
|
|
8
|
-
required?: boolean;
|
|
9
|
-
};
|
|
10
|
-
export default function TagInput({ name, label, value, className, tooltip, required, setValue, }: TagInputProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import ToolTip from './tooltip';
|
|
5
|
-
import Label from './label';
|
|
6
|
-
import EraseButton from './erase';
|
|
7
|
-
import { X } from 'lucide-react';
|
|
8
|
-
export default function TagInput({ name, label, value = [], className, tooltip, required, setValue, }) {
|
|
9
|
-
const original = value;
|
|
10
|
-
const [input, setInput] = useState('');
|
|
11
|
-
const [hasBlured, setHasBlured] = useState(false);
|
|
12
|
-
function addTag(value) {
|
|
13
|
-
const trimmed = value.trim();
|
|
14
|
-
if (trimmed && !value.includes(trimmed)) {
|
|
15
|
-
setValue([...value, trimmed]);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function removeTag(idx) {
|
|
19
|
-
setValue(value.filter((_, i) => i !== idx));
|
|
20
|
-
}
|
|
21
|
-
function handleKeyDown(e) {
|
|
22
|
-
if ((e.key === 'Enter' || e.key === ',' || e.key === 'Tab') &&
|
|
23
|
-
input.trim()) {
|
|
24
|
-
e.preventDefault();
|
|
25
|
-
addTag(input);
|
|
26
|
-
setInput('');
|
|
27
|
-
}
|
|
28
|
-
if (e.key === 'Backspace' && !input && value.length) {
|
|
29
|
-
setValue(value.slice(0, -1));
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function handleErase() {
|
|
33
|
-
setValue([]);
|
|
34
|
-
setInput('');
|
|
35
|
-
}
|
|
36
|
-
const toRemove = original.filter((tag) => !value.includes(tag));
|
|
37
|
-
const toAdd = value.filter((tag) => !original.includes(tag));
|
|
38
|
-
return (_jsx("div", { className: `w-full ${className}`, children: _jsxs("div", { className: 'relative flex items-center flex-wrap gap-1 ' +
|
|
39
|
-
'border-[0.10rem] border-login-200 ' +
|
|
40
|
-
'rounded-lg ' +
|
|
41
|
-
'px-2.5 pt-3 pb-2.5 bg-login-800', children: [_jsxs("div", { className: 'flex flex-wrap gap-1 items-center w-full', children: [value.map((tag, idx) => (_jsxs("span", { className: 'bg-login-600 text-sm rounded px-2 ' +
|
|
42
|
-
'py-0.5 flex items-center gap-0.5', children: [tag, _jsx("button", { type: 'button', className: 'ml-1 text-red-700 hover:text-red-800', onClick: () => removeTag(idx), children: _jsx(X, { className: 'h-4 stroke-3' }) })] }, tag + idx))), _jsx("input", { value: input, onChange: (e) => setInput(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setHasBlured(true), className: 'peer flex-1 min-w-[6ch] bg-transparent ' +
|
|
43
|
-
'outline-none text-sm', autoComplete: 'off', required: required && value.length === 0 }), toRemove.map((tag) => (_jsx("input", { type: 'hidden', name: name + '_remove', value: tag }, tag))), toAdd.map((tag) => (_jsx("input", { type: 'hidden', name: name + '_add', value: tag }, tag))), _jsx(Label, { label: label, value: value.length ? value.join(', ') : '', required: required, showRequired: required && value.length === 0 && hasBlured, className: 'pointer-events-none left-2' })] }), value.length > 0 && _jsx(EraseButton, { setData: handleErase }), value.length === 0 && tooltip && _jsx(ToolTip, { info: tooltip })] }) }));
|
|
44
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
export default function ToolTip({ info, className }) {
|
|
3
|
-
return (_jsxs("div", { className: `absolute z-19 right-0 px-1 flex justify-center ${className}`, children: [_jsx("span", { className: 'peer cursor-pointer rounded-sm px-3 py-1 bg-login-800 hover:bg-login-600', children: "?" }), _jsx("div", { className: 'absolute hidden peer-hover:block p-2 rounded z-20 bg-login-700 border left-12 w-max max-w-3xs', children: info })] }));
|
|
4
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Eraser } from 'lucide-react'
|
|
2
|
-
|
|
3
|
-
export default function EraseButton({ setData }: { setData: (data: string) => void }) {
|
|
4
|
-
return (
|
|
5
|
-
<button
|
|
6
|
-
type='button'
|
|
7
|
-
onClick={() => setData('')}
|
|
8
|
-
className={'absolute right-1 cursor-pointer px-2 py-1 bg-login-800 hover:bg-login-600 rounded-md'}
|
|
9
|
-
>
|
|
10
|
-
<Eraser className='w-5' />
|
|
11
|
-
</button>
|
|
12
|
-
)
|
|
13
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
type labelProps = {
|
|
2
|
-
label: string
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
-
value: any
|
|
5
|
-
required?: boolean
|
|
6
|
-
showRequired?: boolean
|
|
7
|
-
className?: string
|
|
8
|
-
color?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default function Label({ label, value, required, showRequired, className, color }: labelProps) {
|
|
12
|
-
return (
|
|
13
|
-
<label
|
|
14
|
-
className={
|
|
15
|
-
'w-[calc(100%-10px)] truncate pointer-events-none absolute text-sm duration-300 transform z-10 ' +
|
|
16
|
-
'peer-focus:px-2 peer-focus:top-2 origin-left px-2 pt-1 peer-focus:scale-75 peer-focus:-translate-y-5 start-2 ' +
|
|
17
|
-
`${color ? color : 'bg-login-800'} ` +
|
|
18
|
-
`${value ? '-translate-y-5 scale-75 top-2 w-fit '
|
|
19
|
-
: '-translate-y-1/2 scale-100 top-1/2 '
|
|
20
|
-
+ 'peer-focus:w-fit '
|
|
21
|
-
} ${showRequired ? 'text-red-500/50 ' : ''}
|
|
22
|
-
${!value &&
|
|
23
|
-
required ? 'group-[.submitPressed]:text-red-500/50 ' : ''}
|
|
24
|
-
${required ? 'after:content-["_*"] ' : ''}
|
|
25
|
-
${className}`
|
|
26
|
-
}
|
|
27
|
-
>
|
|
28
|
-
{label}
|
|
29
|
-
</label>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useRef, useState } from 'react'
|
|
4
|
-
import Label from './label'
|
|
5
|
-
import ToolTip from './tooltip'
|
|
6
|
-
|
|
7
|
-
type MarkdownProps = {
|
|
8
|
-
name: string
|
|
9
|
-
label: string
|
|
10
|
-
value: string
|
|
11
|
-
setValue: (_: string | number) => void
|
|
12
|
-
className?: string
|
|
13
|
-
tooltip?: string
|
|
14
|
-
required?: boolean
|
|
15
|
-
rows?: number
|
|
16
|
-
color?: string
|
|
17
|
-
buttonColor?: string
|
|
18
|
-
buttonColorHighlighted?: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default function Markdown({
|
|
22
|
-
name,
|
|
23
|
-
label,
|
|
24
|
-
value,
|
|
25
|
-
className,
|
|
26
|
-
tooltip,
|
|
27
|
-
required,
|
|
28
|
-
rows = 6,
|
|
29
|
-
setValue,
|
|
30
|
-
color,
|
|
31
|
-
buttonColor,
|
|
32
|
-
buttonColorHighlighted
|
|
33
|
-
}: MarkdownProps) {
|
|
34
|
-
const [hasBlured, setHasBlured] = useState(false)
|
|
35
|
-
const textareaRef = useRef<HTMLTextAreaElement | null>(null)
|
|
36
|
-
const smallButtonStyle = `px-2 py-1 rounded
|
|
37
|
-
${buttonColorHighlighted ? `hover:${buttonColorHighlighted}` : 'hover:bg-login-500'}
|
|
38
|
-
${' '}${buttonColor ? buttonColor : 'bg-login-600'}`
|
|
39
|
-
|
|
40
|
-
function wrapSelection(before: string, after = before, placeHolder = '') {
|
|
41
|
-
const textarea = textareaRef.current
|
|
42
|
-
if (!textarea) return
|
|
43
|
-
const start = textarea.selectionStart
|
|
44
|
-
const end = textarea.selectionEnd
|
|
45
|
-
const selected = value.slice(start, end) || placeHolder
|
|
46
|
-
const newValue =
|
|
47
|
-
value.slice(0, start) + before + selected + after + value.slice(end)
|
|
48
|
-
setValue(newValue)
|
|
49
|
-
requestAnimationFrame(() => {
|
|
50
|
-
const pos = start + before.length
|
|
51
|
-
textarea.focus()
|
|
52
|
-
textarea.setSelectionRange(pos, pos + selected.length)
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<div className={`w-full ${className ?? ''}`}>
|
|
58
|
-
<div className='relative'>
|
|
59
|
-
<textarea
|
|
60
|
-
name={name}
|
|
61
|
-
ref={textareaRef}
|
|
62
|
-
value={value}
|
|
63
|
-
onChange={(e) => setValue(e.target.value)}
|
|
64
|
-
onBlur={() => setHasBlured(true)}
|
|
65
|
-
rows={rows}
|
|
66
|
-
required={required}
|
|
67
|
-
className={
|
|
68
|
-
'block px-2.5 pb-2.5 pt-4 w-full text-sm ' +
|
|
69
|
-
'rounded-lg border-[0.10rem] appearance-none ' +
|
|
70
|
-
'border-login-200 focus:outline-none focus:ring-0' +
|
|
71
|
-
' focus:border-login-50 peer resize-vertical ' +
|
|
72
|
-
`${color ? color : 'bg-login-800'}`
|
|
73
|
-
}
|
|
74
|
-
/>
|
|
75
|
-
|
|
76
|
-
<Label
|
|
77
|
-
label={label}
|
|
78
|
-
value={value}
|
|
79
|
-
color={color}
|
|
80
|
-
required={required}
|
|
81
|
-
showRequired={required && !value && hasBlured}
|
|
82
|
-
/>
|
|
83
|
-
{tooltip && <ToolTip info={tooltip} />}
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
|
-
<div className='flex items-center justify-between gap-2 mt-2'>
|
|
87
|
-
<div className='flex gap-2'>
|
|
88
|
-
<button
|
|
89
|
-
type='button'
|
|
90
|
-
className={smallButtonStyle}
|
|
91
|
-
onClick={() => wrapSelection('**', '**', 'bold')}
|
|
92
|
-
>
|
|
93
|
-
B
|
|
94
|
-
</button>
|
|
95
|
-
<button
|
|
96
|
-
type='button'
|
|
97
|
-
className={smallButtonStyle}
|
|
98
|
-
onClick={() => wrapSelection('*', '*', 'italic')}
|
|
99
|
-
>
|
|
100
|
-
I
|
|
101
|
-
</button>
|
|
102
|
-
<button
|
|
103
|
-
type='button'
|
|
104
|
-
className={smallButtonStyle}
|
|
105
|
-
onClick={() =>
|
|
106
|
-
wrapSelection('\n```\n', '\n```\n', 'code block')
|
|
107
|
-
}
|
|
108
|
-
>
|
|
109
|
-
CB
|
|
110
|
-
</button>
|
|
111
|
-
<button
|
|
112
|
-
type='button'
|
|
113
|
-
className={smallButtonStyle}
|
|
114
|
-
onClick={() => wrapSelection('[', '](url)', 'text')}
|
|
115
|
-
>
|
|
116
|
-
Link
|
|
117
|
-
</button>
|
|
118
|
-
<button
|
|
119
|
-
type='button'
|
|
120
|
-
className={smallButtonStyle}
|
|
121
|
-
onClick={() => wrapSelection('\n- ', '', 'list item')}
|
|
122
|
-
>
|
|
123
|
-
UL
|
|
124
|
-
</button>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
)
|
|
129
|
-
}
|