@fpkit/acss 3.2.1 → 3.4.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/chunk-KAR3HDXK.js +8 -0
- package/libs/chunk-KAR3HDXK.js.map +1 -0
- package/libs/chunk-M5JARVJD.cjs +18 -0
- package/libs/chunk-M5JARVJD.cjs.map +1 -0
- package/libs/components/alert/alert.min.min.css +2 -0
- package/libs/components/badge/badge.min.min.css +2 -0
- package/libs/components/box/box.min.min.css +2 -0
- package/libs/components/breadcrumbs/breadcrumb.min.min.css +2 -0
- package/libs/components/buttons/button.min.min.css +2 -0
- package/libs/components/card.cjs +6 -6
- package/libs/components/card.js +1 -1
- package/libs/components/cards/card-style.min.min.css +2 -0
- package/libs/components/cards/card.min.min.css +2 -0
- package/libs/components/cluster/cluster.min.min.css +2 -0
- package/libs/components/details/details.min.min.css +2 -0
- package/libs/components/dialog/dialog.min.min.css +2 -0
- package/libs/components/flexbox/flex.min.min.css +2 -0
- package/libs/components/form/form.min.min.css +2 -0
- package/libs/components/grid/grid.min.min.css +2 -0
- package/libs/components/icons/icon.min.min.css +2 -0
- package/libs/components/images/img.min.min.css +2 -0
- package/libs/components/layout/landmarks.min.min.css +2 -0
- package/libs/components/link/link.min.min.css +2 -0
- package/libs/components/list/list.min.min.css +2 -0
- package/libs/components/nav/nav.min.min.css +2 -0
- package/libs/components/progress/progress.min.min.css +2 -0
- package/libs/components/stack/stack.min.min.css +2 -0
- package/libs/components/styles/index.min.min.css +2 -0
- package/libs/components/tag/tag.min.min.css +2 -0
- package/libs/components/text-to-speech/text-to-speech.min.min.css +2 -0
- package/libs/index.cjs +27 -25
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +275 -1
- package/libs/index.d.ts +275 -1
- package/libs/index.js +10 -10
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/cards/card.stories.tsx +1 -1
- package/src/components/cards/card.tsx +46 -41
- package/src/components/col/README.mdx +532 -0
- package/src/components/col/col.stories.tsx +424 -0
- package/src/components/col/col.test.tsx +321 -0
- package/src/components/col/col.tsx +105 -0
- package/src/components/col/col.types.ts +76 -0
- package/src/components/row/README.mdx +324 -0
- package/src/components/row/row.stories.tsx +595 -0
- package/src/components/row/row.test.tsx +358 -0
- package/src/components/row/row.tsx +121 -0
- package/src/components/row/row.types.ts +93 -0
- package/src/index.scss +1 -0
- package/src/index.ts +2 -0
- package/src/sass/README.mdx +597 -0
- package/src/sass/_columns.scss +198 -0
- package/src/sass/columns.stories.tsx +456 -0
- package/src/styles/index.css +340 -0
- package/src/styles/index.css.map +1 -1
- package/src/types/layout-primitives.ts +61 -0
- package/libs/chunk-OU52NIKA.js +0 -8
- package/libs/chunk-OU52NIKA.js.map +0 -1
- package/libs/chunk-WWPLBWCQ.cjs +0 -18
- package/libs/chunk-WWPLBWCQ.cjs.map +0 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 12-Column Utility System
|
|
3
|
+
*
|
|
4
|
+
* Layout-agnostic column width utilities following Bootstrap/Foundation patterns.
|
|
5
|
+
* Works with Flex, Grid, or standalone elements.
|
|
6
|
+
*
|
|
7
|
+
* Responsive Behavior:
|
|
8
|
+
* - Mobile (< 48rem): All columns 100% width (stacked)
|
|
9
|
+
* - Desktop (>= 48rem): Fractional percentage widths
|
|
10
|
+
*
|
|
11
|
+
* All units in rem (1rem = 16px base).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/* CSS Custom Properties */
|
|
15
|
+
:root {
|
|
16
|
+
--col-breakpoint: 48rem; /* 768px - matches fpkit md breakpoint */
|
|
17
|
+
|
|
18
|
+
/* Column width percentages (fractions of 12) */
|
|
19
|
+
--col-1: 8.333333%;
|
|
20
|
+
--col-2: 16.666667%;
|
|
21
|
+
--col-3: 25%;
|
|
22
|
+
--col-4: 33.333333%;
|
|
23
|
+
--col-5: 41.666667%;
|
|
24
|
+
--col-6: 50%;
|
|
25
|
+
--col-7: 58.333333%;
|
|
26
|
+
--col-8: 66.666667%;
|
|
27
|
+
--col-9: 75%;
|
|
28
|
+
--col-10: 83.333333%;
|
|
29
|
+
--col-11: 91.666667%;
|
|
30
|
+
--col-12: 100%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ============================================================================
|
|
34
|
+
Row Container Utility (Optional)
|
|
35
|
+
========================================================================== */
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* .col-row provides a convenient flex container for column layouts.
|
|
39
|
+
* Alternative to using the Flex component for simple, standalone usage.
|
|
40
|
+
*
|
|
41
|
+
* Usage:
|
|
42
|
+
* <div className="col-row">
|
|
43
|
+
* <div className="col-6">Column 1</div>
|
|
44
|
+
* <div className="col-6">Column 2</div>
|
|
45
|
+
* </div>
|
|
46
|
+
*/
|
|
47
|
+
.col-row {
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-wrap: wrap;
|
|
50
|
+
gap: var(--spacing-md); /* Default gap - can be overridden with gap utilities */
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* ============================================================================
|
|
54
|
+
Base Column Classes - Mobile First (100% width)
|
|
55
|
+
========================================================================== */
|
|
56
|
+
|
|
57
|
+
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6,
|
|
58
|
+
.col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
|
|
59
|
+
flex: 0 0 100%; /* flex-grow flex-shrink flex-basis */
|
|
60
|
+
min-width: 0; /* Prevent content overflow in flex containers */
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Desktop Column Widths (>= 48rem / 768px) */
|
|
65
|
+
@media (width >= 48rem) {
|
|
66
|
+
/* Prevent wrapping at desktop - columns shrink to fit instead */
|
|
67
|
+
.col-row {
|
|
68
|
+
flex-wrap: nowrap;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.col-1 { flex: 0 1 var(--col-1); }
|
|
72
|
+
.col-2 { flex: 0 1 var(--col-2); }
|
|
73
|
+
.col-3 { flex: 0 1 var(--col-3); }
|
|
74
|
+
.col-4 { flex: 0 1 var(--col-4); }
|
|
75
|
+
.col-5 { flex: 0 1 var(--col-5); }
|
|
76
|
+
.col-6 { flex: 0 1 var(--col-6); }
|
|
77
|
+
.col-7 { flex: 0 1 var(--col-7); }
|
|
78
|
+
.col-8 { flex: 0 1 var(--col-8); }
|
|
79
|
+
.col-9 { flex: 0 1 var(--col-9); }
|
|
80
|
+
.col-10 { flex: 0 1 var(--col-10); }
|
|
81
|
+
.col-11 { flex: 0 1 var(--col-11); }
|
|
82
|
+
.col-12 { flex: 0 1 var(--col-12); }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ============================================================================
|
|
86
|
+
Proportional Layout Mode (Opt-in)
|
|
87
|
+
========================================================================== */
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* .col-row-proportional prevents columns from stacking on tablets and larger.
|
|
91
|
+
* Columns still stack on mobile phones (< 30rem / 480px) for readability,
|
|
92
|
+
* but maintain proportional widths on tablets and desktops (>= 30rem / 480px).
|
|
93
|
+
*
|
|
94
|
+
* Usage with Row component:
|
|
95
|
+
* <Row alwaysProportional>
|
|
96
|
+
* <Col span={6}>Column 1</Col>
|
|
97
|
+
* <Col span={6}>Column 2</Col>
|
|
98
|
+
* </Row>
|
|
99
|
+
*
|
|
100
|
+
* Usage with vanilla HTML:
|
|
101
|
+
* <div className="col-row col-row-proportional">
|
|
102
|
+
* <div className="col-6">Column 1</div>
|
|
103
|
+
* <div className="col-6">Column 2</div>
|
|
104
|
+
* </div>
|
|
105
|
+
*/
|
|
106
|
+
@media (width >= 30rem) {
|
|
107
|
+
.col-row-proportional {
|
|
108
|
+
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6,
|
|
109
|
+
.col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
|
|
110
|
+
flex: 0 1 auto; /* Allow proportional sizing with shrink */
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.col-1 { flex-basis: var(--col-1); }
|
|
114
|
+
.col-2 { flex-basis: var(--col-2); }
|
|
115
|
+
.col-3 { flex-basis: var(--col-3); }
|
|
116
|
+
.col-4 { flex-basis: var(--col-4); }
|
|
117
|
+
.col-5 { flex-basis: var(--col-5); }
|
|
118
|
+
.col-6 { flex-basis: var(--col-6); }
|
|
119
|
+
.col-7 { flex-basis: var(--col-7); }
|
|
120
|
+
.col-8 { flex-basis: var(--col-8); }
|
|
121
|
+
.col-9 { flex-basis: var(--col-9); }
|
|
122
|
+
.col-10 { flex-basis: var(--col-10); }
|
|
123
|
+
.col-11 { flex-basis: var(--col-11); }
|
|
124
|
+
.col-12 { flex-basis: var(--col-12); }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Optional: Column Offset Utilities */
|
|
129
|
+
@media (width >= 48rem) {
|
|
130
|
+
.col-offset-0 { margin-inline-start: 0; }
|
|
131
|
+
.col-offset-1 { margin-inline-start: var(--col-1); }
|
|
132
|
+
.col-offset-2 { margin-inline-start: var(--col-2); }
|
|
133
|
+
.col-offset-3 { margin-inline-start: var(--col-3); }
|
|
134
|
+
.col-offset-4 { margin-inline-start: var(--col-4); }
|
|
135
|
+
.col-offset-5 { margin-inline-start: var(--col-5); }
|
|
136
|
+
.col-offset-6 { margin-inline-start: var(--col-6); }
|
|
137
|
+
.col-offset-7 { margin-inline-start: var(--col-7); }
|
|
138
|
+
.col-offset-8 { margin-inline-start: var(--col-8); }
|
|
139
|
+
.col-offset-9 { margin-inline-start: var(--col-9); }
|
|
140
|
+
.col-offset-10 { margin-inline-start: var(--col-10); }
|
|
141
|
+
.col-offset-11 { margin-inline-start: var(--col-11); }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Optional: Auto-Width Columns */
|
|
145
|
+
.col-auto {
|
|
146
|
+
width: auto;
|
|
147
|
+
flex: 0 0 auto;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Optional: Column Order Utilities */
|
|
151
|
+
@media (width >= 48rem) {
|
|
152
|
+
.col-order-first { order: -1; }
|
|
153
|
+
.col-order-last { order: 13; }
|
|
154
|
+
.col-order-0 { order: 0; }
|
|
155
|
+
.col-order-1 { order: 1; }
|
|
156
|
+
.col-order-2 { order: 2; }
|
|
157
|
+
.col-order-3 { order: 3; }
|
|
158
|
+
.col-order-4 { order: 4; }
|
|
159
|
+
.col-order-5 { order: 5; }
|
|
160
|
+
.col-order-6 { order: 6; }
|
|
161
|
+
.col-order-7 { order: 7; }
|
|
162
|
+
.col-order-8 { order: 8; }
|
|
163
|
+
.col-order-9 { order: 9; }
|
|
164
|
+
.col-order-10 { order: 10; }
|
|
165
|
+
.col-order-11 { order: 11; }
|
|
166
|
+
.col-order-12 { order: 12; }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* ============================================================================
|
|
170
|
+
Row Variant Utilities (for Row React Component)
|
|
171
|
+
========================================================================== */
|
|
172
|
+
|
|
173
|
+
/* Row Gap Utilities - Override default gap */
|
|
174
|
+
.col-row-gap-0 { gap: 0; }
|
|
175
|
+
.col-row-gap-xs { gap: var(--spacing-xs); }
|
|
176
|
+
.col-row-gap-sm { gap: var(--spacing-sm); }
|
|
177
|
+
.col-row-gap-md { gap: var(--spacing-md); }
|
|
178
|
+
.col-row-gap-lg { gap: var(--spacing-lg); }
|
|
179
|
+
.col-row-gap-xl { gap: var(--spacing-xl); }
|
|
180
|
+
|
|
181
|
+
/* Row Justify Content Utilities */
|
|
182
|
+
.col-row-justify-start { justify-content: flex-start; }
|
|
183
|
+
.col-row-justify-center { justify-content: center; }
|
|
184
|
+
.col-row-justify-end { justify-content: flex-end; }
|
|
185
|
+
.col-row-justify-between { justify-content: space-between; }
|
|
186
|
+
.col-row-justify-around { justify-content: space-around; }
|
|
187
|
+
.col-row-justify-evenly { justify-content: space-evenly; }
|
|
188
|
+
|
|
189
|
+
/* Row Align Items Utilities */
|
|
190
|
+
.col-row-align-start { align-items: flex-start; }
|
|
191
|
+
.col-row-align-center { align-items: center; }
|
|
192
|
+
.col-row-align-end { align-items: flex-end; }
|
|
193
|
+
.col-row-align-baseline { align-items: baseline; }
|
|
194
|
+
.col-row-align-stretch { align-items: stretch; }
|
|
195
|
+
|
|
196
|
+
/* Row Wrap Utilities */
|
|
197
|
+
.col-row-nowrap { flex-wrap: nowrap; }
|
|
198
|
+
.col-row-wrap-reverse { flex-wrap: wrap-reverse; }
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { within, expect } from "storybook/test";
|
|
3
|
+
|
|
4
|
+
import "./_columns.scss";
|
|
5
|
+
|
|
6
|
+
const meta: Meta = {
|
|
7
|
+
title: "FP.React Components/Utilities/Columns",
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: `
|
|
13
|
+
## 12-Column Utility System
|
|
14
|
+
|
|
15
|
+
Bootstrap/Foundation-compatible column utilities for Flexbox layouts. Provides \`.col-1\` through \`.col-12\` classes with mobile-first responsive behavior.
|
|
16
|
+
|
|
17
|
+
### Key Features
|
|
18
|
+
- **12-column grid**: \`.col-1\` (8.333%) through \`.col-12\` (100%)
|
|
19
|
+
- **Mobile-first**: 100% width on mobile (< 768px), percentage widths on desktop
|
|
20
|
+
- **Flexbox-only**: Works with Flex component or \`.col-row\` utility (NOT with Grid component)
|
|
21
|
+
- **Optional utilities**: Offsets, auto-width, and ordering
|
|
22
|
+
|
|
23
|
+
### Container Requirements
|
|
24
|
+
Column utilities require a flex container with \`flex-wrap: wrap\`:
|
|
25
|
+
|
|
26
|
+
**Option 1: Use \`.col-row\` utility (recommended for simple layouts)**
|
|
27
|
+
\`\`\`jsx
|
|
28
|
+
<div className="col-row">
|
|
29
|
+
<div className="col-6">Column</div>
|
|
30
|
+
</div>
|
|
31
|
+
\`\`\`
|
|
32
|
+
|
|
33
|
+
**Option 2: Use Flex component (recommended for complex layouts)**
|
|
34
|
+
\`\`\`jsx
|
|
35
|
+
<Flex wrap="wrap" gap="md">
|
|
36
|
+
<div className="col-6">Column</div>
|
|
37
|
+
</Flex>
|
|
38
|
+
\`\`\`
|
|
39
|
+
`,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default meta;
|
|
46
|
+
type Story = StoryObj<typeof meta>;
|
|
47
|
+
|
|
48
|
+
// Demo card styling
|
|
49
|
+
const demoCardStyle = {
|
|
50
|
+
padding: "1rem",
|
|
51
|
+
backgroundColor: "#e0e7ff",
|
|
52
|
+
border: "2px solid #6366f1",
|
|
53
|
+
borderRadius: "0.5rem",
|
|
54
|
+
textAlign: "center" as const,
|
|
55
|
+
fontWeight: "600",
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Demonstrates all 12 column sizes stacked vertically.
|
|
60
|
+
* Shows the percentage width each column class represents.
|
|
61
|
+
*/
|
|
62
|
+
export const AllColumnSizes: Story = {
|
|
63
|
+
render: () => (
|
|
64
|
+
<div style={{ maxWidth: "1200px", margin: "0 auto" }}>
|
|
65
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
66
|
+
<div className="col-1" style={demoCardStyle}>
|
|
67
|
+
.col-1
|
|
68
|
+
<br />
|
|
69
|
+
8.333%
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
73
|
+
<div className="col-2" style={demoCardStyle}>
|
|
74
|
+
.col-2
|
|
75
|
+
<br />
|
|
76
|
+
16.667%
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
80
|
+
<div className="col-3" style={demoCardStyle}>
|
|
81
|
+
.col-3
|
|
82
|
+
<br />
|
|
83
|
+
25%
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
87
|
+
<div className="col-4" style={demoCardStyle}>
|
|
88
|
+
.col-4
|
|
89
|
+
<br />
|
|
90
|
+
33.333%
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
94
|
+
<div className="col-5" style={demoCardStyle}>
|
|
95
|
+
.col-5
|
|
96
|
+
<br />
|
|
97
|
+
41.667%
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
101
|
+
<div className="col-6" style={demoCardStyle}>
|
|
102
|
+
.col-6
|
|
103
|
+
<br />
|
|
104
|
+
50%
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
108
|
+
<div className="col-7" style={demoCardStyle}>
|
|
109
|
+
.col-7
|
|
110
|
+
<br />
|
|
111
|
+
58.333%
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
115
|
+
<div className="col-8" style={demoCardStyle}>
|
|
116
|
+
.col-8
|
|
117
|
+
<br />
|
|
118
|
+
66.667%
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
122
|
+
<div className="col-9" style={demoCardStyle}>
|
|
123
|
+
.col-9
|
|
124
|
+
<br />
|
|
125
|
+
75%
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
129
|
+
<div className="col-10" style={demoCardStyle}>
|
|
130
|
+
.col-10
|
|
131
|
+
<br />
|
|
132
|
+
83.333%
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
136
|
+
<div className="col-11" style={demoCardStyle}>
|
|
137
|
+
.col-11
|
|
138
|
+
<br />
|
|
139
|
+
91.667%
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
|
|
143
|
+
<div className="col-12" style={demoCardStyle}>
|
|
144
|
+
.col-12
|
|
145
|
+
<br />
|
|
146
|
+
100%
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
),
|
|
151
|
+
play: async ({ canvasElement, step }) => {
|
|
152
|
+
const canvas = within(canvasElement);
|
|
153
|
+
|
|
154
|
+
await step("All column sizes render correctly", async () => {
|
|
155
|
+
expect(canvas.getByText(".col-1")).toBeInTheDocument();
|
|
156
|
+
expect(canvas.getByText(".col-6")).toBeInTheDocument();
|
|
157
|
+
expect(canvas.getByText(".col-12")).toBeInTheDocument();
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Two-column layout (50/50 split).
|
|
164
|
+
* Common pattern for side-by-side content.
|
|
165
|
+
*/
|
|
166
|
+
export const TwoColumns: Story = {
|
|
167
|
+
render: () => (
|
|
168
|
+
<div className="col-row">
|
|
169
|
+
<div className="col-6" style={demoCardStyle}>
|
|
170
|
+
Left Column
|
|
171
|
+
<br />
|
|
172
|
+
.col-6
|
|
173
|
+
</div>
|
|
174
|
+
<div className="col-6" style={demoCardStyle}>
|
|
175
|
+
Right Column
|
|
176
|
+
<br />
|
|
177
|
+
.col-6
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
),
|
|
181
|
+
play: async ({ canvasElement, step }) => {
|
|
182
|
+
const canvas = within(canvasElement);
|
|
183
|
+
|
|
184
|
+
await step("Two columns render side by side", async () => {
|
|
185
|
+
expect(canvas.getByText("Left Column")).toBeInTheDocument();
|
|
186
|
+
expect(canvas.getByText("Right Column")).toBeInTheDocument();
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Three-column layout (equal widths).
|
|
193
|
+
* Perfect for feature lists, card grids, etc.
|
|
194
|
+
*/
|
|
195
|
+
export const ThreeColumns: Story = {
|
|
196
|
+
render: () => (
|
|
197
|
+
<div className="col-row">
|
|
198
|
+
<div className="col-4" style={demoCardStyle}>
|
|
199
|
+
Column 1<br />.col-4
|
|
200
|
+
</div>
|
|
201
|
+
<div className="col-4" style={demoCardStyle}>
|
|
202
|
+
Column 2<br />.col-4
|
|
203
|
+
</div>
|
|
204
|
+
<div className="col-4" style={demoCardStyle}>
|
|
205
|
+
Column 3<br />.col-4
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
),
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Four-column layout (equal widths).
|
|
213
|
+
* Great for dashboard cards or product grids.
|
|
214
|
+
*/
|
|
215
|
+
export const FourColumns: Story = {
|
|
216
|
+
render: () => (
|
|
217
|
+
<div className="col-row">
|
|
218
|
+
<div className="col-3" style={demoCardStyle}>
|
|
219
|
+
Col 1<br />.col-3
|
|
220
|
+
</div>
|
|
221
|
+
<div className="col-3" style={demoCardStyle}>
|
|
222
|
+
Col 2<br />.col-3
|
|
223
|
+
</div>
|
|
224
|
+
<div className="col-3" style={demoCardStyle}>
|
|
225
|
+
Col 3<br />.col-3
|
|
226
|
+
</div>
|
|
227
|
+
<div className="col-3" style={demoCardStyle}>
|
|
228
|
+
Col 4<br />.col-3
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
),
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Sidebar layout with asymmetric columns.
|
|
236
|
+
* Common pattern: narrow sidebar + wide main content area.
|
|
237
|
+
*/
|
|
238
|
+
export const SidebarLayout: Story = {
|
|
239
|
+
render: () => (
|
|
240
|
+
<div className="col-row">
|
|
241
|
+
<div className="col-3" style={{ ...demoCardStyle, backgroundColor: "#fef3c7" }}>
|
|
242
|
+
Sidebar
|
|
243
|
+
<br />
|
|
244
|
+
.col-3
|
|
245
|
+
</div>
|
|
246
|
+
<div className="col-9" style={{ ...demoCardStyle, backgroundColor: "#dbeafe" }}>
|
|
247
|
+
Main Content
|
|
248
|
+
<br />
|
|
249
|
+
.col-9
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
),
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Mixed column widths demonstrating flexible layouts.
|
|
257
|
+
* Shows how columns automatically wrap to new rows.
|
|
258
|
+
*/
|
|
259
|
+
export const MixedWidths: Story = {
|
|
260
|
+
render: () => (
|
|
261
|
+
<div className="col-row">
|
|
262
|
+
<div className="col-8" style={demoCardStyle}>
|
|
263
|
+
Wide (.col-8)
|
|
264
|
+
</div>
|
|
265
|
+
<div className="col-4" style={demoCardStyle}>
|
|
266
|
+
Narrow (.col-4)
|
|
267
|
+
</div>
|
|
268
|
+
<div className="col-6" style={demoCardStyle}>
|
|
269
|
+
Half (.col-6)
|
|
270
|
+
</div>
|
|
271
|
+
<div className="col-6" style={demoCardStyle}>
|
|
272
|
+
Half (.col-6)
|
|
273
|
+
</div>
|
|
274
|
+
<div className="col-12" style={demoCardStyle}>
|
|
275
|
+
Full Width (.col-12)
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Column offset utilities for centering or creating asymmetric layouts.
|
|
283
|
+
* Offsets push columns to the right using margin-inline-start.
|
|
284
|
+
*/
|
|
285
|
+
export const ColumnOffsets: Story = {
|
|
286
|
+
render: () => (
|
|
287
|
+
<div style={{ maxWidth: "1200px", margin: "0 auto" }}>
|
|
288
|
+
<div className="col-row" style={{ marginBottom: "1rem" }}>
|
|
289
|
+
<div className="col-6 col-offset-3" style={demoCardStyle}>
|
|
290
|
+
Centered
|
|
291
|
+
<br />
|
|
292
|
+
.col-6.col-offset-3
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
<div className="col-row" style={{ marginBottom: "1rem" }}>
|
|
296
|
+
<div className="col-4 col-offset-4" style={demoCardStyle}>
|
|
297
|
+
Centered
|
|
298
|
+
<br />
|
|
299
|
+
.col-4.col-offset-4
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
<div className="col-row">
|
|
303
|
+
<div className="col-3 col-offset-2" style={demoCardStyle}>
|
|
304
|
+
Offset Left
|
|
305
|
+
<br />
|
|
306
|
+
.col-3.col-offset-2
|
|
307
|
+
</div>
|
|
308
|
+
<div className="col-4 col-offset-1" style={demoCardStyle}>
|
|
309
|
+
Offset Left
|
|
310
|
+
<br />
|
|
311
|
+
.col-4.col-offset-1
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
),
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Auto-width column that sizes based on content.
|
|
320
|
+
* Useful for buttons, labels, or dynamic content widths.
|
|
321
|
+
*/
|
|
322
|
+
export const AutoWidth: Story = {
|
|
323
|
+
render: () => (
|
|
324
|
+
<div className="col-row">
|
|
325
|
+
<div className="col-auto" style={{ ...demoCardStyle, whiteSpace: "nowrap" }}>
|
|
326
|
+
Auto Width (.col-auto)
|
|
327
|
+
</div>
|
|
328
|
+
<div className="col-6" style={demoCardStyle}>
|
|
329
|
+
Fixed Width (.col-6)
|
|
330
|
+
</div>
|
|
331
|
+
<div className="col-auto" style={{ ...demoCardStyle, whiteSpace: "nowrap" }}>
|
|
332
|
+
Auto (.col-auto)
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
),
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Column ordering utilities for visual reordering without changing HTML.
|
|
340
|
+
* Useful for responsive layouts where order changes at breakpoints.
|
|
341
|
+
*/
|
|
342
|
+
export const ColumnOrdering: Story = {
|
|
343
|
+
render: () => (
|
|
344
|
+
<div style={{ maxWidth: "1200px", margin: "0 auto" }}>
|
|
345
|
+
<p style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#6b7280" }}>
|
|
346
|
+
Visual order: Second → First → Third (using .col-order-* classes)
|
|
347
|
+
</p>
|
|
348
|
+
<div className="col-row">
|
|
349
|
+
<div className="col-4 col-order-2" style={{ ...demoCardStyle, backgroundColor: "#fecaca" }}>
|
|
350
|
+
HTML Order: 1<br />
|
|
351
|
+
Visual Order: 2<br />
|
|
352
|
+
.col-order-2
|
|
353
|
+
</div>
|
|
354
|
+
<div className="col-4 col-order-first" style={{ ...demoCardStyle, backgroundColor: "#bbf7d0" }}>
|
|
355
|
+
HTML Order: 2<br />
|
|
356
|
+
Visual Order: 1<br />
|
|
357
|
+
.col-order-first
|
|
358
|
+
</div>
|
|
359
|
+
<div className="col-4 col-order-last" style={{ ...demoCardStyle, backgroundColor: "#bfdbfe" }}>
|
|
360
|
+
HTML Order: 3<br />
|
|
361
|
+
Visual Order: 3<br />
|
|
362
|
+
.col-order-last
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
),
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Custom gap spacing using gap utility classes.
|
|
371
|
+
* Shows how to control spacing between columns.
|
|
372
|
+
*/
|
|
373
|
+
export const CustomGapSpacing: Story = {
|
|
374
|
+
render: () => (
|
|
375
|
+
<div style={{ maxWidth: "1200px", margin: "0 auto" }}>
|
|
376
|
+
<h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>No Gap</h3>
|
|
377
|
+
<div className="col-row" style={{ gap: 0, marginBottom: "2rem" }}>
|
|
378
|
+
<div className="col-4" style={demoCardStyle}>
|
|
379
|
+
Column 1
|
|
380
|
+
</div>
|
|
381
|
+
<div className="col-4" style={demoCardStyle}>
|
|
382
|
+
Column 2
|
|
383
|
+
</div>
|
|
384
|
+
<div className="col-4" style={demoCardStyle}>
|
|
385
|
+
Column 3
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
|
|
389
|
+
<h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>Small Gap (0.5rem)</h3>
|
|
390
|
+
<div className="col-row" style={{ gap: "0.5rem", marginBottom: "2rem" }}>
|
|
391
|
+
<div className="col-4" style={demoCardStyle}>
|
|
392
|
+
Column 1
|
|
393
|
+
</div>
|
|
394
|
+
<div className="col-4" style={demoCardStyle}>
|
|
395
|
+
Column 2
|
|
396
|
+
</div>
|
|
397
|
+
<div className="col-4" style={demoCardStyle}>
|
|
398
|
+
Column 3
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
<h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>Large Gap (2rem)</h3>
|
|
403
|
+
<div className="col-row" style={{ gap: "2rem" }}>
|
|
404
|
+
<div className="col-4" style={demoCardStyle}>
|
|
405
|
+
Column 1
|
|
406
|
+
</div>
|
|
407
|
+
<div className="col-4" style={demoCardStyle}>
|
|
408
|
+
Column 2
|
|
409
|
+
</div>
|
|
410
|
+
<div className="col-4" style={demoCardStyle}>
|
|
411
|
+
Column 3
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
),
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Responsive behavior demonstration.
|
|
420
|
+
* Resize browser to see columns stack on mobile (< 768px) and spread on desktop.
|
|
421
|
+
*/
|
|
422
|
+
export const ResponsiveBehavior: Story = {
|
|
423
|
+
render: () => (
|
|
424
|
+
<div style={{ maxWidth: "1200px", margin: "0 auto" }}>
|
|
425
|
+
<div
|
|
426
|
+
style={{
|
|
427
|
+
padding: "1rem",
|
|
428
|
+
backgroundColor: "#fef3c7",
|
|
429
|
+
borderRadius: "0.5rem",
|
|
430
|
+
marginBottom: "1rem",
|
|
431
|
+
fontSize: "0.875rem",
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
<strong>💡 Try this:</strong> Resize your browser or use DevTools responsive mode.
|
|
435
|
+
<br />• <strong>Mobile (< 768px):</strong> All columns stack to 100% width
|
|
436
|
+
<br />• <strong>Desktop (≥ 768px):</strong> Columns use percentage widths
|
|
437
|
+
</div>
|
|
438
|
+
<div className="col-row">
|
|
439
|
+
<div className="col-4" style={demoCardStyle}>
|
|
440
|
+
Column 1<br />.col-4
|
|
441
|
+
</div>
|
|
442
|
+
<div className="col-4" style={demoCardStyle}>
|
|
443
|
+
Column 2<br />.col-4
|
|
444
|
+
</div>
|
|
445
|
+
<div className="col-4" style={demoCardStyle}>
|
|
446
|
+
Column 3<br />.col-4
|
|
447
|
+
</div>
|
|
448
|
+
</div>
|
|
449
|
+
</div>
|
|
450
|
+
),
|
|
451
|
+
parameters: {
|
|
452
|
+
viewport: {
|
|
453
|
+
defaultViewport: "md",
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
};
|