ywana-core8 0.1.75 → 0.1.77

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 (122) hide show
  1. package/ACCORDION_EVALUATION.md +583 -0
  2. package/CHECKBOX_EVALUATION.md +273 -0
  3. package/CHIP_EVALUATION.md +542 -0
  4. package/COLOR_EVALUATION.md +524 -0
  5. package/COMPONENTS_EVALUATION.md +477 -0
  6. package/FORM_EVALUATION.md +459 -0
  7. package/HEADER_EVALUATION.md +436 -0
  8. package/ICON_EVALUATION.md +254 -0
  9. package/LIST_EVALUATION.md +574 -0
  10. package/PROGRESS_EVALUATION.md +450 -0
  11. package/RADIO_EVALUATION.md +439 -0
  12. package/RADIO_VISUAL_FIX.md +183 -0
  13. package/SECTION_IMPROVEMENTS.md +153 -0
  14. package/SWITCH_EVALUATION.md +335 -0
  15. package/SWITCH_VISUAL_FIX.md +232 -0
  16. package/TAB_EVALUATION.md +626 -0
  17. package/TEXTFIELD_EVALUATION.md +747 -0
  18. package/TOOLTIP_FIX.md +157 -0
  19. package/TREE_EVALUATION.md +708 -0
  20. package/dist/index.cjs +10893 -1969
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.css +7768 -1096
  23. package/dist/index.css.map +1 -1
  24. package/dist/index.modern.js +10921 -2005
  25. package/dist/index.modern.js.map +1 -1
  26. package/dist/index.umd.js +10893 -1969
  27. package/dist/index.umd.js.map +1 -1
  28. package/jest.config.js +24 -0
  29. package/package.json +10 -1
  30. package/src/html/accordion.css +208 -4
  31. package/src/html/accordion.example.js +390 -0
  32. package/src/html/accordion.js +284 -28
  33. package/src/html/accordion.unit.test.js +334 -0
  34. package/src/html/button.css +157 -16
  35. package/src/html/button.example.js +374 -0
  36. package/src/html/button.js +240 -60
  37. package/src/html/button.test.js +422 -0
  38. package/src/html/checkbox.css +74 -2
  39. package/src/html/checkbox.example.js +316 -0
  40. package/src/html/checkbox.js +113 -26
  41. package/src/html/checkbox.test.js +285 -0
  42. package/src/html/chip.css +230 -19
  43. package/src/html/chip.example.js +355 -0
  44. package/src/html/chip.js +321 -25
  45. package/src/html/chip.test.js +425 -0
  46. package/src/html/color.css +435 -6
  47. package/src/html/color.example.js +527 -0
  48. package/src/html/color.js +458 -9
  49. package/src/html/color.test.js +362 -4
  50. package/src/html/components.example.js +492 -0
  51. package/src/html/components_enhanced.test.js +581 -0
  52. package/src/html/form.css +70 -3
  53. package/src/html/form.example.js +385 -0
  54. package/src/html/form.js +232 -34
  55. package/src/html/form.test.js +369 -0
  56. package/src/html/header2.css +264 -0
  57. package/src/html/header2.example.js +411 -0
  58. package/src/html/header2.js +203 -0
  59. package/src/html/header2.test.js +377 -0
  60. package/src/html/icon.css +20 -2
  61. package/src/html/icon.example.js +268 -0
  62. package/src/html/icon.js +86 -16
  63. package/src/html/icon.test.js +231 -0
  64. package/src/html/index.js +4 -1
  65. package/src/html/list.css +393 -1
  66. package/src/html/list.example.js +404 -0
  67. package/src/html/list.js +583 -40
  68. package/src/html/list.test.js +383 -0
  69. package/src/html/progress.css +707 -17
  70. package/src/html/progress.example.js +424 -0
  71. package/src/html/progress.js +906 -9
  72. package/src/html/progress.test.js +313 -0
  73. package/src/html/property.css +399 -0
  74. package/src/html/property.example.js +553 -0
  75. package/src/html/property.js +393 -15
  76. package/src/html/property.test.js +351 -2
  77. package/src/html/radio-visual-test.js +289 -0
  78. package/src/html/radio.css +137 -11
  79. package/src/html/radio.example.js +389 -0
  80. package/src/html/radio.js +234 -10
  81. package/src/html/radio.test.js +318 -0
  82. package/src/html/section.example.js +99 -0
  83. package/src/html/section.js +40 -3
  84. package/src/html/section.test.js +131 -0
  85. package/src/html/selector.css +329 -3
  86. package/src/html/selector.js +369 -23
  87. package/src/html/switch-debug.js +197 -0
  88. package/src/html/switch-test-visual.js +294 -0
  89. package/src/html/switch.css +200 -0
  90. package/src/html/switch.example.js +461 -0
  91. package/src/html/switch.js +283 -23
  92. package/src/html/switch.test.js +355 -0
  93. package/src/html/tab.css +289 -0
  94. package/src/html/tab.example.js +446 -0
  95. package/src/html/tab.js +387 -22
  96. package/src/html/tab_enhanced.js +378 -0
  97. package/src/html/tab_enhanced.test.js +504 -0
  98. package/src/html/table2.css +576 -0
  99. package/src/html/table2.example.js +703 -0
  100. package/src/html/table2.js +1252 -0
  101. package/src/html/table2.migration.md +328 -0
  102. package/src/html/table2.test.js +582 -0
  103. package/src/html/text.css +375 -0
  104. package/src/html/text.js +311 -20
  105. package/src/html/textfield2.css +841 -0
  106. package/src/html/textfield2.example.js +1370 -0
  107. package/src/html/textfield2.js +1143 -0
  108. package/src/html/textfield2.test.js +950 -0
  109. package/src/html/thumbnail.css +289 -2
  110. package/src/html/thumbnail.js +214 -9
  111. package/src/html/tokenfield.css +449 -1
  112. package/src/html/tokenfield.example.js +503 -0
  113. package/src/html/tokenfield.js +561 -56
  114. package/src/html/tokenfield.test.js +423 -0
  115. package/src/html/tooltip-positioning-demo.js +187 -0
  116. package/src/html/tooltip.css +25 -2
  117. package/src/html/tree.css +240 -10
  118. package/src/html/tree.example.js +475 -0
  119. package/src/html/tree.js +714 -28
  120. package/src/html/tree_enhanced.test.js +495 -0
  121. package/table2.test.js +454 -0
  122. package/src/html/button.tsx +0 -38
@@ -6,11 +6,298 @@
6
6
  height: 100%;
7
7
  min-height: 3rem;
8
8
  max-height: 6rem;
9
-
9
+
10
10
  overflow: hidden;
11
+ position: relative;
12
+ display: inline-block;
13
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
11
14
  }
12
15
 
13
- .thumbnail>img {
16
+ .thumbnail>img,
17
+ .thumbnail__image {
14
18
  width: 100%;
15
19
  height: 100%;
20
+ display: block;
21
+ }
22
+
23
+ /* Enhanced Thumbnail Styles - New functionality while maintaining compatibility */
24
+
25
+ /* Sizes */
26
+ .thumbnail--small {
27
+ min-width: 2rem;
28
+ max-width: 4rem;
29
+ min-height: 2rem;
30
+ max-height: 4rem;
31
+ }
32
+
33
+ .thumbnail--medium {
34
+ min-width: 3rem;
35
+ max-width: 6rem;
36
+ min-height: 3rem;
37
+ max-height: 6rem;
38
+ }
39
+
40
+ .thumbnail--large {
41
+ min-width: 4rem;
42
+ max-width: 8rem;
43
+ min-height: 4rem;
44
+ max-height: 8rem;
45
+ }
46
+
47
+ .thumbnail--xlarge {
48
+ min-width: 6rem;
49
+ max-width: 12rem;
50
+ min-height: 6rem;
51
+ max-height: 12rem;
52
+ }
53
+
54
+ /* Shapes */
55
+ .thumbnail--square {
56
+ border-radius: 4px;
57
+ }
58
+
59
+ .thumbnail--circle {
60
+ border-radius: 50%;
61
+ }
62
+
63
+ .thumbnail--rounded {
64
+ border-radius: 12px;
65
+ }
66
+
67
+ /* States */
68
+ .thumbnail--bordered {
69
+ border: 2px solid var(--divider-color, #e0e0e0);
70
+ }
71
+
72
+ .thumbnail--shadow {
73
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
74
+ }
75
+
76
+ .thumbnail--clickable {
77
+ cursor: pointer;
78
+ }
79
+
80
+ .thumbnail--clickable:hover {
81
+ transform: scale(1.05);
82
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
83
+ }
84
+
85
+ .thumbnail--clickable:focus {
86
+ outline: 2px solid var(--primary-color, #2196f3);
87
+ outline-offset: 2px;
88
+ }
89
+
90
+ .thumbnail--disabled {
91
+ opacity: 0.6;
92
+ cursor: not-allowed;
93
+ pointer-events: none;
94
+ }
95
+
96
+ .thumbnail--loading {
97
+ background-color: var(--background-color-light, #f5f5f5);
98
+ }
99
+
100
+ .thumbnail--error {
101
+ background-color: var(--error-color-light, #ffebee);
102
+ }
103
+
104
+ .thumbnail--loaded .thumbnail__image {
105
+ opacity: 1;
106
+ }
107
+
108
+ /* Placeholder */
109
+ .thumbnail__placeholder {
110
+ position: absolute;
111
+ top: 0;
112
+ left: 0;
113
+ right: 0;
114
+ bottom: 0;
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ background-color: var(--background-color-light, #f5f5f5);
119
+ color: var(--text-color-light, #666);
120
+ }
121
+
122
+ /* Fallback */
123
+ .thumbnail__fallback {
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ right: 0;
128
+ bottom: 0;
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ background-color: var(--background-color-light, #f5f5f5);
133
+ color: var(--text-color-light, #666);
134
+ }
135
+
136
+ /* Overlay */
137
+ .thumbnail__overlay {
138
+ position: absolute;
139
+ top: 0;
140
+ left: 0;
141
+ right: 0;
142
+ bottom: 0;
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ background-color: rgba(0, 0, 0, 0.5);
147
+ color: white;
148
+ opacity: 0;
149
+ transition: opacity 0.2s ease;
150
+ }
151
+
152
+ .thumbnail:hover .thumbnail__overlay {
153
+ opacity: 1;
154
+ }
155
+
156
+ /* Badge */
157
+ .thumbnail__badge {
158
+ position: absolute;
159
+ top: -8px;
160
+ right: -8px;
161
+ background-color: var(--primary-color, #2196f3);
162
+ color: white;
163
+ border-radius: 50%;
164
+ min-width: 20px;
165
+ height: 20px;
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ font-size: 0.75rem;
170
+ font-weight: 500;
171
+ border: 2px solid white;
172
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
173
+ }
174
+
175
+ /* Loading indicator */
176
+ .thumbnail__loading {
177
+ position: absolute;
178
+ top: 50%;
179
+ left: 50%;
180
+ transform: translate(-50%, -50%);
181
+ color: var(--text-color-light, #666);
182
+ }
183
+
184
+ /* Image transitions */
185
+ .thumbnail__image {
186
+ opacity: 0;
187
+ transition: opacity 0.3s ease;
188
+ }
189
+
190
+ .thumbnail--loaded .thumbnail__image {
191
+ opacity: 1;
192
+ }
193
+
194
+ /* Responsive Design */
195
+ @media (max-width: 768px) {
196
+ .thumbnail--small {
197
+ min-width: 1.5rem;
198
+ max-width: 3rem;
199
+ min-height: 1.5rem;
200
+ max-height: 3rem;
201
+ }
202
+
203
+ .thumbnail--medium {
204
+ min-width: 2rem;
205
+ max-width: 4rem;
206
+ min-height: 2rem;
207
+ max-height: 4rem;
208
+ }
209
+
210
+ .thumbnail--large {
211
+ min-width: 3rem;
212
+ max-width: 6rem;
213
+ min-height: 3rem;
214
+ max-height: 6rem;
215
+ }
216
+
217
+ .thumbnail--xlarge {
218
+ min-width: 4rem;
219
+ max-width: 8rem;
220
+ min-height: 4rem;
221
+ max-height: 8rem;
222
+ }
223
+
224
+ .thumbnail__badge {
225
+ top: -4px;
226
+ right: -4px;
227
+ min-width: 16px;
228
+ height: 16px;
229
+ font-size: 0.7rem;
230
+ }
231
+ }
232
+
233
+ /* Dark Theme Support */
234
+ @media (prefers-color-scheme: dark) {
235
+ .thumbnail--bordered {
236
+ border-color: var(--divider-color-dark, #616161);
237
+ }
238
+
239
+ .thumbnail__placeholder,
240
+ .thumbnail__fallback {
241
+ background-color: var(--background-color-light-dark, #424242);
242
+ color: var(--text-color-light-dark, #cccccc);
243
+ }
244
+
245
+ .thumbnail--loading {
246
+ background-color: var(--background-color-light-dark, #424242);
247
+ }
248
+
249
+ .thumbnail--error {
250
+ background-color: var(--error-color-dark, #d32f2f);
251
+ }
252
+
253
+ .thumbnail__loading {
254
+ color: var(--text-color-light-dark, #cccccc);
255
+ }
256
+ }
257
+
258
+ /* High Contrast Mode */
259
+ @media (prefers-contrast: high) {
260
+ .thumbnail--bordered {
261
+ border-width: 3px;
262
+ border-color: currentColor;
263
+ }
264
+
265
+ .thumbnail--clickable:focus {
266
+ outline-width: 3px;
267
+ }
268
+
269
+ .thumbnail__overlay {
270
+ background-color: rgba(0, 0, 0, 0.8);
271
+ }
272
+ }
273
+
274
+ /* Reduced Motion */
275
+ @media (prefers-reduced-motion: reduce) {
276
+ .thumbnail,
277
+ .thumbnail__image,
278
+ .thumbnail__overlay {
279
+ transition: none;
280
+ }
281
+
282
+ .thumbnail--clickable:hover {
283
+ transform: none;
284
+ }
285
+ }
286
+
287
+ /* Print Styles */
288
+ @media print {
289
+ .thumbnail {
290
+ break-inside: avoid;
291
+ box-shadow: none !important;
292
+ border: 1px solid black !important;
293
+ }
294
+
295
+ .thumbnail__overlay,
296
+ .thumbnail__badge {
297
+ display: none !important;
298
+ }
299
+
300
+ .thumbnail__image {
301
+ opacity: 1 !important;
302
+ }
16
303
  }
@@ -1,22 +1,227 @@
1
- import React from 'react'
1
+ import React, { useState, useCallback, useRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { Icon } from './icon'
2
4
  import './thumbnail.css'
3
5
 
4
6
  /**
5
- * Thumbnail
7
+ * Enhanced Thumbnail component with improved functionality while maintaining 100% compatibility
6
8
  */
7
9
  export const Thumbnail = (props) => {
8
-
9
10
  const {
11
+ // Original props (100% compatible)
10
12
  src = "https://www.w3schools.com/howto/img_forest.jpg",
11
13
  empty = "",
12
- objectFit = "cover"
14
+ objectFit = "cover",
15
+ // New enhanced props (all optional for compatibility)
16
+ alt,
17
+ title,
18
+ loading = "lazy",
19
+ placeholder,
20
+ fallback,
21
+ size = "medium",
22
+ shape = "square",
23
+ bordered = false,
24
+ shadow = false,
25
+ clickable = false,
26
+ onClick,
27
+ onLoad,
28
+ onError,
29
+ overlay,
30
+ badge,
31
+ disabled = false,
32
+ className,
33
+ style,
34
+ ...restProps
13
35
  } = props
14
36
 
15
- const image = src ? src : empty
16
- const style = { objectFit }
37
+ const [imageLoaded, setImageLoaded] = useState(false)
38
+ const [imageError, setImageError] = useState(false)
39
+ const [isLoading, setIsLoading] = useState(true)
40
+ const imgRef = useRef(null)
41
+
42
+ // Handle image load
43
+ const handleLoad = useCallback((event) => {
44
+ setImageLoaded(true)
45
+ setIsLoading(false)
46
+ setImageError(false)
47
+ if (onLoad) onLoad(event)
48
+ }, [onLoad])
49
+
50
+ // Handle image error
51
+ const handleError = useCallback((event) => {
52
+ setImageError(true)
53
+ setIsLoading(false)
54
+ setImageLoaded(false)
55
+ if (onError) onError(event)
56
+ }, [onError])
57
+
58
+ // Handle click
59
+ const handleClick = useCallback((event) => {
60
+ if (disabled || !clickable) return
61
+ if (onClick) onClick(event)
62
+ }, [disabled, clickable, onClick])
63
+
64
+ // Generate CSS classes
65
+ const cssClasses = [
66
+ 'thumbnail',
67
+ `thumbnail--${size}`,
68
+ `thumbnail--${shape}`,
69
+ bordered && 'thumbnail--bordered',
70
+ shadow && 'thumbnail--shadow',
71
+ clickable && 'thumbnail--clickable',
72
+ disabled && 'thumbnail--disabled',
73
+ isLoading && 'thumbnail--loading',
74
+ imageError && 'thumbnail--error',
75
+ imageLoaded && 'thumbnail--loaded',
76
+ className
77
+ ].filter(Boolean).join(' ')
78
+
79
+ // Determine image source
80
+ const imageSrc = src ? src : empty
81
+ const showFallback = imageError && (fallback || empty)
82
+ const showPlaceholder = isLoading && placeholder
83
+
84
+ // Generate inline styles (maintaining original logic)
85
+ const inlineStyle = {
86
+ objectFit,
87
+ ...style
88
+ }
89
+
17
90
  return (
18
- <div className="thumbnail" >
19
- <img src={image} style={style} />
91
+ <div
92
+ className={cssClasses}
93
+ style={inlineStyle}
94
+ onClick={handleClick}
95
+ title={title}
96
+ role={clickable ? 'button' : undefined}
97
+ tabIndex={clickable && !disabled ? 0 : undefined}
98
+ aria-disabled={disabled}
99
+ {...restProps}
100
+ >
101
+ {/* Loading placeholder */}
102
+ {showPlaceholder && (
103
+ <div className="thumbnail__placeholder">
104
+ {typeof placeholder === 'string' ? (
105
+ <Icon icon={placeholder} size="medium" />
106
+ ) : (
107
+ placeholder
108
+ )}
109
+ </div>
110
+ )}
111
+
112
+ {/* Main image */}
113
+ {!showFallback && (
114
+ <img
115
+ ref={imgRef}
116
+ src={imageSrc}
117
+ alt={alt || title || "Thumbnail"}
118
+ style={{ objectFit }}
119
+ loading={loading}
120
+ onLoad={handleLoad}
121
+ onError={handleError}
122
+ className="thumbnail__image"
123
+ />
124
+ )}
125
+
126
+ {/* Fallback content */}
127
+ {showFallback && (
128
+ <div className="thumbnail__fallback">
129
+ {typeof fallback === 'string' ? (
130
+ <Icon icon={fallback} size="medium" />
131
+ ) : fallback ? (
132
+ fallback
133
+ ) : (
134
+ <img
135
+ src={empty}
136
+ alt={alt || "Fallback image"}
137
+ style={{ objectFit }}
138
+ className="thumbnail__image"
139
+ />
140
+ )}
141
+ </div>
142
+ )}
143
+
144
+ {/* Overlay */}
145
+ {overlay && (
146
+ <div className="thumbnail__overlay">
147
+ {overlay}
148
+ </div>
149
+ )}
150
+
151
+ {/* Badge */}
152
+ {badge && (
153
+ <div className="thumbnail__badge">
154
+ {badge}
155
+ </div>
156
+ )}
157
+
158
+ {/* Loading indicator */}
159
+ {isLoading && !placeholder && (
160
+ <div className="thumbnail__loading">
161
+ <Icon icon="hourglass_empty" size="small" />
162
+ </div>
163
+ )}
20
164
  </div>
21
165
  )
22
- }
166
+ }
167
+
168
+ // PropTypes
169
+ Thumbnail.propTypes = {
170
+ /** Image source URL */
171
+ src: PropTypes.string,
172
+ /** Empty/fallback image URL */
173
+ empty: PropTypes.string,
174
+ /** CSS object-fit property */
175
+ objectFit: PropTypes.oneOf(['cover', 'contain', 'fill', 'scale-down', 'none']),
176
+ /** Alt text for accessibility */
177
+ alt: PropTypes.string,
178
+ /** Title/tooltip text */
179
+ title: PropTypes.string,
180
+ /** Image loading strategy */
181
+ loading: PropTypes.oneOf(['lazy', 'eager']),
182
+ /** Placeholder content while loading */
183
+ placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
184
+ /** Fallback content on error */
185
+ fallback: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
186
+ /** Thumbnail size */
187
+ size: PropTypes.oneOf(['small', 'medium', 'large', 'xlarge']),
188
+ /** Thumbnail shape */
189
+ shape: PropTypes.oneOf(['square', 'circle', 'rounded']),
190
+ /** Show border */
191
+ bordered: PropTypes.bool,
192
+ /** Show shadow */
193
+ shadow: PropTypes.bool,
194
+ /** Make clickable */
195
+ clickable: PropTypes.bool,
196
+ /** Click handler */
197
+ onClick: PropTypes.func,
198
+ /** Load handler */
199
+ onLoad: PropTypes.func,
200
+ /** Error handler */
201
+ onError: PropTypes.func,
202
+ /** Overlay content */
203
+ overlay: PropTypes.node,
204
+ /** Badge content */
205
+ badge: PropTypes.node,
206
+ /** Disabled state */
207
+ disabled: PropTypes.bool,
208
+ /** Additional CSS classes */
209
+ className: PropTypes.string,
210
+ /** Inline styles */
211
+ style: PropTypes.object
212
+ }
213
+
214
+ Thumbnail.defaultProps = {
215
+ src: "https://www.w3schools.com/howto/img_forest.jpg",
216
+ empty: "",
217
+ objectFit: "cover",
218
+ loading: "lazy",
219
+ size: "medium",
220
+ shape: "square",
221
+ bordered: false,
222
+ shadow: false,
223
+ clickable: false,
224
+ disabled: false
225
+ }
226
+
227
+ export default Thumbnail