ywana-core8 0.1.80 → 0.1.82

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ywana-core8",
3
- "version": "0.1.80",
3
+ "version": "0.1.82",
4
4
  "description": "ywana-core8",
5
5
  "homepage": "https://ywana.github.io/workspace",
6
6
  "author": "Ernesto Roldan Garcia",
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState, useCallback } from 'react'
1
+ import React, { useEffect, useState, useCallback, useMemo } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { Icon } from './icon'
4
4
  import { Text } from './text'
@@ -88,6 +88,24 @@ export const Button = (props) => {
88
88
  'aria-describedby': tooltip ? `${id}-tooltip` : undefined
89
89
  }
90
90
 
91
+ // Label text - support both string and React components
92
+ const labelElement = useMemo(() => {
93
+ if (!label) return null
94
+
95
+ // If label is already a React element, use it directly
96
+ if (React.isValidElement(label)) {
97
+ return label
98
+ }
99
+
100
+ // If label is a string, wrap it in Text component
101
+ if (typeof label === 'string') {
102
+ return <Text>{label}</Text>
103
+ }
104
+
105
+ // Fallback for other types (convert to string)
106
+ return <Text>{String(label)}</Text>
107
+ }, [label])
108
+
91
109
  // Icon configuration
92
110
  const iconProps = {
93
111
  icon: loading ? 'hourglass_empty' : icon,
@@ -111,7 +129,7 @@ export const Button = (props) => {
111
129
  {...restProps}
112
130
  >
113
131
  {(icon || loading) && <Icon {...iconProps} />}
114
- {label && <Text>{label}</Text>}
132
+ {labelElement}
115
133
  {loading && !icon && <span className="loading-text">Loading...</span>}
116
134
  </button>
117
135
  )
@@ -207,8 +225,8 @@ export const ActionButton = (props) => {
207
225
  Button.propTypes = {
208
226
  /** Unique identifier for the button */
209
227
  id: PropTypes.string,
210
- /** Button text label */
211
- label: PropTypes.string,
228
+ /** Button text label - can be string or React element */
229
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
212
230
  /** Icon name for Material Icons */
213
231
  icon: PropTypes.string,
214
232
  /** Click handler function */
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { Icon } from './icon';
3
3
  import { Text } from './text';
4
4
  import './header.css';
@@ -18,11 +18,28 @@ export const Header = (props) => {
18
18
 
19
19
  const style = props.img ? { backgroundImage: `url(${props.img })` } : {}
20
20
 
21
- const title=<Text>{props.title}</Text>
21
+ // Title element - support both string and React components
22
+ const titleElement = useMemo(() => {
23
+ if (!props.title) return null
24
+
25
+ // If title is already a React element, use it directly
26
+ if (React.isValidElement(props.title)) {
27
+ return props.title
28
+ }
29
+
30
+ // If title is a string, wrap it in Text component
31
+ if (typeof props.title === 'string') {
32
+ return <Text>{props.title}</Text>
33
+ }
34
+
35
+ // Fallback for other types (convert to string)
36
+ return <Text>{String(props.title)}</Text>
37
+ }, [props.title])
38
+
22
39
  return (
23
40
  <header className={`header ${caption} ${prominent} ${dense} ${theme} ${props.className}`} style={style}>
24
41
  {icon}
25
- {props.title ? <label>{title}</label> : null }
42
+ {props.title ? <label>{titleElement}</label> : null }
26
43
  <span className="actions">{props.children}</span>
27
44
  </header>
28
45
  )
package/src/html/list.css CHANGED
@@ -10,7 +10,6 @@
10
10
  }
11
11
 
12
12
  .list>header {
13
- padding: .5rem 0 0 1.5rem;
14
13
  color: var(--text-color-light);
15
14
  text-transform: capitalize;
16
15
  font-size: .8rem;
@@ -20,10 +19,10 @@
20
19
  overflow: auto;
21
20
  list-style: none;
22
21
  margin: 0;
23
- padding: 0.5rem 0;
24
22
  cursor: pointer;
25
23
  display: flex;
26
24
  flex-direction: column;
25
+ padding: 0;
27
26
  }
28
27
 
29
28
  .list.grouped>ul {
@@ -100,17 +99,25 @@
100
99
  /* Search functionality */
101
100
  .list__search {
102
101
  padding: 1rem;
103
- border-bottom: 1px solid var(--divider-color, #e0e0e0);
104
102
  background-color: var(--background-color-light, #fafafa);
105
103
  }
106
104
 
105
+ /* Outlined variant - search with border */
106
+ .list--outlined .list__search {
107
+ border-bottom: 1px solid var(--divider-color, #e0e0e0);
108
+ }
109
+
107
110
  /* Sort functionality */
108
111
  .list__sort {
109
112
  padding: 0.5rem 1rem;
110
- border-bottom: 1px solid var(--divider-color, #e0e0e0);
111
113
  background-color: var(--background-color-light, #fafafa);
112
114
  }
113
115
 
116
+ /* Outlined variant - sort with border */
117
+ .list--outlined .list__sort {
118
+ border-bottom: 1px solid var(--divider-color, #e0e0e0);
119
+ }
120
+
114
121
  .list__sort-button {
115
122
  display: flex;
116
123
  align-items: center;
@@ -163,25 +170,28 @@
163
170
  align-items: center;
164
171
  padding: 0.75rem;
165
172
  cursor: pointer;
166
- border-bottom: solid 1px var(--divider-color, #e0e0e0);
167
173
  transition: background-color 0.2s ease, transform 0.1s ease;
168
174
  outline: none;
169
175
  position: relative;
170
176
  }
171
177
 
178
+ /* Outlined variant - items with borders */
179
+ .list--outlined .list__item {
180
+ border-bottom: solid 1px var(--divider-color, #e0e0e0);
181
+ }
182
+
172
183
  .list--dense .list__item {
173
184
  padding: 0.5rem 0.75rem;
174
185
  }
175
186
 
176
187
  .list__item:focus {
177
188
  background-color: var(--focus-color, rgba(0, 0, 0, 0.08));
178
- outline: 2px solid var(--primary-color, #2196f3);
179
189
  outline-offset: -2px;
180
190
  }
181
191
 
182
192
  .list__item--selected {
183
193
  background-color: var(--primary-color-lighter, #e3f2fd);
184
- border-left: 4px solid var(--primary-color, #2196f3);
194
+ border-left: .1rem solid var(--primary-color, #2196f3);
185
195
  }
186
196
 
187
197
  .list__item--disabled {
@@ -313,7 +323,6 @@
313
323
  align-items: center;
314
324
  padding: 0.5rem 0.75rem;
315
325
  background-color: var(--background-color-light, #fafafa);
316
- border-bottom: solid 1px var(--divider-color, #e0e0e0);
317
326
  font-weight: 600;
318
327
  color: var(--text-color-light, #666);
319
328
  cursor: pointer;
@@ -321,6 +330,11 @@
321
330
  outline: none;
322
331
  }
323
332
 
333
+ /* Outlined variant - group headers with border */
334
+ .list--outlined .list__group-header {
335
+ border-bottom: solid 1px var(--divider-color, #e0e0e0);
336
+ }
337
+
324
338
  .list__group-header:hover {
325
339
  background-color: var(--hover-color, rgba(0, 0, 0, 0.04));
326
340
  }
@@ -412,7 +426,7 @@
412
426
 
413
427
  /* High Contrast Mode */
414
428
  @media (prefers-contrast: high) {
415
- .list__item {
429
+ .list--outlined .list__item {
416
430
  border-bottom-width: 2px;
417
431
  }
418
432
 
@@ -455,10 +469,13 @@
455
469
 
456
470
  .list__item {
457
471
  break-inside: avoid;
458
- border-bottom: 1px solid black !important;
459
472
  background: white !important;
460
473
  }
461
474
 
475
+ .list--outlined .list__item {
476
+ border-bottom: 1px solid black !important;
477
+ }
478
+
462
479
  .list__item-line1,
463
480
  .list__item-line2,
464
481
  .list__item-meta {