@duro-app/ui 0.34.3 → 0.34.5
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/components/Table/Table.d.ts +12 -2
- package/dist/components/Table/Table.d.ts.map +1 -1
- package/dist/components/Table/styles.css.d.ts +2 -3
- package/dist/components/Table/styles.css.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.js +43 -40
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Table/Table.tsx +32 -6
- package/src/components/Table/styles.css.ts +30 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duro-app/ui",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@duro-app/tokens": "^0.34.
|
|
56
|
+
"@duro-app/tokens": "^0.34.5"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@babel/preset-typescript": "^7.28.0",
|
|
@@ -107,8 +107,13 @@ function unwrapElementType(t: unknown): unknown {
|
|
|
107
107
|
return current
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
function extractColumnMeta(children: ReactNode): {
|
|
110
|
+
function extractColumnMeta(children: ReactNode): {
|
|
111
|
+
template: string
|
|
112
|
+
compactTemplate: string
|
|
113
|
+
labels: string[]
|
|
114
|
+
} {
|
|
111
115
|
const widths: string[] = []
|
|
116
|
+
const compactWidths: string[] = []
|
|
112
117
|
const labels: string[] = []
|
|
113
118
|
|
|
114
119
|
function walk(node: ReactNode) {
|
|
@@ -128,7 +133,13 @@ function extractColumnMeta(children: ReactNode): {template: string; labels: stri
|
|
|
128
133
|
// cell's text is wider than 1/N of the container. With minmax(0,
|
|
129
134
|
// 1fr), the cell's compact-mode `min-width: 0` + `overflow:
|
|
130
135
|
// hidden` + `text-overflow: ellipsis` can actually truncate.
|
|
131
|
-
|
|
136
|
+
const width = props.width || 'minmax(0, 1fr)'
|
|
137
|
+
widths.push(width)
|
|
138
|
+
// `compactWidth` lets the consumer switch to a content-aware
|
|
139
|
+
// layout in the compact band while staying evenly distributed
|
|
140
|
+
// at desktop. Falls back to `width` so columns that don't opt
|
|
141
|
+
// in keep one template across both breakpoints.
|
|
142
|
+
compactWidths.push(props.compactWidth || width)
|
|
132
143
|
const explicit = typeof props.label === 'string' ? props.label : undefined
|
|
133
144
|
const fallback = extractText(props.children).trim()
|
|
134
145
|
const label = explicit ?? fallback
|
|
@@ -148,7 +159,11 @@ function extractColumnMeta(children: ReactNode): {template: string; labels: stri
|
|
|
148
159
|
}
|
|
149
160
|
|
|
150
161
|
walk(children)
|
|
151
|
-
return {
|
|
162
|
+
return {
|
|
163
|
+
template: widths.join(' '),
|
|
164
|
+
compactTemplate: compactWidths.join(' '),
|
|
165
|
+
labels,
|
|
166
|
+
}
|
|
152
167
|
}
|
|
153
168
|
|
|
154
169
|
// --- Root ---
|
|
@@ -181,7 +196,7 @@ export function Root({
|
|
|
181
196
|
pagination,
|
|
182
197
|
}: RootProps) {
|
|
183
198
|
const inferredTemplateRef = useRef<string | null>(null)
|
|
184
|
-
const {template, labels} = extractColumnMeta(children)
|
|
199
|
+
const {template, compactTemplate, labels} = extractColumnMeta(children)
|
|
185
200
|
if (template) {
|
|
186
201
|
inferredTemplateRef.current = template
|
|
187
202
|
}
|
|
@@ -199,7 +214,7 @@ export function Root({
|
|
|
199
214
|
// always wins as the later entry in the array.
|
|
200
215
|
template
|
|
201
216
|
? responsive
|
|
202
|
-
? styles.gridColumnsResponsive(template)
|
|
217
|
+
? styles.gridColumnsResponsive(template, compactTemplate)
|
|
203
218
|
: styles.gridColumns(template)
|
|
204
219
|
: undefined,
|
|
205
220
|
responsive && styles.rootResponsive,
|
|
@@ -362,13 +377,24 @@ const CellIndexContext = createContext<{index: number; total: number}>({index: 0
|
|
|
362
377
|
export function HeaderCell({
|
|
363
378
|
children,
|
|
364
379
|
width: _width,
|
|
380
|
+
compactWidth: _compactWidth,
|
|
365
381
|
label: _label,
|
|
366
382
|
isActions,
|
|
367
383
|
'aria-label': ariaLabel,
|
|
368
384
|
}: {
|
|
369
385
|
children?: ReactNode
|
|
370
|
-
/** Column width
|
|
386
|
+
/** Column width at default (wide) viewport. CSS grid-template-columns
|
|
387
|
+
* track value — e.g. '40px', '2fr', 'max-content'. Defaults to
|
|
388
|
+
* 'minmax(0, 1fr)' so each column shares the row evenly and is free
|
|
389
|
+
* to shrink below its content's intrinsic size. */
|
|
371
390
|
width?: string
|
|
391
|
+
/** Column width when the table's container drops into compact mode
|
|
392
|
+
* (≤720px container). Use this to switch to a content-aware layout
|
|
393
|
+
* at narrow widths — e.g. give a status badge `max-content` and the
|
|
394
|
+
* action column `minmax(0, 2fr)` so it absorbs the slack — while
|
|
395
|
+
* keeping evenly-distributed columns on wide screens. Defaults to the
|
|
396
|
+
* same value as `width`. */
|
|
397
|
+
compactWidth?: string
|
|
372
398
|
/** Stack-mode label string. Optional when children is a plain string — the
|
|
373
399
|
* text content is used as the label automatically. Required when children
|
|
374
400
|
* contain JSX (icon + text, sort indicator, etc.). */
|
|
@@ -159,8 +159,15 @@ export const styles = css.create({
|
|
|
159
159
|
},
|
|
160
160
|
},
|
|
161
161
|
|
|
162
|
-
// Body cell.
|
|
163
|
-
//
|
|
162
|
+
// Body cell. Text wraps by default — preferring "wrap to a 2nd line" over
|
|
163
|
+
// "truncate with ellipsis" matches BI/data-reporting conventions where
|
|
164
|
+
// hiding content (even with a visual hint) is treated as data loss.
|
|
165
|
+
// Consumers that explicitly want single-line truncation use Text's
|
|
166
|
+
// `truncate` prop, which sets its own nowrap + overflow + ellipsis chain
|
|
167
|
+
// on the Text element itself. Buttons and badges already enforce
|
|
168
|
+
// `white-space: nowrap` internally, so they're unaffected by this
|
|
169
|
+
// default. In stack mode the cell becomes a 2-column grid for
|
|
170
|
+
// label / value.
|
|
164
171
|
cell: {
|
|
165
172
|
color: colors.text,
|
|
166
173
|
display: {
|
|
@@ -169,22 +176,20 @@ export const styles = css.create({
|
|
|
169
176
|
},
|
|
170
177
|
alignItems: 'center',
|
|
171
178
|
minWidth: {
|
|
179
|
+
// Allow the cell to shrink inside its grid track. In default (wide)
|
|
180
|
+
// mode there's enough room so `auto` is fine; in compact and stack
|
|
181
|
+
// we explicitly drop to 0 so wrappable content can size to the
|
|
182
|
+
// track instead of forcing the track to grow.
|
|
172
183
|
default: 'auto',
|
|
173
184
|
[`@container (max-width: ${COMPACT_BP})`]: 0,
|
|
174
185
|
},
|
|
175
186
|
overflow: {
|
|
187
|
+
// Safety against pathological unbreakable content (long URLs,
|
|
188
|
+
// dataless ids) at narrow widths.
|
|
176
189
|
default: 'visible',
|
|
177
190
|
[`@container (max-width: ${COMPACT_BP})`]: 'hidden',
|
|
178
191
|
},
|
|
179
|
-
|
|
180
|
-
default: 'clip',
|
|
181
|
-
[`@container (max-width: ${COMPACT_BP})`]: 'ellipsis',
|
|
182
|
-
},
|
|
183
|
-
whiteSpace: {
|
|
184
|
-
default: 'normal',
|
|
185
|
-
[`@container (max-width: ${COMPACT_BP})`]: 'nowrap',
|
|
186
|
-
[`@container (max-width: ${STACK_BP})`]: 'normal',
|
|
187
|
-
},
|
|
192
|
+
whiteSpace: 'normal',
|
|
188
193
|
gridTemplateColumns: {
|
|
189
194
|
default: null,
|
|
190
195
|
[`@container (max-width: ${STACK_BP})`]: '1fr 2fr',
|
|
@@ -303,15 +308,22 @@ export const styles = css.create({
|
|
|
303
308
|
gridTemplateColumns: template,
|
|
304
309
|
}),
|
|
305
310
|
|
|
306
|
-
// Dynamic: grid columns
|
|
307
|
-
// Used instead of gridColumns() when responsive=true so that
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
|
|
311
|
+
// Dynamic: grid columns at three tiers (default / compact / stack) in
|
|
312
|
+
// one style. Used instead of gridColumns() when responsive=true so that
|
|
313
|
+
// every gridTemplateColumns rule lives in the same StyleX style object —
|
|
314
|
+
// splitting them would let StyleX's conflict resolution drop the
|
|
315
|
+
// earlier classes (the LAST style wins per property key).
|
|
316
|
+
//
|
|
317
|
+
// - default: balanced multi-column layout for desktop widths
|
|
318
|
+
// - @container (max-width: COMPACT_BP): consumer-supplied "compact"
|
|
319
|
+
// template, e.g. give a badge column max-content and let the action
|
|
320
|
+
// column absorb the slack so its hint text fits on one line
|
|
321
|
+
// - @container (max-width: STACK_BP): collapse to a single column so
|
|
322
|
+
// each row becomes a card
|
|
323
|
+
gridColumnsResponsive: (template: string, compactTemplate: string) => ({
|
|
313
324
|
gridTemplateColumns: {
|
|
314
325
|
default: template,
|
|
326
|
+
[`@container (max-width: ${COMPACT_BP})`]: compactTemplate,
|
|
315
327
|
[`@container (max-width: ${STACK_BP})`]: '1fr',
|
|
316
328
|
},
|
|
317
329
|
}),
|