@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,321 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { describe, it, expect } from "vitest";
|
|
4
|
+
import { Col } from "./col";
|
|
5
|
+
|
|
6
|
+
describe("Col Component", () => {
|
|
7
|
+
describe("Rendering", () => {
|
|
8
|
+
it("renders with default props", () => {
|
|
9
|
+
render(<Col>Test content</Col>);
|
|
10
|
+
expect(screen.getByText("Test content")).toBeInTheDocument();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("renders as div by default", () => {
|
|
14
|
+
const { container } = render(<Col>Content</Col>);
|
|
15
|
+
const col = container.firstChild as HTMLElement;
|
|
16
|
+
expect(col.tagName).toBe("DIV");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("renders as specified element type", () => {
|
|
20
|
+
const { container } = render(<Col as="section">Content</Col>);
|
|
21
|
+
const col = container.firstChild as HTMLElement;
|
|
22
|
+
expect(col.tagName).toBe("SECTION");
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("renders as li element", () => {
|
|
26
|
+
const { container } = render(<Col as="li">Content</Col>);
|
|
27
|
+
const col = container.firstChild as HTMLElement;
|
|
28
|
+
expect(col.tagName).toBe("LI");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("renders children correctly", () => {
|
|
32
|
+
render(
|
|
33
|
+
<Col>
|
|
34
|
+
<span>Child 1</span>
|
|
35
|
+
<span>Child 2</span>
|
|
36
|
+
</Col>
|
|
37
|
+
);
|
|
38
|
+
expect(screen.getByText("Child 1")).toBeInTheDocument();
|
|
39
|
+
expect(screen.getByText("Child 2")).toBeInTheDocument();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("No Base Class", () => {
|
|
44
|
+
it("has no classes when no props provided", () => {
|
|
45
|
+
const { container } = render(<Col>Content</Col>);
|
|
46
|
+
const col = container.firstChild as HTMLElement;
|
|
47
|
+
expect(col.className).toBe("");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("does not have a base .col class", () => {
|
|
51
|
+
const { container } = render(<Col span={6}>Content</Col>);
|
|
52
|
+
const col = container.firstChild as HTMLElement;
|
|
53
|
+
expect(col.classList.contains("col")).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("Span Utilities", () => {
|
|
58
|
+
it("applies col-1 utility class", () => {
|
|
59
|
+
const { container } = render(<Col span={1}>Content</Col>);
|
|
60
|
+
const col = container.firstChild as HTMLElement;
|
|
61
|
+
expect(col).toHaveClass("col-1");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("applies col-6 utility class", () => {
|
|
65
|
+
const { container } = render(<Col span={6}>Content</Col>);
|
|
66
|
+
const col = container.firstChild as HTMLElement;
|
|
67
|
+
expect(col).toHaveClass("col-6");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("applies col-12 utility class", () => {
|
|
71
|
+
const { container } = render(<Col span={12}>Content</Col>);
|
|
72
|
+
const col = container.firstChild as HTMLElement;
|
|
73
|
+
expect(col).toHaveClass("col-12");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("does not apply span class when span is undefined", () => {
|
|
77
|
+
const { container } = render(<Col>Content</Col>);
|
|
78
|
+
const col = container.firstChild as HTMLElement;
|
|
79
|
+
expect(col.className).not.toMatch(/col-\d+/);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Test all span values
|
|
83
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].forEach((spanValue) => {
|
|
84
|
+
it(`applies col-${spanValue} for span={${spanValue}}`, () => {
|
|
85
|
+
const { container } = render(<Col span={spanValue as 1}>Content</Col>);
|
|
86
|
+
const col = container.firstChild as HTMLElement;
|
|
87
|
+
expect(col).toHaveClass(`col-${spanValue}`);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("Auto Width", () => {
|
|
93
|
+
it("applies col-auto utility class", () => {
|
|
94
|
+
const { container } = render(<Col auto>Content</Col>);
|
|
95
|
+
const col = container.firstChild as HTMLElement;
|
|
96
|
+
expect(col).toHaveClass("col-auto");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("auto overrides span when both provided", () => {
|
|
100
|
+
const { container } = render(<Col auto span={6}>Content</Col>);
|
|
101
|
+
const col = container.firstChild as HTMLElement;
|
|
102
|
+
expect(col).toHaveClass("col-auto");
|
|
103
|
+
expect(col).not.toHaveClass("col-6");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("does not apply auto class when auto is false", () => {
|
|
107
|
+
const { container } = render(<Col auto={false} span={6}>Content</Col>);
|
|
108
|
+
const col = container.firstChild as HTMLElement;
|
|
109
|
+
expect(col).not.toHaveClass("col-auto");
|
|
110
|
+
expect(col).toHaveClass("col-6");
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("Offset Utilities", () => {
|
|
115
|
+
it("applies col-offset-0 utility class", () => {
|
|
116
|
+
const { container } = render(<Col offset={0}>Content</Col>);
|
|
117
|
+
const col = container.firstChild as HTMLElement;
|
|
118
|
+
expect(col).toHaveClass("col-offset-0");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("applies col-offset-3 utility class", () => {
|
|
122
|
+
const { container } = render(<Col offset={3}>Content</Col>);
|
|
123
|
+
const col = container.firstChild as HTMLElement;
|
|
124
|
+
expect(col).toHaveClass("col-offset-3");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("applies col-offset-11 utility class", () => {
|
|
128
|
+
const { container } = render(<Col offset={11}>Content</Col>);
|
|
129
|
+
const col = container.firstChild as HTMLElement;
|
|
130
|
+
expect(col).toHaveClass("col-offset-11");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("does not apply offset class when offset is undefined", () => {
|
|
134
|
+
const { container } = render(<Col span={6}>Content</Col>);
|
|
135
|
+
const col = container.firstChild as HTMLElement;
|
|
136
|
+
expect(col.className).not.toMatch(/col-offset-/);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Test all offset values
|
|
140
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].forEach((offsetValue) => {
|
|
141
|
+
it(`applies col-offset-${offsetValue} for offset={${offsetValue}}`, () => {
|
|
142
|
+
const { container } = render(
|
|
143
|
+
<Col offset={offsetValue as 0}>Content</Col>
|
|
144
|
+
);
|
|
145
|
+
const col = container.firstChild as HTMLElement;
|
|
146
|
+
expect(col).toHaveClass(`col-offset-${offsetValue}`);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe("Order Utilities", () => {
|
|
152
|
+
it("applies col-order-first utility class", () => {
|
|
153
|
+
const { container } = render(<Col order="first">Content</Col>);
|
|
154
|
+
const col = container.firstChild as HTMLElement;
|
|
155
|
+
expect(col).toHaveClass("col-order-first");
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("applies col-order-last utility class", () => {
|
|
159
|
+
const { container } = render(<Col order="last">Content</Col>);
|
|
160
|
+
const col = container.firstChild as HTMLElement;
|
|
161
|
+
expect(col).toHaveClass("col-order-last");
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("applies col-order-0 utility class", () => {
|
|
165
|
+
const { container } = render(<Col order={0}>Content</Col>);
|
|
166
|
+
const col = container.firstChild as HTMLElement;
|
|
167
|
+
expect(col).toHaveClass("col-order-0");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("applies col-order-5 utility class", () => {
|
|
171
|
+
const { container } = render(<Col order={5}>Content</Col>);
|
|
172
|
+
const col = container.firstChild as HTMLElement;
|
|
173
|
+
expect(col).toHaveClass("col-order-5");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("applies col-order-12 utility class", () => {
|
|
177
|
+
const { container } = render(<Col order={12}>Content</Col>);
|
|
178
|
+
const col = container.firstChild as HTMLElement;
|
|
179
|
+
expect(col).toHaveClass("col-order-12");
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("does not apply order class when order is undefined", () => {
|
|
183
|
+
const { container } = render(<Col span={6}>Content</Col>);
|
|
184
|
+
const col = container.firstChild as HTMLElement;
|
|
185
|
+
expect(col.className).not.toMatch(/col-order-/);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Test numeric order values
|
|
189
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].forEach((orderValue) => {
|
|
190
|
+
it(`applies col-order-${orderValue} for order={${orderValue}}`, () => {
|
|
191
|
+
const { container } = render(
|
|
192
|
+
<Col order={orderValue as 0}>Content</Col>
|
|
193
|
+
);
|
|
194
|
+
const col = container.firstChild as HTMLElement;
|
|
195
|
+
expect(col).toHaveClass(`col-order-${orderValue}`);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe("Combined Props", () => {
|
|
201
|
+
it("applies span and offset together", () => {
|
|
202
|
+
const { container } = render(<Col span={6} offset={3}>Content</Col>);
|
|
203
|
+
const col = container.firstChild as HTMLElement;
|
|
204
|
+
expect(col).toHaveClass("col-6");
|
|
205
|
+
expect(col).toHaveClass("col-offset-3");
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("applies span and order together", () => {
|
|
209
|
+
const { container } = render(<Col span={4} order={2}>Content</Col>);
|
|
210
|
+
const col = container.firstChild as HTMLElement;
|
|
211
|
+
expect(col).toHaveClass("col-4");
|
|
212
|
+
expect(col).toHaveClass("col-order-2");
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("applies span, offset, and order together", () => {
|
|
216
|
+
const { container } = render(
|
|
217
|
+
<Col span={4} offset={2} order="first">
|
|
218
|
+
Content
|
|
219
|
+
</Col>
|
|
220
|
+
);
|
|
221
|
+
const col = container.firstChild as HTMLElement;
|
|
222
|
+
expect(col).toHaveClass("col-4");
|
|
223
|
+
expect(col).toHaveClass("col-offset-2");
|
|
224
|
+
expect(col).toHaveClass("col-order-first");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("applies auto, offset, and order together", () => {
|
|
228
|
+
const { container } = render(
|
|
229
|
+
<Col auto offset={1} order="last">
|
|
230
|
+
Content
|
|
231
|
+
</Col>
|
|
232
|
+
);
|
|
233
|
+
const col = container.firstChild as HTMLElement;
|
|
234
|
+
expect(col).toHaveClass("col-auto");
|
|
235
|
+
expect(col).toHaveClass("col-offset-1");
|
|
236
|
+
expect(col).toHaveClass("col-order-last");
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe("Custom Classes", () => {
|
|
241
|
+
it("merges className prop with utility classes", () => {
|
|
242
|
+
const { container } = render(
|
|
243
|
+
<Col className="custom-class" span={6}>
|
|
244
|
+
Content
|
|
245
|
+
</Col>
|
|
246
|
+
);
|
|
247
|
+
const col = container.firstChild as HTMLElement;
|
|
248
|
+
expect(col).toHaveClass("col-6");
|
|
249
|
+
expect(col).toHaveClass("custom-class");
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("merges classes prop with utility classes", () => {
|
|
253
|
+
const { container } = render(
|
|
254
|
+
<Col classes="another-class" span={4}>
|
|
255
|
+
Content
|
|
256
|
+
</Col>
|
|
257
|
+
);
|
|
258
|
+
const col = container.firstChild as HTMLElement;
|
|
259
|
+
expect(col).toHaveClass("col-4");
|
|
260
|
+
expect(col).toHaveClass("another-class");
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("merges both className and classes props", () => {
|
|
264
|
+
const { container } = render(
|
|
265
|
+
<Col className="class-one" classes="class-two" span={6}>
|
|
266
|
+
Content
|
|
267
|
+
</Col>
|
|
268
|
+
);
|
|
269
|
+
const col = container.firstChild as HTMLElement;
|
|
270
|
+
expect(col).toHaveClass("col-6");
|
|
271
|
+
expect(col).toHaveClass("class-one");
|
|
272
|
+
expect(col).toHaveClass("class-two");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("allows custom classes without utility props", () => {
|
|
276
|
+
const { container } = render(
|
|
277
|
+
<Col className="custom-only">Content</Col>
|
|
278
|
+
);
|
|
279
|
+
const col = container.firstChild as HTMLElement;
|
|
280
|
+
expect(col).toHaveClass("custom-only");
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
describe("Ref Forwarding", () => {
|
|
285
|
+
it("forwards ref to the underlying element", () => {
|
|
286
|
+
const ref = { current: null };
|
|
287
|
+
render(<Col ref={ref}>Content</Col>);
|
|
288
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("forwards ref with custom element type", () => {
|
|
292
|
+
const ref = { current: null };
|
|
293
|
+
render(
|
|
294
|
+
<Col ref={ref} as="section">
|
|
295
|
+
Content
|
|
296
|
+
</Col>
|
|
297
|
+
);
|
|
298
|
+
expect(ref.current).toBeInstanceOf(HTMLElement);
|
|
299
|
+
expect((ref.current as unknown as HTMLElement).tagName).toBe("SECTION");
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
describe("Additional Props", () => {
|
|
304
|
+
it("passes through additional HTML attributes", () => {
|
|
305
|
+
const { container } = render(
|
|
306
|
+
<Col data-testid="test-col" aria-label="Test Column" span={6}>
|
|
307
|
+
Content
|
|
308
|
+
</Col>
|
|
309
|
+
);
|
|
310
|
+
const col = container.firstChild as HTMLElement;
|
|
311
|
+
expect(col).toHaveAttribute("data-testid", "test-col");
|
|
312
|
+
expect(col).toHaveAttribute("aria-label", "Test Column");
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("handles id prop", () => {
|
|
316
|
+
const { container } = render(<Col id="my-col" span={6}>Content</Col>);
|
|
317
|
+
const col = container.firstChild as HTMLElement;
|
|
318
|
+
expect(col).toHaveAttribute("id", "my-col");
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import UI from "../ui";
|
|
3
|
+
import type { ColProps } from "./col.types";
|
|
4
|
+
|
|
5
|
+
// Re-export types for convenience
|
|
6
|
+
export type { ColProps } from "./col.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Col - A column component for 12-column layouts.
|
|
10
|
+
*
|
|
11
|
+
* Col provides a type-safe React wrapper around column utility classes,
|
|
12
|
+
* allowing developers to create responsive columns with span, offset, order,
|
|
13
|
+
* and auto-width options. Unlike Row, Col has no base class - it's pure
|
|
14
|
+
* utility class composition.
|
|
15
|
+
*
|
|
16
|
+
* ## Key Features
|
|
17
|
+
* - **No base class**: Pure utility class mapping (follows Grid.Item pattern)
|
|
18
|
+
* - **Span control**: 1-12 column widths via span prop
|
|
19
|
+
* - **Offset positioning**: Push columns right with offset prop
|
|
20
|
+
* - **Visual reordering**: Change order with order prop
|
|
21
|
+
* - **Auto-width**: Content-based width with auto prop
|
|
22
|
+
* - **Polymorphic**: Render as any semantic HTML element
|
|
23
|
+
* - **Type-Safe**: Full TypeScript support with literal types
|
|
24
|
+
*
|
|
25
|
+
* ## Use Cases
|
|
26
|
+
* - Responsive column layouts
|
|
27
|
+
* - Grid-based designs
|
|
28
|
+
* - Content positioning
|
|
29
|
+
* - Visual reordering
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* // Basic 50% column
|
|
33
|
+
* <Col span={6}>Half width column</Col>
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Centered column with offset
|
|
37
|
+
* <Col span={6} offset={3}>Centered column</Col>
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Auto-width column
|
|
41
|
+
* <Col auto>Content-based width</Col>
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Reordered column
|
|
45
|
+
* <Col span={6} order="first">Appears first visually</Col>
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Semantic HTML
|
|
49
|
+
* <Row as="ul">
|
|
50
|
+
* <Col as="li" span={4}>List item</Col>
|
|
51
|
+
* </Row>
|
|
52
|
+
*
|
|
53
|
+
* @see {@link ColProps} for complete props documentation
|
|
54
|
+
*/
|
|
55
|
+
export const Col = React.forwardRef<HTMLElement, ColProps>(
|
|
56
|
+
(
|
|
57
|
+
{
|
|
58
|
+
span,
|
|
59
|
+
offset,
|
|
60
|
+
order,
|
|
61
|
+
auto = false,
|
|
62
|
+
as = "div",
|
|
63
|
+
className,
|
|
64
|
+
classes,
|
|
65
|
+
children,
|
|
66
|
+
...props
|
|
67
|
+
},
|
|
68
|
+
ref
|
|
69
|
+
) => {
|
|
70
|
+
// Build utility classes array - NO base class
|
|
71
|
+
const utilityClasses: string[] = [];
|
|
72
|
+
|
|
73
|
+
// Auto takes precedence over span
|
|
74
|
+
if (auto) {
|
|
75
|
+
utilityClasses.push("col-auto");
|
|
76
|
+
} else if (span) {
|
|
77
|
+
utilityClasses.push(`col-${span}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Offset utilities
|
|
81
|
+
if (offset !== undefined) {
|
|
82
|
+
utilityClasses.push(`col-offset-${offset}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Order utilities
|
|
86
|
+
if (order !== undefined) {
|
|
87
|
+
utilityClasses.push(`col-order-${order}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Merge all classes: utilities + className + classes
|
|
91
|
+
const allClasses = [...utilityClasses, className, classes]
|
|
92
|
+
.filter(Boolean)
|
|
93
|
+
.join(" ");
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<UI as={as} ref={ref} classes={allClasses} {...props}>
|
|
97
|
+
{children}
|
|
98
|
+
</UI>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
Col.displayName = "Col";
|
|
104
|
+
|
|
105
|
+
export default Col;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ComponentProps } from "../../types/component-props";
|
|
2
|
+
import type {
|
|
3
|
+
ColElement,
|
|
4
|
+
ColumnSpan,
|
|
5
|
+
ColumnOffset,
|
|
6
|
+
ColumnOrder,
|
|
7
|
+
} from "../../types/layout-primitives";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Props for the Col component
|
|
11
|
+
*
|
|
12
|
+
* Col provides a column element for use within Row containers. Maps React
|
|
13
|
+
* props to column utility classes (.col-*, .col-offset-*, .col-order-*,
|
|
14
|
+
* .col-auto) without a base class. Pure utility class composition.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Basic column with 50% width
|
|
18
|
+
* <Col span={6}>Column content</Col>
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Column with offset and order
|
|
22
|
+
* <Col span={4} offset={2} order={1}>
|
|
23
|
+
* Offset and reordered
|
|
24
|
+
* </Col>
|
|
25
|
+
*/
|
|
26
|
+
export interface ColProps
|
|
27
|
+
extends Partial<ComponentProps>,
|
|
28
|
+
Omit<React.HTMLAttributes<HTMLElement>, "className"> {
|
|
29
|
+
/**
|
|
30
|
+
* Column span (1-12)
|
|
31
|
+
* Maps to .col-{span} utility class
|
|
32
|
+
* Ignored if auto is true
|
|
33
|
+
* @default undefined
|
|
34
|
+
*/
|
|
35
|
+
span?: ColumnSpan;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Column offset (0-11)
|
|
39
|
+
* Pushes column to the right using margin-inline-start
|
|
40
|
+
* Maps to .col-offset-{offset} utility class
|
|
41
|
+
* @default undefined
|
|
42
|
+
*/
|
|
43
|
+
offset?: ColumnOffset;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Column order
|
|
47
|
+
* Controls visual order using flexbox order property
|
|
48
|
+
* Maps to .col-order-{order} utility class
|
|
49
|
+
* @default undefined
|
|
50
|
+
*/
|
|
51
|
+
order?: ColumnOrder;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Auto-width column
|
|
55
|
+
* When true, uses .col-auto (content-based width)
|
|
56
|
+
* Takes precedence over span prop
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
auto?: boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Element type to render
|
|
63
|
+
* @default "div"
|
|
64
|
+
*/
|
|
65
|
+
as?: ColElement;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Additional CSS classes
|
|
69
|
+
*/
|
|
70
|
+
className?: string;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Child elements
|
|
74
|
+
*/
|
|
75
|
+
children?: React.ReactNode;
|
|
76
|
+
}
|