@fpkit/acss 3.4.0 → 3.5.0
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/libs/index.cjs +2 -2
- package/libs/index.cjs.map +1 -1
- package/libs/index.d.cts +40 -6
- package/libs/index.d.ts +40 -6
- package/libs/index.js +2 -2
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/col/README.mdx +138 -9
- package/src/components/col/col.stories.tsx +105 -2
- package/src/components/col/col.test.tsx +45 -0
- package/src/components/col/col.tsx +3 -1
- package/src/components/col/col.types.ts +18 -4
- package/src/sass/_columns.scss +274 -78
- package/src/styles/index.css +56 -4
- package/src/styles/index.css.map +1 -1
- package/src/types/layout-primitives.ts +22 -2
- package/libs/components/alert/alert.css +0 -1
- package/libs/components/alert/alert.css.map +0 -1
- package/libs/components/alert/alert.min.css +0 -3
- package/libs/components/alert/alert.min.min.css +0 -2
- package/libs/components/badge/badge.css +0 -1
- package/libs/components/badge/badge.css.map +0 -1
- package/libs/components/badge/badge.min.css +0 -3
- package/libs/components/badge/badge.min.min.css +0 -2
- package/libs/components/box/box.css +0 -1
- package/libs/components/box/box.css.map +0 -1
- package/libs/components/box/box.min.css +0 -3
- package/libs/components/box/box.min.min.css +0 -2
- package/libs/components/breadcrumbs/breadcrumb.css +0 -1
- package/libs/components/breadcrumbs/breadcrumb.css.map +0 -1
- package/libs/components/breadcrumbs/breadcrumb.min.css +0 -3
- package/libs/components/breadcrumbs/breadcrumb.min.min.css +0 -2
- package/libs/components/buttons/button.css +0 -1
- package/libs/components/buttons/button.css.map +0 -1
- package/libs/components/buttons/button.min.css +0 -3
- package/libs/components/buttons/button.min.min.css +0 -2
- package/libs/components/cards/card-style.css +0 -1
- package/libs/components/cards/card-style.css.map +0 -1
- package/libs/components/cards/card-style.min.css +0 -3
- package/libs/components/cards/card-style.min.min.css +0 -2
- package/libs/components/cards/card.css +0 -1
- package/libs/components/cards/card.css.map +0 -1
- package/libs/components/cards/card.min.css +0 -3
- package/libs/components/cards/card.min.min.css +0 -2
- package/libs/components/cluster/cluster.css +0 -1
- package/libs/components/cluster/cluster.css.map +0 -1
- package/libs/components/cluster/cluster.min.css +0 -3
- package/libs/components/cluster/cluster.min.min.css +0 -2
- package/libs/components/details/details.css +0 -1
- package/libs/components/details/details.css.map +0 -1
- package/libs/components/details/details.min.css +0 -3
- package/libs/components/details/details.min.min.css +0 -2
- package/libs/components/dialog/dialog.css +0 -1
- package/libs/components/dialog/dialog.css.map +0 -1
- package/libs/components/dialog/dialog.min.css +0 -3
- package/libs/components/dialog/dialog.min.min.css +0 -2
- package/libs/components/flexbox/flex.css +0 -1
- package/libs/components/flexbox/flex.css.map +0 -1
- package/libs/components/flexbox/flex.min.css +0 -3
- package/libs/components/flexbox/flex.min.min.css +0 -2
- package/libs/components/form/form.css +0 -1
- package/libs/components/form/form.css.map +0 -1
- package/libs/components/form/form.min.css +0 -3
- package/libs/components/form/form.min.min.css +0 -2
- package/libs/components/grid/grid.css +0 -1
- package/libs/components/grid/grid.css.map +0 -1
- package/libs/components/grid/grid.min.css +0 -3
- package/libs/components/grid/grid.min.min.css +0 -2
- package/libs/components/icons/icon.css +0 -1
- package/libs/components/icons/icon.css.map +0 -1
- package/libs/components/icons/icon.min.css +0 -3
- package/libs/components/icons/icon.min.min.css +0 -2
- package/libs/components/images/img.css +0 -1
- package/libs/components/images/img.css.map +0 -1
- package/libs/components/images/img.min.css +0 -3
- package/libs/components/images/img.min.min.css +0 -2
- package/libs/components/layout/landmarks.css +0 -1
- package/libs/components/layout/landmarks.css.map +0 -1
- package/libs/components/layout/landmarks.min.css +0 -3
- package/libs/components/layout/landmarks.min.min.css +0 -2
- package/libs/components/link/link.css +0 -1
- package/libs/components/link/link.css.map +0 -1
- package/libs/components/link/link.min.css +0 -3
- package/libs/components/link/link.min.min.css +0 -2
- package/libs/components/list/list.css +0 -1
- package/libs/components/list/list.css.map +0 -1
- package/libs/components/list/list.min.css +0 -3
- package/libs/components/list/list.min.min.css +0 -2
- package/libs/components/nav/nav.css +0 -1
- package/libs/components/nav/nav.css.map +0 -1
- package/libs/components/nav/nav.min.css +0 -3
- package/libs/components/nav/nav.min.min.css +0 -2
- package/libs/components/progress/progress.css +0 -1
- package/libs/components/progress/progress.css.map +0 -1
- package/libs/components/progress/progress.min.css +0 -3
- package/libs/components/progress/progress.min.min.css +0 -2
- package/libs/components/stack/stack.css +0 -1
- package/libs/components/stack/stack.css.map +0 -1
- package/libs/components/stack/stack.min.css +0 -3
- package/libs/components/stack/stack.min.min.css +0 -2
- package/libs/components/styles/index.css +0 -1
- package/libs/components/styles/index.css.map +0 -1
- package/libs/components/styles/index.min.css +0 -3
- package/libs/components/styles/index.min.min.css +0 -2
- package/libs/components/tag/tag.css +0 -1
- package/libs/components/tag/tag.css.map +0 -1
- package/libs/components/tag/tag.min.css +0 -3
- package/libs/components/tag/tag.min.min.css +0 -2
- package/libs/components/text-to-speech/text-to-speech.css +0 -1
- package/libs/components/text-to-speech/text-to-speech.css.map +0 -1
- package/libs/components/text-to-speech/text-to-speech.min.css +0 -3
- package/libs/components/text-to-speech/text-to-speech.min.min.css +0 -2
- package/libs/index.css +0 -1
- package/libs/index.css.map +0 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@fpkit/acss",
|
|
3
3
|
"description": "A lightweight React UI library for building modern and accessible components that leverage CSS custom properties for reactive Styles.",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.5.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=22.12.0",
|
|
8
8
|
"npm": ">=8.0.0"
|
|
@@ -126,5 +126,5 @@
|
|
|
126
126
|
"publishConfig": {
|
|
127
127
|
"access": "public"
|
|
128
128
|
},
|
|
129
|
-
"gitHead": "
|
|
129
|
+
"gitHead": "1fafc2d670435f58f0d1bc930d7c44e4454f31b2"
|
|
130
130
|
}
|
|
@@ -20,6 +20,7 @@ utility class composition following the Grid.Item pattern.
|
|
|
20
20
|
|
|
21
21
|
- **No Base Class**: Pure utility class mapping for maximum flexibility
|
|
22
22
|
- **Span Control**: 1-12 column widths via the `span` prop
|
|
23
|
+
- **Flex-Grow Columns**: Fill remaining space with `span="flex"`
|
|
23
24
|
- **Offset Positioning**: Push columns right with `offset` prop
|
|
24
25
|
- **Visual Reordering**: Change display order with `order` prop
|
|
25
26
|
- **Auto-Width**: Content-based width with `auto` prop
|
|
@@ -40,20 +41,27 @@ Use Col when you need:
|
|
|
40
41
|
|
|
41
42
|
### span
|
|
42
43
|
|
|
43
|
-
Column span (width) from 1-12 columns
|
|
44
|
+
Column span (width) from 1-12 columns, or "flex" for flex-grow behavior. Ignored
|
|
45
|
+
if `auto` is true.
|
|
44
46
|
|
|
45
|
-
- **Type**: `1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12`
|
|
47
|
+
- **Type**: `1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | "flex"`
|
|
46
48
|
- **Default**: `undefined`
|
|
47
|
-
- **CSS Class**: `.col-{span}`
|
|
48
|
-
- **Calculation**: `span / 12 * 100%`
|
|
49
|
+
- **CSS Class**: `.col-{span}` or `.col-flex`
|
|
50
|
+
- **Calculation**: `span / 12 * 100%` (for numeric values)
|
|
49
51
|
|
|
50
|
-
**Examples:**
|
|
52
|
+
**Numeric Examples:**
|
|
51
53
|
|
|
52
54
|
- `span={12}` = 100% width (`.col-12`)
|
|
53
55
|
- `span={6}` = 50% width (`.col-6`)
|
|
54
56
|
- `span={4}` = 33.33% width (`.col-4`)
|
|
55
57
|
- `span={3}` = 25% width (`.col-3`)
|
|
56
58
|
|
|
59
|
+
**Flex Example:**
|
|
60
|
+
|
|
61
|
+
- `span="flex"` = Grows to fill remaining space (`.col-flex`)
|
|
62
|
+
- Desktop: `flex: 1 1 0%` (grows to fill available space)
|
|
63
|
+
- Mobile: Stacks to 100% width like other columns
|
|
64
|
+
|
|
57
65
|
### offset
|
|
58
66
|
|
|
59
67
|
Column offset (left margin) from 0-11 columns. Pushes column to the right.
|
|
@@ -85,7 +93,8 @@ Visual display order using flexbox `order` property. Does not change DOM order.
|
|
|
85
93
|
|
|
86
94
|
### auto
|
|
87
95
|
|
|
88
|
-
Auto-width column based on content. Takes precedence over `span
|
|
96
|
+
Auto-width column based on content. Takes precedence over `span` (including
|
|
97
|
+
`span="flex"`).
|
|
89
98
|
|
|
90
99
|
- **Type**: `boolean`
|
|
91
100
|
- **Default**: `false`
|
|
@@ -94,6 +103,9 @@ Auto-width column based on content. Takes precedence over `span`.
|
|
|
94
103
|
When `true`, column width adjusts to fit content instead of spanning a fixed
|
|
95
104
|
number of columns.
|
|
96
105
|
|
|
106
|
+
**Note**: For columns that grow to fill remaining space (not content-based), use
|
|
107
|
+
`span="flex"` instead of `auto`.
|
|
108
|
+
|
|
97
109
|
### as
|
|
98
110
|
|
|
99
111
|
Element type to render. Supports semantic HTML elements.
|
|
@@ -208,11 +220,81 @@ function MyLayout() {
|
|
|
208
220
|
<Row gap="md">
|
|
209
221
|
{/* Mix fixed and auto */}
|
|
210
222
|
<Col span={3}>Fixed 25%</Col>
|
|
211
|
-
<Col auto>Auto (
|
|
223
|
+
<Col auto>Auto width (content-based)</Col>
|
|
212
224
|
<Col span={2}>Fixed 16.66%</Col>
|
|
213
225
|
</Row>
|
|
214
226
|
```
|
|
215
227
|
|
|
228
|
+
### Flex Columns (Fill Remaining Space)
|
|
229
|
+
|
|
230
|
+
Use `span="flex"` to create columns that grow to fill available space after
|
|
231
|
+
fixed-width columns. This is different from `auto` which sizes to content.
|
|
232
|
+
|
|
233
|
+
```jsx
|
|
234
|
+
{/* Flex vs Auto Comparison */}
|
|
235
|
+
<Row gap="md">
|
|
236
|
+
<Col span={3}>Fixed 25%</Col>
|
|
237
|
+
<Col span="flex">Flex (grows to fill 75%)</Col>
|
|
238
|
+
</Row>
|
|
239
|
+
|
|
240
|
+
<Row gap="md">
|
|
241
|
+
<Col span={3}>Fixed 25%</Col>
|
|
242
|
+
<Col auto>Auto (sizes to content only)</Col>
|
|
243
|
+
</Row>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Multiple flex columns share space equally:**
|
|
247
|
+
|
|
248
|
+
```jsx
|
|
249
|
+
<Row gap="md">
|
|
250
|
+
<Col span={2}>Fixed sidebar</Col>
|
|
251
|
+
<Col span="flex">Section 1 (50% of remaining)</Col>
|
|
252
|
+
<Col span="flex">Section 2 (50% of remaining)</Col>
|
|
253
|
+
</Row>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Common Patterns:**
|
|
257
|
+
|
|
258
|
+
```jsx
|
|
259
|
+
{/* Sidebar layout */}
|
|
260
|
+
<Row gap="lg">
|
|
261
|
+
<Col span={3}>Sidebar (25%)</Col>
|
|
262
|
+
<Col span="flex">Main content (grows to fill 75%)</Col>
|
|
263
|
+
</Row>
|
|
264
|
+
|
|
265
|
+
{/* Button group with spacer */}
|
|
266
|
+
<Row gap="sm" align="center">
|
|
267
|
+
<Col auto><Button>Save</Button></Col>
|
|
268
|
+
<Col span="flex">{/* Flexible spacer */}</Col>
|
|
269
|
+
<Col auto><Button>Cancel</Button></Col>
|
|
270
|
+
</Row>
|
|
271
|
+
|
|
272
|
+
{/* App layout */}
|
|
273
|
+
<Row gap="md">
|
|
274
|
+
<Col span={2}>Navigation</Col>
|
|
275
|
+
<Col span="flex">Main Content</Col>
|
|
276
|
+
<Col span={3}>Sidebar</Col>
|
|
277
|
+
</Row>
|
|
278
|
+
|
|
279
|
+
{/* Form layout with label and input */}
|
|
280
|
+
<Row gap="sm" align="center">
|
|
281
|
+
<Col auto><Label>Email:</Label></Col>
|
|
282
|
+
<Col span="flex"><Input type="email" /></Col>
|
|
283
|
+
<Col auto><Button>Subscribe</Button></Col>
|
|
284
|
+
</Row>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Key Differences:**
|
|
288
|
+
|
|
289
|
+
| Feature | `auto` | `span="flex"` |
|
|
290
|
+
| ----------------- | ---------------------- | --------------------------- |
|
|
291
|
+
| **CSS** | `flex: 0 0 auto` | `flex: 1 1 0%` |
|
|
292
|
+
| **Behavior** | Sizes to content width | Grows to fill space |
|
|
293
|
+
| **Use case** | Buttons, labels, icons | Main content areas |
|
|
294
|
+
| **Mobile** | Content-based | 100% width (stacked) |
|
|
295
|
+
| **Desktop** | Content-based | Fills remaining space |
|
|
296
|
+
| **Multiple cols** | Each sizes to content | Share remaining space equally |
|
|
297
|
+
|
|
216
298
|
### Responsive Columns
|
|
217
299
|
|
|
218
300
|
```jsx
|
|
@@ -487,10 +569,11 @@ Use responsive utility classes on Col for breakpoint-specific widths:
|
|
|
487
569
|
|
|
488
570
|
Col renders with **no base class**. Only utility classes are applied:
|
|
489
571
|
|
|
490
|
-
- Span: `.col-{1-12}`
|
|
572
|
+
- Span: `.col-{1-12}` (fixed width columns)
|
|
573
|
+
- Flex: `.col-flex` (flex-grow column)
|
|
491
574
|
- Offset: `.col-offset-{0-11}`
|
|
492
575
|
- Order: `.col-order-{first|last|0-12}`
|
|
493
|
-
- Auto: `.col-auto`
|
|
576
|
+
- Auto: `.col-auto` (content-based width)
|
|
494
577
|
|
|
495
578
|
### Column Width Calculation
|
|
496
579
|
|
|
@@ -526,6 +609,52 @@ margin-inline-start = (offset / 12) * 100%
|
|
|
526
609
|
`.col-auto` uses `flex: 0 0 auto` with `width: auto`, allowing the column to
|
|
527
610
|
size based on its content.
|
|
528
611
|
|
|
612
|
+
### Flex-Grow Behavior
|
|
613
|
+
|
|
614
|
+
`.col-flex` uses responsive flex properties to fill remaining space:
|
|
615
|
+
|
|
616
|
+
**Mobile (`< 768px`):**
|
|
617
|
+
|
|
618
|
+
```css
|
|
619
|
+
.col-flex {
|
|
620
|
+
flex: 0 0 100%; /* Stack to full width */
|
|
621
|
+
min-width: 0;
|
|
622
|
+
box-sizing: border-box;
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
**Desktop (`≥ 768px`):**
|
|
627
|
+
|
|
628
|
+
```css
|
|
629
|
+
.col-flex {
|
|
630
|
+
flex: 1 1 0%; /* Grow to fill available space */
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**How it works:**
|
|
635
|
+
|
|
636
|
+
- `flex-grow: 1` - Column grows to fill available space
|
|
637
|
+
- `flex-shrink: 1` - Column can shrink if constrained
|
|
638
|
+
- `flex-basis: 0%` - Ensures equal distribution when multiple flex columns exist
|
|
639
|
+
- Multiple flex columns share remaining space equally
|
|
640
|
+
|
|
641
|
+
**Example calculations:**
|
|
642
|
+
|
|
643
|
+
```jsx
|
|
644
|
+
// Container width: 1200px
|
|
645
|
+
<Row>
|
|
646
|
+
<Col span={3}>Fixed 300px (25%)</Col>
|
|
647
|
+
<Col span="flex">Grows to 900px (75%)</Col>
|
|
648
|
+
</Row>
|
|
649
|
+
|
|
650
|
+
// Multiple flex columns
|
|
651
|
+
<Row>
|
|
652
|
+
<Col span={2}>Fixed 200px (16.67%)</Col>
|
|
653
|
+
<Col span="flex">Flex 1: 500px (41.67%)</Col>
|
|
654
|
+
<Col span="flex">Flex 2: 500px (41.67%)</Col>
|
|
655
|
+
</Row>
|
|
656
|
+
```
|
|
657
|
+
|
|
529
658
|
### Performance
|
|
530
659
|
|
|
531
660
|
Col is a lightweight wrapper with no runtime overhead. All layout calculations
|
|
@@ -18,8 +18,8 @@ const meta: Meta<typeof Col> = {
|
|
|
18
18
|
argTypes: {
|
|
19
19
|
span: {
|
|
20
20
|
control: "select",
|
|
21
|
-
options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
|
22
|
-
description: "Column span (1-12 columns)",
|
|
21
|
+
options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "flex"],
|
|
22
|
+
description: "Column span (1-12 columns) or 'flex' for flex-grow behavior",
|
|
23
23
|
},
|
|
24
24
|
offset: {
|
|
25
25
|
control: "select",
|
|
@@ -422,3 +422,106 @@ export const ResponsiveGrid: Story = {
|
|
|
422
422
|
},
|
|
423
423
|
},
|
|
424
424
|
};
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Flex Column - Demonstrates flex-grow behavior to fill remaining space.
|
|
428
|
+
* Shows how flex columns differ from auto columns and adapt responsively.
|
|
429
|
+
*/
|
|
430
|
+
export const FlexColumn: Story = {
|
|
431
|
+
render: () => (
|
|
432
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
433
|
+
{/* Flex vs Auto comparison */}
|
|
434
|
+
<div>
|
|
435
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Flex vs Auto Comparison</h3>
|
|
436
|
+
<Row>
|
|
437
|
+
<Col span={3} style={colStyle}>
|
|
438
|
+
Fixed (25%)
|
|
439
|
+
</Col>
|
|
440
|
+
<Col span="flex" style={{ ...colStyle, background: "#fef3c7", borderColor: "#f59e0b" }}>
|
|
441
|
+
Flex (grows to fill 75%)
|
|
442
|
+
</Col>
|
|
443
|
+
</Row>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
<div>
|
|
447
|
+
<Row>
|
|
448
|
+
<Col span={3} style={colStyle}>
|
|
449
|
+
Fixed (25%)
|
|
450
|
+
</Col>
|
|
451
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
452
|
+
Auto (sizes to content)
|
|
453
|
+
</Col>
|
|
454
|
+
</Row>
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
{/* Multiple flex columns */}
|
|
458
|
+
<div>
|
|
459
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Multiple Flex Columns (Equal Distribution)</h3>
|
|
460
|
+
<Row>
|
|
461
|
+
<Col span={2} style={colStyle}>
|
|
462
|
+
Fixed col-2
|
|
463
|
+
</Col>
|
|
464
|
+
<Col span="flex" style={{ ...colStyle, background: "#fef3c7", borderColor: "#f59e0b" }}>
|
|
465
|
+
Flex 1
|
|
466
|
+
</Col>
|
|
467
|
+
<Col span="flex" style={{ ...colStyle, background: "#fef3c7", borderColor: "#f59e0b" }}>
|
|
468
|
+
Flex 2
|
|
469
|
+
</Col>
|
|
470
|
+
</Row>
|
|
471
|
+
</div>
|
|
472
|
+
|
|
473
|
+
{/* Flex with auto */}
|
|
474
|
+
<div>
|
|
475
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Flex + Auto Combination</h3>
|
|
476
|
+
<Row>
|
|
477
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
478
|
+
Button
|
|
479
|
+
</Col>
|
|
480
|
+
<Col span="flex" style={{ ...colStyle, background: "#fef3c7", borderColor: "#f59e0b" }}>
|
|
481
|
+
Main Content (fills remaining)
|
|
482
|
+
</Col>
|
|
483
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
484
|
+
Icon
|
|
485
|
+
</Col>
|
|
486
|
+
</Row>
|
|
487
|
+
</div>
|
|
488
|
+
|
|
489
|
+
{/* Complex layout */}
|
|
490
|
+
<div>
|
|
491
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Complex Layout</h3>
|
|
492
|
+
<Row>
|
|
493
|
+
<Col span={2} style={colStyle}>
|
|
494
|
+
Sidebar
|
|
495
|
+
</Col>
|
|
496
|
+
<Col span="flex" style={{ ...colStyle, background: "#fef3c7", borderColor: "#f59e0b" }}>
|
|
497
|
+
Main Content (grows)
|
|
498
|
+
</Col>
|
|
499
|
+
<Col span={3} style={colStyle}>
|
|
500
|
+
Aside
|
|
501
|
+
</Col>
|
|
502
|
+
</Row>
|
|
503
|
+
</div>
|
|
504
|
+
</div>
|
|
505
|
+
),
|
|
506
|
+
play: async ({ canvasElement, step }) => {
|
|
507
|
+
await step("Flex classes are applied correctly", async () => {
|
|
508
|
+
const flexElements = canvasElement.querySelectorAll(".col-flex");
|
|
509
|
+
expect(flexElements.length).toBeGreaterThan(0);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
await step("Flex columns exist alongside fixed columns", async () => {
|
|
513
|
+
const rows = canvasElement.querySelectorAll(".col-row");
|
|
514
|
+
const firstRow = rows[0];
|
|
515
|
+
expect(firstRow.querySelector(".col-3")).toBeInTheDocument();
|
|
516
|
+
expect(firstRow.querySelector(".col-flex")).toBeInTheDocument();
|
|
517
|
+
});
|
|
518
|
+
},
|
|
519
|
+
parameters: {
|
|
520
|
+
docs: {
|
|
521
|
+
description: {
|
|
522
|
+
story:
|
|
523
|
+
"Flex columns use `flex-grow: 1` to fill remaining space after fixed-width columns. Multiple flex columns share space equally. On mobile (<768px), all columns stack to 100% width. Yellow background indicates flex columns, blue indicates fixed/auto columns.",
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
};
|
|
@@ -111,6 +111,51 @@ describe("Col Component", () => {
|
|
|
111
111
|
});
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
describe("Flex Column", () => {
|
|
115
|
+
it("applies col-flex utility class when span is 'flex'", () => {
|
|
116
|
+
const { container } = render(<Col span="flex">Content</Col>);
|
|
117
|
+
const col = container.firstChild as HTMLElement;
|
|
118
|
+
expect(col).toHaveClass("col-flex");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("does not apply numeric col class when span is 'flex'", () => {
|
|
122
|
+
const { container } = render(<Col span="flex">Content</Col>);
|
|
123
|
+
const col = container.firstChild as HTMLElement;
|
|
124
|
+
expect(col.className).not.toMatch(/col-\d+/);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("auto overrides flex when both provided", () => {
|
|
128
|
+
const { container } = render(<Col auto span="flex">Content</Col>);
|
|
129
|
+
const col = container.firstChild as HTMLElement;
|
|
130
|
+
expect(col).toHaveClass("col-auto");
|
|
131
|
+
expect(col).not.toHaveClass("col-flex");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("flex column works with offset", () => {
|
|
135
|
+
const { container } = render(<Col span="flex" offset={2}>Content</Col>);
|
|
136
|
+
const col = container.firstChild as HTMLElement;
|
|
137
|
+
expect(col).toHaveClass("col-flex");
|
|
138
|
+
expect(col).toHaveClass("col-offset-2");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("flex column works with order", () => {
|
|
142
|
+
const { container } = render(<Col span="flex" order="first">Content</Col>);
|
|
143
|
+
const col = container.firstChild as HTMLElement;
|
|
144
|
+
expect(col).toHaveClass("col-flex");
|
|
145
|
+
expect(col).toHaveClass("col-order-first");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("flex column works with combined props", () => {
|
|
149
|
+
const { container } = render(
|
|
150
|
+
<Col span="flex" offset={1} order={2}>Content</Col>
|
|
151
|
+
);
|
|
152
|
+
const col = container.firstChild as HTMLElement;
|
|
153
|
+
expect(col).toHaveClass("col-flex");
|
|
154
|
+
expect(col).toHaveClass("col-offset-1");
|
|
155
|
+
expect(col).toHaveClass("col-order-2");
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
114
159
|
describe("Offset Utilities", () => {
|
|
115
160
|
it("applies col-offset-0 utility class", () => {
|
|
116
161
|
const { container } = render(<Col offset={0}>Content</Col>);
|
|
@@ -70,9 +70,11 @@ export const Col = React.forwardRef<HTMLElement, ColProps>(
|
|
|
70
70
|
// Build utility classes array - NO base class
|
|
71
71
|
const utilityClasses: string[] = [];
|
|
72
72
|
|
|
73
|
-
// Auto takes precedence over span
|
|
73
|
+
// Auto takes precedence over span (including "flex")
|
|
74
74
|
if (auto) {
|
|
75
75
|
utilityClasses.push("col-auto");
|
|
76
|
+
} else if (span === "flex") {
|
|
77
|
+
utilityClasses.push("col-flex");
|
|
76
78
|
} else if (span) {
|
|
77
79
|
utilityClasses.push(`col-${span}`);
|
|
78
80
|
}
|
|
@@ -27,10 +27,22 @@ export interface ColProps
|
|
|
27
27
|
extends Partial<ComponentProps>,
|
|
28
28
|
Omit<React.HTMLAttributes<HTMLElement>, "className"> {
|
|
29
29
|
/**
|
|
30
|
-
* Column span (1-12)
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* Column span (1-12 or "flex")
|
|
31
|
+
*
|
|
32
|
+
* - Numeric values (1-12): Maps to .col-{span} utility class (fixed width)
|
|
33
|
+
* - "flex": Maps to .col-flex utility class (grows to fill space)
|
|
34
|
+
*
|
|
35
|
+
* Ignored if auto is true (auto takes precedence)
|
|
36
|
+
*
|
|
33
37
|
* @default undefined
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Fixed width column
|
|
41
|
+
* <Col span={6}>50% width on desktop</Col>
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Flex column fills remaining space
|
|
45
|
+
* <Col span="flex">Grows to fill available space</Col>
|
|
34
46
|
*/
|
|
35
47
|
span?: ColumnSpan;
|
|
36
48
|
|
|
@@ -53,8 +65,10 @@ export interface ColProps
|
|
|
53
65
|
/**
|
|
54
66
|
* Auto-width column
|
|
55
67
|
* When true, uses .col-auto (content-based width)
|
|
56
|
-
* Takes precedence over span prop
|
|
68
|
+
* Takes precedence over span prop (including "flex")
|
|
57
69
|
* @default false
|
|
70
|
+
*
|
|
71
|
+
* @see span - For flex-grow behavior, use span="flex" instead of auto
|
|
58
72
|
*/
|
|
59
73
|
auto?: boolean;
|
|
60
74
|
|