ywana-core8 0.1.75 → 0.1.76
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/ACCORDION_EVALUATION.md +583 -0
- package/CHECKBOX_EVALUATION.md +273 -0
- package/CHIP_EVALUATION.md +542 -0
- package/COLOR_EVALUATION.md +524 -0
- package/COMPONENTS_EVALUATION.md +477 -0
- package/FORM_EVALUATION.md +459 -0
- package/HEADER_EVALUATION.md +436 -0
- package/ICON_EVALUATION.md +254 -0
- package/LIST_EVALUATION.md +574 -0
- package/PROGRESS_EVALUATION.md +450 -0
- package/RADIO_EVALUATION.md +439 -0
- package/RADIO_VISUAL_FIX.md +183 -0
- package/SECTION_IMPROVEMENTS.md +153 -0
- package/SWITCH_EVALUATION.md +335 -0
- package/SWITCH_VISUAL_FIX.md +232 -0
- package/TAB_EVALUATION.md +626 -0
- package/TEXTFIELD_EVALUATION.md +747 -0
- package/TOOLTIP_FIX.md +157 -0
- package/TREE_EVALUATION.md +708 -0
- package/dist/index.cjs +7900 -1615
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +6094 -1122
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +7929 -1645
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +7900 -1615
- package/dist/index.umd.js.map +1 -1
- package/jest.config.js +24 -0
- package/package.json +10 -1
- package/src/html/accordion.css +208 -4
- package/src/html/accordion.example.js +390 -0
- package/src/html/accordion.js +284 -28
- package/src/html/accordion.unit.test.js +334 -0
- package/src/html/button.css +157 -16
- package/src/html/button.example.js +374 -0
- package/src/html/button.js +240 -60
- package/src/html/button.test.js +422 -0
- package/src/html/checkbox.css +74 -2
- package/src/html/checkbox.example.js +316 -0
- package/src/html/checkbox.js +113 -26
- package/src/html/checkbox.test.js +285 -0
- package/src/html/chip.css +230 -19
- package/src/html/chip.example.js +355 -0
- package/src/html/chip.js +321 -25
- package/src/html/chip.test.js +425 -0
- package/src/html/color.css +435 -6
- package/src/html/color.example.js +527 -0
- package/src/html/color.js +458 -9
- package/src/html/color.test.js +362 -4
- package/src/html/components.example.js +492 -0
- package/src/html/components_enhanced.test.js +581 -0
- package/src/html/form.css +70 -3
- package/src/html/form.example.js +385 -0
- package/src/html/form.js +232 -34
- package/src/html/form.test.js +369 -0
- package/src/html/header2.css +264 -0
- package/src/html/header2.example.js +411 -0
- package/src/html/header2.js +203 -0
- package/src/html/header2.test.js +377 -0
- package/src/html/icon.css +20 -2
- package/src/html/icon.example.js +268 -0
- package/src/html/icon.js +86 -16
- package/src/html/icon.test.js +231 -0
- package/src/html/index.js +1 -1
- package/src/html/list.css +393 -1
- package/src/html/list.example.js +404 -0
- package/src/html/list.js +583 -40
- package/src/html/list.test.js +383 -0
- package/src/html/progress.css +707 -17
- package/src/html/progress.example.js +424 -0
- package/src/html/progress.js +906 -9
- package/src/html/progress.test.js +313 -0
- package/src/html/property.css +399 -0
- package/src/html/property.example.js +553 -0
- package/src/html/property.js +393 -15
- package/src/html/property.test.js +351 -2
- package/src/html/radio-visual-test.js +289 -0
- package/src/html/radio.css +137 -11
- package/src/html/radio.example.js +389 -0
- package/src/html/radio.js +234 -10
- package/src/html/radio.test.js +318 -0
- package/src/html/section.example.js +99 -0
- package/src/html/section.js +40 -3
- package/src/html/section.test.js +131 -0
- package/src/html/selector.css +329 -3
- package/src/html/selector.js +369 -23
- package/src/html/switch-debug.js +197 -0
- package/src/html/switch-test-visual.js +294 -0
- package/src/html/switch.css +200 -0
- package/src/html/switch.example.js +461 -0
- package/src/html/switch.js +283 -23
- package/src/html/switch.test.js +355 -0
- package/src/html/tab.css +288 -0
- package/src/html/tab.example.js +446 -0
- package/src/html/tab.js +387 -22
- package/src/html/tab_enhanced.js +378 -0
- package/src/html/tab_enhanced.test.js +504 -0
- package/src/html/table2.css +576 -0
- package/src/html/table2.example.js +703 -0
- package/src/html/table2.js +1252 -0
- package/src/html/table2.migration.md +328 -0
- package/src/html/table2.test.js +582 -0
- package/src/html/text.css +375 -0
- package/src/html/text.js +311 -20
- package/src/html/textfield2.css +842 -0
- package/src/html/textfield2.example.js +499 -0
- package/src/html/textfield2.js +1130 -0
- package/src/html/textfield2.test.js +950 -0
- package/src/html/thumbnail.css +289 -2
- package/src/html/thumbnail.js +214 -9
- package/src/html/tokenfield.css +449 -1
- package/src/html/tokenfield.example.js +503 -0
- package/src/html/tokenfield.js +561 -56
- package/src/html/tokenfield.test.js +423 -0
- package/src/html/tooltip-positioning-demo.js +187 -0
- package/src/html/tooltip.css +25 -2
- package/src/html/tree.css +228 -0
- package/src/html/tree.example.js +475 -0
- package/src/html/tree.js +712 -28
- package/src/html/tree_enhanced.test.js +495 -0
- package/table2.test.js +454 -0
- package/src/html/button.tsx +0 -38
package/src/html/color.js
CHANGED
@@ -1,19 +1,468 @@
|
|
1
|
-
import React, {useState} from 'react'
|
1
|
+
import React, { useState, useCallback, useRef, useEffect } from 'react'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
import { Icon } from './icon'
|
4
|
+
import { Text } from './text'
|
2
5
|
import './color.css'
|
3
6
|
|
7
|
+
/**
|
8
|
+
* Enhanced ColorField component with improved functionality while maintaining 100% compatibility
|
9
|
+
*/
|
4
10
|
export const ColorField = (props) => {
|
11
|
+
const {
|
12
|
+
// Original props (100% compatible)
|
13
|
+
id,
|
14
|
+
label = "Color",
|
15
|
+
value,
|
16
|
+
onChange,
|
17
|
+
// New enhanced props (all optional for compatibility)
|
18
|
+
disabled = false,
|
19
|
+
required = false,
|
20
|
+
placeholder = "#000000",
|
21
|
+
format = 'hex',
|
22
|
+
showPreview = true,
|
23
|
+
showValue = false,
|
24
|
+
allowTransparent = false,
|
25
|
+
presetColors = [],
|
26
|
+
size = 'medium',
|
27
|
+
variant = 'default',
|
28
|
+
error,
|
29
|
+
helperText,
|
30
|
+
onFocus,
|
31
|
+
onBlur,
|
32
|
+
onClear,
|
33
|
+
clearable = false,
|
34
|
+
className,
|
35
|
+
style,
|
36
|
+
...restProps
|
37
|
+
} = props
|
5
38
|
|
6
|
-
const
|
39
|
+
const [internalValue, setInternalValue] = useState(value || placeholder)
|
40
|
+
const [isFocused, setIsFocused] = useState(false)
|
41
|
+
const [isValid, setIsValid] = useState(true)
|
42
|
+
const inputRef = useRef(null)
|
7
43
|
|
8
|
-
|
9
|
-
|
10
|
-
|
44
|
+
// Sync internal value with prop value
|
45
|
+
useEffect(() => {
|
46
|
+
if (value !== undefined) {
|
47
|
+
setInternalValue(value)
|
48
|
+
}
|
49
|
+
}, [value])
|
50
|
+
|
51
|
+
// Validate color format
|
52
|
+
const validateColor = useCallback((color) => {
|
53
|
+
if (!color) return allowTransparent
|
54
|
+
|
55
|
+
const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
|
56
|
+
const rgbRegex = /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/
|
57
|
+
const rgbaRegex = /^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/
|
58
|
+
const hslRegex = /^hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)$/
|
59
|
+
const hslaRegex = /^hsla\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*,\s*[\d.]+\s*\)$/
|
60
|
+
|
61
|
+
return hexRegex.test(color) || rgbRegex.test(color) || rgbaRegex.test(color) ||
|
62
|
+
hslRegex.test(color) || hslaRegex.test(color) ||
|
63
|
+
(allowTransparent && color.toLowerCase() === 'transparent')
|
64
|
+
}, [allowTransparent])
|
65
|
+
|
66
|
+
// Convert color to different formats
|
67
|
+
const convertColor = useCallback((color, targetFormat) => {
|
68
|
+
if (!color || !validateColor(color)) return color
|
69
|
+
|
70
|
+
try {
|
71
|
+
// Create a temporary element to get computed color
|
72
|
+
const tempElement = document.createElement('div')
|
73
|
+
tempElement.style.color = color
|
74
|
+
document.body.appendChild(tempElement)
|
75
|
+
const computedColor = window.getComputedStyle(tempElement).color
|
76
|
+
document.body.removeChild(tempElement)
|
77
|
+
|
78
|
+
if (targetFormat === 'hex') {
|
79
|
+
// Convert RGB to hex
|
80
|
+
const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/)
|
81
|
+
if (rgbMatch) {
|
82
|
+
const [, r, g, b] = rgbMatch
|
83
|
+
return `#${parseInt(r).toString(16).padStart(2, '0')}${parseInt(g).toString(16).padStart(2, '0')}${parseInt(b).toString(16).padStart(2, '0')}`
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
return color
|
88
|
+
} catch (error) {
|
89
|
+
console.warn('Color conversion failed:', error)
|
90
|
+
return color
|
91
|
+
}
|
92
|
+
}, [validateColor])
|
93
|
+
|
94
|
+
// Handle change (maintaining original behavior)
|
95
|
+
const handleChange = useCallback((event) => {
|
96
|
+
const newColor = event.target.value
|
97
|
+
setInternalValue(newColor)
|
98
|
+
|
99
|
+
const isValidColor = validateColor(newColor)
|
100
|
+
setIsValid(isValidColor)
|
101
|
+
|
102
|
+
if (onChange) {
|
103
|
+
const convertedColor = format !== 'hex' ? convertColor(newColor, format) : newColor
|
104
|
+
onChange(id, convertedColor)
|
105
|
+
}
|
106
|
+
}, [id, onChange, format, validateColor, convertColor])
|
107
|
+
|
108
|
+
// Handle focus
|
109
|
+
const handleFocus = useCallback((event) => {
|
110
|
+
setIsFocused(true)
|
111
|
+
if (onFocus) onFocus(event)
|
112
|
+
}, [onFocus])
|
113
|
+
|
114
|
+
// Handle blur
|
115
|
+
const handleBlur = useCallback((event) => {
|
116
|
+
setIsFocused(false)
|
117
|
+
if (onBlur) onBlur(event)
|
118
|
+
}, [onBlur])
|
119
|
+
|
120
|
+
// Handle clear
|
121
|
+
const handleClear = useCallback(() => {
|
122
|
+
if (disabled) return
|
123
|
+
|
124
|
+
const clearedValue = allowTransparent ? 'transparent' : placeholder
|
125
|
+
setInternalValue(clearedValue)
|
126
|
+
setIsValid(true)
|
127
|
+
|
128
|
+
if (onChange) onChange(id, clearedValue)
|
129
|
+
if (onClear) onClear()
|
130
|
+
}, [disabled, allowTransparent, placeholder, id, onChange, onClear])
|
131
|
+
|
132
|
+
// Handle preset color selection
|
133
|
+
const handlePresetSelect = useCallback((presetColor) => {
|
134
|
+
if (disabled) return
|
135
|
+
|
136
|
+
setInternalValue(presetColor)
|
137
|
+
setIsValid(true)
|
138
|
+
|
139
|
+
if (onChange) {
|
140
|
+
const convertedColor = format !== 'hex' ? convertColor(presetColor, format) : presetColor
|
141
|
+
onChange(id, convertedColor)
|
142
|
+
}
|
143
|
+
}, [disabled, id, onChange, format, convertColor])
|
144
|
+
|
145
|
+
// Generate CSS classes
|
146
|
+
const cssClasses = [
|
147
|
+
'color-field',
|
148
|
+
`color-field--${size}`,
|
149
|
+
`color-field--${variant}`,
|
150
|
+
disabled && 'color-field--disabled',
|
151
|
+
required && 'color-field--required',
|
152
|
+
isFocused && 'color-field--focused',
|
153
|
+
error && 'color-field--error',
|
154
|
+
!isValid && 'color-field--invalid',
|
155
|
+
showPreview && 'color-field--with-preview',
|
156
|
+
className
|
157
|
+
].filter(Boolean).join(' ')
|
158
|
+
|
159
|
+
// Generate preview style
|
160
|
+
const previewStyle = {
|
161
|
+
backgroundColor: internalValue && validateColor(internalValue) ? internalValue : 'transparent'
|
162
|
+
}
|
163
|
+
|
164
|
+
return (
|
165
|
+
<div className={cssClasses} style={style} {...restProps}>
|
166
|
+
{/* Label (maintaining original structure) */}
|
167
|
+
<label htmlFor={id} className="color-field__label">
|
168
|
+
{label}
|
169
|
+
{required && <span className="color-field__required">*</span>}
|
170
|
+
</label>
|
171
|
+
|
172
|
+
{/* Input container */}
|
173
|
+
<div className="color-field__input-container">
|
174
|
+
{/* Color preview */}
|
175
|
+
{showPreview && (
|
176
|
+
<div
|
177
|
+
className="color-field__preview"
|
178
|
+
style={previewStyle}
|
179
|
+
title={`Current color: ${internalValue}`}
|
180
|
+
>
|
181
|
+
{!internalValue || !validateColor(internalValue) ? (
|
182
|
+
<Icon icon="block" size="small" className="color-field__no-color" />
|
183
|
+
) : null}
|
184
|
+
</div>
|
185
|
+
)}
|
186
|
+
|
187
|
+
{/* Main color input (maintaining original structure) */}
|
188
|
+
<input
|
189
|
+
ref={inputRef}
|
190
|
+
id={id}
|
191
|
+
type="color"
|
192
|
+
value={internalValue && validateColor(internalValue) ? internalValue : placeholder}
|
193
|
+
onChange={handleChange}
|
194
|
+
onFocus={handleFocus}
|
195
|
+
onBlur={handleBlur}
|
196
|
+
disabled={disabled}
|
197
|
+
required={required}
|
198
|
+
className="color-field__input"
|
199
|
+
aria-invalid={!isValid || !!error}
|
200
|
+
aria-describedby={helperText ? `${id}-helper` : undefined}
|
201
|
+
/>
|
202
|
+
|
203
|
+
{/* Clear button */}
|
204
|
+
{clearable && internalValue && internalValue !== placeholder && (
|
205
|
+
<button
|
206
|
+
type="button"
|
207
|
+
onClick={handleClear}
|
208
|
+
disabled={disabled}
|
209
|
+
className="color-field__clear"
|
210
|
+
aria-label="Clear color"
|
211
|
+
>
|
212
|
+
<Icon icon="clear" size="small" />
|
213
|
+
</button>
|
214
|
+
)}
|
215
|
+
</div>
|
216
|
+
|
217
|
+
{/* Color value display */}
|
218
|
+
{showValue && internalValue && (
|
219
|
+
<div className="color-field__value">
|
220
|
+
<Text size="sm" color="muted">
|
221
|
+
{internalValue}
|
222
|
+
</Text>
|
223
|
+
</div>
|
224
|
+
)}
|
225
|
+
|
226
|
+
{/* Preset colors */}
|
227
|
+
{presetColors.length > 0 && (
|
228
|
+
<div className="color-field__presets">
|
229
|
+
<Text size="sm" color="muted" className="color-field__presets-label">
|
230
|
+
Presets:
|
231
|
+
</Text>
|
232
|
+
<div className="color-field__presets-grid">
|
233
|
+
{presetColors.map((presetColor, index) => (
|
234
|
+
<button
|
235
|
+
key={index}
|
236
|
+
type="button"
|
237
|
+
onClick={() => handlePresetSelect(presetColor)}
|
238
|
+
disabled={disabled}
|
239
|
+
className="color-field__preset"
|
240
|
+
style={{ backgroundColor: presetColor }}
|
241
|
+
title={presetColor}
|
242
|
+
aria-label={`Select preset color ${presetColor}`}
|
243
|
+
/>
|
244
|
+
))}
|
245
|
+
</div>
|
246
|
+
</div>
|
247
|
+
)}
|
248
|
+
|
249
|
+
{/* Helper text or error */}
|
250
|
+
{(helperText || error) && (
|
251
|
+
<div
|
252
|
+
id={`${id}-helper`}
|
253
|
+
className={`color-field__helper ${error ? 'color-field__helper--error' : ''}`}
|
254
|
+
>
|
255
|
+
<Text size="sm" color={error ? 'error' : 'muted'}>
|
256
|
+
{error || helperText}
|
257
|
+
</Text>
|
258
|
+
</div>
|
259
|
+
)}
|
260
|
+
</div>
|
261
|
+
)
|
262
|
+
}
|
263
|
+
|
264
|
+
// Color utilities
|
265
|
+
export const ColorUtils = {
|
266
|
+
/**
|
267
|
+
* Convert hex color to RGB
|
268
|
+
*/
|
269
|
+
hexToRgb: (hex) => {
|
270
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
271
|
+
return result ? {
|
272
|
+
r: parseInt(result[1], 16),
|
273
|
+
g: parseInt(result[2], 16),
|
274
|
+
b: parseInt(result[3], 16)
|
275
|
+
} : null
|
276
|
+
},
|
277
|
+
|
278
|
+
/**
|
279
|
+
* Convert RGB to hex
|
280
|
+
*/
|
281
|
+
rgbToHex: (r, g, b) => {
|
282
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`
|
283
|
+
},
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Get contrast ratio between two colors
|
287
|
+
*/
|
288
|
+
getContrastRatio: (color1, color2) => {
|
289
|
+
const getLuminance = (color) => {
|
290
|
+
const rgb = ColorUtils.hexToRgb(color)
|
291
|
+
if (!rgb) return 0
|
292
|
+
|
293
|
+
const [r, g, b] = [rgb.r, rgb.g, rgb.b].map(c => {
|
294
|
+
c = c / 255
|
295
|
+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
|
296
|
+
})
|
297
|
+
|
298
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
299
|
+
}
|
300
|
+
|
301
|
+
const lum1 = getLuminance(color1)
|
302
|
+
const lum2 = getLuminance(color2)
|
303
|
+
const brightest = Math.max(lum1, lum2)
|
304
|
+
const darkest = Math.min(lum1, lum2)
|
305
|
+
|
306
|
+
return (brightest + 0.05) / (darkest + 0.05)
|
307
|
+
},
|
308
|
+
|
309
|
+
/**
|
310
|
+
* Check if color is light or dark
|
311
|
+
*/
|
312
|
+
isLight: (color) => {
|
313
|
+
const rgb = ColorUtils.hexToRgb(color)
|
314
|
+
if (!rgb) return false
|
315
|
+
|
316
|
+
const brightness = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000
|
317
|
+
return brightness > 128
|
318
|
+
},
|
319
|
+
|
320
|
+
/**
|
321
|
+
* Generate color palette
|
322
|
+
*/
|
323
|
+
generatePalette: (baseColor, count = 5) => {
|
324
|
+
const rgb = ColorUtils.hexToRgb(baseColor)
|
325
|
+
if (!rgb) return []
|
326
|
+
|
327
|
+
const palette = []
|
328
|
+
for (let i = 0; i < count; i++) {
|
329
|
+
const factor = (i + 1) / (count + 1)
|
330
|
+
const r = Math.round(rgb.r + (255 - rgb.r) * factor)
|
331
|
+
const g = Math.round(rgb.g + (255 - rgb.g) * factor)
|
332
|
+
const b = Math.round(rgb.b + (255 - rgb.b) * factor)
|
333
|
+
palette.push(ColorUtils.rgbToHex(r, g, b))
|
334
|
+
}
|
335
|
+
return palette
|
11
336
|
}
|
337
|
+
}
|
338
|
+
|
339
|
+
// Color picker component
|
340
|
+
export const ColorPicker = (props) => {
|
341
|
+
const {
|
342
|
+
value,
|
343
|
+
onChange,
|
344
|
+
presetColors = [
|
345
|
+
'#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF',
|
346
|
+
'#000000', '#FFFFFF', '#808080', '#800000', '#008000', '#000080'
|
347
|
+
],
|
348
|
+
disabled = false,
|
349
|
+
className,
|
350
|
+
...restProps
|
351
|
+
} = props
|
352
|
+
|
353
|
+
const [isOpen, setIsOpen] = useState(false)
|
354
|
+
|
355
|
+
const handleColorSelect = useCallback((color) => {
|
356
|
+
if (onChange) onChange(color)
|
357
|
+
setIsOpen(false)
|
358
|
+
}, [onChange])
|
12
359
|
|
13
360
|
return (
|
14
|
-
<div className=
|
15
|
-
<
|
16
|
-
|
361
|
+
<div className={`color-picker ${className || ''}`} {...restProps}>
|
362
|
+
<button
|
363
|
+
type="button"
|
364
|
+
onClick={() => setIsOpen(!isOpen)}
|
365
|
+
disabled={disabled}
|
366
|
+
className="color-picker__trigger"
|
367
|
+
style={{ backgroundColor: value || '#000000' }}
|
368
|
+
aria-label="Open color picker"
|
369
|
+
/>
|
370
|
+
|
371
|
+
{isOpen && (
|
372
|
+
<div className="color-picker__dropdown">
|
373
|
+
<div className="color-picker__grid">
|
374
|
+
{presetColors.map((color, index) => (
|
375
|
+
<button
|
376
|
+
key={index}
|
377
|
+
type="button"
|
378
|
+
onClick={() => handleColorSelect(color)}
|
379
|
+
className="color-picker__option"
|
380
|
+
style={{ backgroundColor: color }}
|
381
|
+
title={color}
|
382
|
+
aria-label={`Select color ${color}`}
|
383
|
+
/>
|
384
|
+
))}
|
385
|
+
</div>
|
386
|
+
</div>
|
387
|
+
)}
|
17
388
|
</div>
|
18
389
|
)
|
19
|
-
}
|
390
|
+
}
|
391
|
+
|
392
|
+
// PropTypes
|
393
|
+
ColorField.propTypes = {
|
394
|
+
/** Field ID */
|
395
|
+
id: PropTypes.string,
|
396
|
+
/** Field label */
|
397
|
+
label: PropTypes.string,
|
398
|
+
/** Current color value */
|
399
|
+
value: PropTypes.string,
|
400
|
+
/** Change callback */
|
401
|
+
onChange: PropTypes.func,
|
402
|
+
/** Disabled state */
|
403
|
+
disabled: PropTypes.bool,
|
404
|
+
/** Required field */
|
405
|
+
required: PropTypes.bool,
|
406
|
+
/** Placeholder color */
|
407
|
+
placeholder: PropTypes.string,
|
408
|
+
/** Color format */
|
409
|
+
format: PropTypes.oneOf(['hex', 'rgb', 'hsl']),
|
410
|
+
/** Show color preview */
|
411
|
+
showPreview: PropTypes.bool,
|
412
|
+
/** Show color value */
|
413
|
+
showValue: PropTypes.bool,
|
414
|
+
/** Allow transparent colors */
|
415
|
+
allowTransparent: PropTypes.bool,
|
416
|
+
/** Preset colors array */
|
417
|
+
presetColors: PropTypes.arrayOf(PropTypes.string),
|
418
|
+
/** Field size */
|
419
|
+
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
420
|
+
/** Visual variant */
|
421
|
+
variant: PropTypes.oneOf(['default', 'outlined', 'filled']),
|
422
|
+
/** Error message */
|
423
|
+
error: PropTypes.string,
|
424
|
+
/** Helper text */
|
425
|
+
helperText: PropTypes.string,
|
426
|
+
/** Focus callback */
|
427
|
+
onFocus: PropTypes.func,
|
428
|
+
/** Blur callback */
|
429
|
+
onBlur: PropTypes.func,
|
430
|
+
/** Clear callback */
|
431
|
+
onClear: PropTypes.func,
|
432
|
+
/** Show clear button */
|
433
|
+
clearable: PropTypes.bool,
|
434
|
+
/** Additional CSS classes */
|
435
|
+
className: PropTypes.string,
|
436
|
+
/** Inline styles */
|
437
|
+
style: PropTypes.object
|
438
|
+
}
|
439
|
+
|
440
|
+
ColorField.defaultProps = {
|
441
|
+
label: "Color",
|
442
|
+
disabled: false,
|
443
|
+
required: false,
|
444
|
+
placeholder: "#000000",
|
445
|
+
format: 'hex',
|
446
|
+
showPreview: true,
|
447
|
+
showValue: false,
|
448
|
+
allowTransparent: false,
|
449
|
+
presetColors: [],
|
450
|
+
size: 'medium',
|
451
|
+
variant: 'default',
|
452
|
+
clearable: false
|
453
|
+
}
|
454
|
+
|
455
|
+
ColorPicker.propTypes = {
|
456
|
+
/** Current color value */
|
457
|
+
value: PropTypes.string,
|
458
|
+
/** Change callback */
|
459
|
+
onChange: PropTypes.func,
|
460
|
+
/** Preset colors */
|
461
|
+
presetColors: PropTypes.arrayOf(PropTypes.string),
|
462
|
+
/** Disabled state */
|
463
|
+
disabled: PropTypes.bool,
|
464
|
+
/** Additional CSS classes */
|
465
|
+
className: PropTypes.string
|
466
|
+
}
|
467
|
+
|
468
|
+
export default ColorField
|