@fpkit/acss 3.4.0 → 3.6.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 +5 -5
- 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 +64 -13
- package/libs/index.d.ts +64 -13
- package/libs/index.js +4 -4
- 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 +1711 -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/components/row/row.tsx +9 -0
- package/src/components/row/row.types.ts +24 -7
- package/src/sass/_columns.scss +396 -81
- package/src/styles/index.css +515 -7
- package/src/styles/index.css.map +1 -1
- package/src/types/layout-primitives.ts +22 -2
- package/libs/components/alert/alert.min.min.css +0 -2
- package/libs/components/badge/badge.min.min.css +0 -2
- package/libs/components/box/box.min.min.css +0 -2
- package/libs/components/breadcrumbs/breadcrumb.min.min.css +0 -2
- package/libs/components/buttons/button.min.min.css +0 -2
- package/libs/components/cards/card-style.min.min.css +0 -2
- package/libs/components/cards/card.min.min.css +0 -2
- package/libs/components/cluster/cluster.min.min.css +0 -2
- package/libs/components/details/details.min.min.css +0 -2
- package/libs/components/dialog/dialog.min.min.css +0 -2
- package/libs/components/flexbox/flex.min.min.css +0 -2
- package/libs/components/form/form.min.min.css +0 -2
- package/libs/components/grid/grid.min.min.css +0 -2
- package/libs/components/icons/icon.min.min.css +0 -2
- package/libs/components/images/img.min.min.css +0 -2
- package/libs/components/layout/landmarks.min.min.css +0 -2
- package/libs/components/link/link.min.min.css +0 -2
- package/libs/components/list/list.min.min.css +0 -2
- package/libs/components/nav/nav.min.min.css +0 -2
- package/libs/components/progress/progress.min.min.css +0 -2
- package/libs/components/stack/stack.min.min.css +0 -2
- package/libs/components/styles/index.min.min.css +0 -2
- package/libs/components/tag/tag.min.min.css +0 -2
- package/libs/components/text-to-speech/text-to-speech.min.min.css +0 -2
|
@@ -18,8 +18,9 @@ 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:
|
|
21
|
+
options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "flex"],
|
|
22
|
+
description:
|
|
23
|
+
"Column span (1-12 columns) or 'flex' for flex-grow behavior",
|
|
23
24
|
},
|
|
24
25
|
offset: {
|
|
25
26
|
control: "select",
|
|
@@ -422,3 +423,1711 @@ export const ResponsiveGrid: Story = {
|
|
|
422
423
|
},
|
|
423
424
|
},
|
|
424
425
|
};
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Flex Column - Demonstrates flex-grow behavior to fill remaining space.
|
|
429
|
+
* Shows how flex columns differ from auto columns and adapt responsively.
|
|
430
|
+
*/
|
|
431
|
+
export const FlexColumn: Story = {
|
|
432
|
+
render: () => (
|
|
433
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
434
|
+
{/* Flex vs Auto comparison */}
|
|
435
|
+
<div>
|
|
436
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Flex vs Auto Comparison</h3>
|
|
437
|
+
<Row>
|
|
438
|
+
<Col span={3} style={colStyle}>
|
|
439
|
+
Fixed (25%)
|
|
440
|
+
</Col>
|
|
441
|
+
<Col
|
|
442
|
+
span="flex"
|
|
443
|
+
style={{
|
|
444
|
+
...colStyle,
|
|
445
|
+
background: "#fef3c7",
|
|
446
|
+
borderColor: "#f59e0b",
|
|
447
|
+
}}
|
|
448
|
+
>
|
|
449
|
+
Flex (grows to fill 75%)
|
|
450
|
+
</Col>
|
|
451
|
+
</Row>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<div>
|
|
455
|
+
<Row>
|
|
456
|
+
<Col span={3} style={colStyle}>
|
|
457
|
+
Fixed (25%)
|
|
458
|
+
</Col>
|
|
459
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
460
|
+
Auto (sizes to content)
|
|
461
|
+
</Col>
|
|
462
|
+
</Row>
|
|
463
|
+
</div>
|
|
464
|
+
|
|
465
|
+
{/* Multiple flex columns */}
|
|
466
|
+
<div>
|
|
467
|
+
<h3 style={{ marginBottom: "0.5rem" }}>
|
|
468
|
+
Multiple Flex Columns (Equal Distribution)
|
|
469
|
+
</h3>
|
|
470
|
+
<Row>
|
|
471
|
+
<Col span={2} style={colStyle}>
|
|
472
|
+
Fixed col-2
|
|
473
|
+
</Col>
|
|
474
|
+
<Col
|
|
475
|
+
span="flex"
|
|
476
|
+
style={{
|
|
477
|
+
...colStyle,
|
|
478
|
+
background: "#fef3c7",
|
|
479
|
+
borderColor: "#f59e0b",
|
|
480
|
+
}}
|
|
481
|
+
>
|
|
482
|
+
Flex 1
|
|
483
|
+
</Col>
|
|
484
|
+
<Col
|
|
485
|
+
span="flex"
|
|
486
|
+
style={{
|
|
487
|
+
...colStyle,
|
|
488
|
+
background: "#fef3c7",
|
|
489
|
+
borderColor: "#f59e0b",
|
|
490
|
+
}}
|
|
491
|
+
>
|
|
492
|
+
Flex 2
|
|
493
|
+
</Col>
|
|
494
|
+
</Row>
|
|
495
|
+
</div>
|
|
496
|
+
|
|
497
|
+
{/* Flex with auto */}
|
|
498
|
+
<div>
|
|
499
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Flex + Auto Combination</h3>
|
|
500
|
+
<Row>
|
|
501
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
502
|
+
Button
|
|
503
|
+
</Col>
|
|
504
|
+
<Col
|
|
505
|
+
span="flex"
|
|
506
|
+
style={{
|
|
507
|
+
...colStyle,
|
|
508
|
+
background: "#fef3c7",
|
|
509
|
+
borderColor: "#f59e0b",
|
|
510
|
+
}}
|
|
511
|
+
>
|
|
512
|
+
Main Content (fills remaining)
|
|
513
|
+
</Col>
|
|
514
|
+
<Col auto style={{ ...colStyle, background: "#e0e7ff" }}>
|
|
515
|
+
Icon
|
|
516
|
+
</Col>
|
|
517
|
+
</Row>
|
|
518
|
+
</div>
|
|
519
|
+
|
|
520
|
+
{/* Complex layout */}
|
|
521
|
+
<div>
|
|
522
|
+
<h3 style={{ marginBottom: "0.5rem" }}>Complex Layout</h3>
|
|
523
|
+
<Row>
|
|
524
|
+
<Col span={2} style={colStyle}>
|
|
525
|
+
Sidebar
|
|
526
|
+
</Col>
|
|
527
|
+
<Col
|
|
528
|
+
span="flex"
|
|
529
|
+
style={{
|
|
530
|
+
...colStyle,
|
|
531
|
+
background: "#fef3c7",
|
|
532
|
+
borderColor: "#f59e0b",
|
|
533
|
+
}}
|
|
534
|
+
>
|
|
535
|
+
Main Content (grows)
|
|
536
|
+
</Col>
|
|
537
|
+
<Col span={3} style={colStyle}>
|
|
538
|
+
Aside
|
|
539
|
+
</Col>
|
|
540
|
+
</Row>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
),
|
|
544
|
+
play: async ({ canvasElement, step }) => {
|
|
545
|
+
await step("Flex classes are applied correctly", async () => {
|
|
546
|
+
const flexElements = canvasElement.querySelectorAll(".col-flex");
|
|
547
|
+
expect(flexElements.length).toBeGreaterThan(0);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
await step("Flex columns exist alongside fixed columns", async () => {
|
|
551
|
+
const rows = canvasElement.querySelectorAll(".col-row");
|
|
552
|
+
const firstRow = rows[0];
|
|
553
|
+
expect(firstRow.querySelector(".col-3")).toBeInTheDocument();
|
|
554
|
+
expect(firstRow.querySelector(".col-flex")).toBeInTheDocument();
|
|
555
|
+
});
|
|
556
|
+
},
|
|
557
|
+
parameters: {
|
|
558
|
+
docs: {
|
|
559
|
+
description: {
|
|
560
|
+
story:
|
|
561
|
+
"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.",
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* NEW: Responsive Utilities - Mobile-First Layout
|
|
569
|
+
* Demonstrates the new responsive column utilities (.col-sm-*, .col-md-*, .col-lg-*).
|
|
570
|
+
* Shows columns adapting across breakpoints: mobile (100%), tablet (50%), desktop (33.33%).
|
|
571
|
+
*/
|
|
572
|
+
export const ResponsiveUtilities: Story = {
|
|
573
|
+
render: () => (
|
|
574
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
|
|
575
|
+
<div>
|
|
576
|
+
<h3
|
|
577
|
+
style={{
|
|
578
|
+
marginBottom: "0.5rem",
|
|
579
|
+
fontSize: "1.125rem",
|
|
580
|
+
fontWeight: 600,
|
|
581
|
+
}}
|
|
582
|
+
>
|
|
583
|
+
Mobile-First Responsive Grid
|
|
584
|
+
</h3>
|
|
585
|
+
<p
|
|
586
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
587
|
+
>
|
|
588
|
+
Resize viewport: Mobile <480px (stacked), Tablet ≥480px (2 cols),
|
|
589
|
+
Desktop ≥1024px (3 cols)
|
|
590
|
+
</p>
|
|
591
|
+
<Row>
|
|
592
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
593
|
+
.col-12.col-sm-6.col-lg-4
|
|
594
|
+
</div>
|
|
595
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
596
|
+
.col-12.col-sm-6.col-lg-4
|
|
597
|
+
</div>
|
|
598
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
599
|
+
.col-12.col-sm-6.col-lg-4
|
|
600
|
+
</div>
|
|
601
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
602
|
+
.col-12.col-sm-6.col-lg-4
|
|
603
|
+
</div>
|
|
604
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
605
|
+
.col-12.col-sm-6.col-lg-4
|
|
606
|
+
</div>
|
|
607
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
608
|
+
.col-12.col-sm-6.col-lg-4
|
|
609
|
+
</div>
|
|
610
|
+
</Row>
|
|
611
|
+
</div>
|
|
612
|
+
|
|
613
|
+
<div>
|
|
614
|
+
<h3
|
|
615
|
+
style={{
|
|
616
|
+
marginBottom: "0.5rem",
|
|
617
|
+
fontSize: "1.125rem",
|
|
618
|
+
fontWeight: 600,
|
|
619
|
+
}}
|
|
620
|
+
>
|
|
621
|
+
Different Widths Per Breakpoint
|
|
622
|
+
</h3>
|
|
623
|
+
<p
|
|
624
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
625
|
+
>
|
|
626
|
+
Mobile: full width | Tablet ≥480px: 3 cols | Desktop ≥1024px: 2 cols
|
|
627
|
+
</p>
|
|
628
|
+
<Row>
|
|
629
|
+
<div
|
|
630
|
+
className="col-12 col-sm-4 col-lg-6"
|
|
631
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
632
|
+
>
|
|
633
|
+
.col-12.col-sm-4.col-lg-6
|
|
634
|
+
</div>
|
|
635
|
+
<div
|
|
636
|
+
className="col-12 col-sm-4 col-lg-6"
|
|
637
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
638
|
+
>
|
|
639
|
+
.col-12.col-sm-4.col-lg-6
|
|
640
|
+
</div>
|
|
641
|
+
<div
|
|
642
|
+
className="col-12 col-sm-4 col-lg-12"
|
|
643
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
644
|
+
>
|
|
645
|
+
.col-12.col-sm-4.col-lg-12
|
|
646
|
+
</div>
|
|
647
|
+
</Row>
|
|
648
|
+
</div>
|
|
649
|
+
|
|
650
|
+
<div>
|
|
651
|
+
<h3
|
|
652
|
+
style={{
|
|
653
|
+
marginBottom: "0.5rem",
|
|
654
|
+
fontSize: "1.125rem",
|
|
655
|
+
fontWeight: 600,
|
|
656
|
+
}}
|
|
657
|
+
>
|
|
658
|
+
Sidebar Layout (Responsive)
|
|
659
|
+
</h3>
|
|
660
|
+
<p
|
|
661
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
662
|
+
>
|
|
663
|
+
Mobile: stacked | Tablet+: sidebar (25%) + main (75%)
|
|
664
|
+
</p>
|
|
665
|
+
<Row>
|
|
666
|
+
<div
|
|
667
|
+
className="col-12 col-md-3"
|
|
668
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
669
|
+
>
|
|
670
|
+
Sidebar
|
|
671
|
+
<br />
|
|
672
|
+
.col-12.col-md-3
|
|
673
|
+
</div>
|
|
674
|
+
<div
|
|
675
|
+
className="col-12 col-md-9"
|
|
676
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
677
|
+
>
|
|
678
|
+
Main Content
|
|
679
|
+
<br />
|
|
680
|
+
.col-12.col-md-9
|
|
681
|
+
</div>
|
|
682
|
+
</Row>
|
|
683
|
+
</div>
|
|
684
|
+
</div>
|
|
685
|
+
),
|
|
686
|
+
play: async ({ canvasElement, step }) => {
|
|
687
|
+
await step("Responsive utility classes are applied", async () => {
|
|
688
|
+
const sm6Elements = canvasElement.querySelectorAll(".col-sm-6");
|
|
689
|
+
expect(sm6Elements.length).toBeGreaterThan(0);
|
|
690
|
+
|
|
691
|
+
const lg4Elements = canvasElement.querySelectorAll(".col-lg-4");
|
|
692
|
+
expect(lg4Elements.length).toBeGreaterThan(0);
|
|
693
|
+
|
|
694
|
+
const md3Element = canvasElement.querySelector(".col-md-3");
|
|
695
|
+
expect(md3Element).toBeInTheDocument();
|
|
696
|
+
});
|
|
697
|
+
},
|
|
698
|
+
parameters: {
|
|
699
|
+
docs: {
|
|
700
|
+
description: {
|
|
701
|
+
story:
|
|
702
|
+
"NEW responsive utility classes enable mobile-first layouts. Use `.col-{breakpoint}-{span}` to control column widths at different screen sizes. Breakpoints: sm (≥480px), md (≥768px), lg (≥1024px). Classes cascade: smaller breakpoints apply unless overridden by larger ones.",
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
viewport: {
|
|
706
|
+
defaultViewport: "responsive",
|
|
707
|
+
},
|
|
708
|
+
},
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* NEW: Responsive Offsets - Centering and Positioning
|
|
713
|
+
* Demonstrates responsive offset utilities (.col-*-offset-*).
|
|
714
|
+
* Shows columns centering at different breakpoints.
|
|
715
|
+
*/
|
|
716
|
+
export const ResponsiveOffsets: Story = {
|
|
717
|
+
render: () => (
|
|
718
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
|
|
719
|
+
<div>
|
|
720
|
+
<h3
|
|
721
|
+
style={{
|
|
722
|
+
marginBottom: "0.5rem",
|
|
723
|
+
fontSize: "1.125rem",
|
|
724
|
+
fontWeight: 600,
|
|
725
|
+
}}
|
|
726
|
+
>
|
|
727
|
+
Responsive Centering
|
|
728
|
+
</h3>
|
|
729
|
+
<p
|
|
730
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
731
|
+
>
|
|
732
|
+
Mobile: full width | Tablet+: centered with offset
|
|
733
|
+
</p>
|
|
734
|
+
<Row>
|
|
735
|
+
<div
|
|
736
|
+
className="col-12 col-md-6 col-md-offset-3"
|
|
737
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
738
|
+
>
|
|
739
|
+
.col-12.col-md-6.col-md-offset-3
|
|
740
|
+
<br />
|
|
741
|
+
<small>Centered on tablet+</small>
|
|
742
|
+
</div>
|
|
743
|
+
</Row>
|
|
744
|
+
</div>
|
|
745
|
+
|
|
746
|
+
<div>
|
|
747
|
+
<h3
|
|
748
|
+
style={{
|
|
749
|
+
marginBottom: "0.5rem",
|
|
750
|
+
fontSize: "1.125rem",
|
|
751
|
+
fontWeight: 600,
|
|
752
|
+
}}
|
|
753
|
+
>
|
|
754
|
+
Different Offsets Per Breakpoint
|
|
755
|
+
</h3>
|
|
756
|
+
<p
|
|
757
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
758
|
+
>
|
|
759
|
+
Offset changes at different screen sizes
|
|
760
|
+
</p>
|
|
761
|
+
<Row>
|
|
762
|
+
<div
|
|
763
|
+
className="col-12 col-sm-6 col-sm-offset-0 col-lg-4 col-lg-offset-2"
|
|
764
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
765
|
+
>
|
|
766
|
+
.col-sm-6.col-sm-offset-0
|
|
767
|
+
<br />
|
|
768
|
+
.col-lg-4.col-lg-offset-2
|
|
769
|
+
</div>
|
|
770
|
+
<div
|
|
771
|
+
className="col-12 col-sm-6 col-sm-offset-0 col-lg-4 col-lg-offset-0"
|
|
772
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
773
|
+
>
|
|
774
|
+
.col-sm-6.col-sm-offset-0
|
|
775
|
+
<br />
|
|
776
|
+
.col-lg-4.col-lg-offset-0
|
|
777
|
+
</div>
|
|
778
|
+
</Row>
|
|
779
|
+
</div>
|
|
780
|
+
|
|
781
|
+
<div>
|
|
782
|
+
<h3
|
|
783
|
+
style={{
|
|
784
|
+
marginBottom: "0.5rem",
|
|
785
|
+
fontSize: "1.125rem",
|
|
786
|
+
fontWeight: 600,
|
|
787
|
+
}}
|
|
788
|
+
>
|
|
789
|
+
Push/Pull Layout
|
|
790
|
+
</h3>
|
|
791
|
+
<p
|
|
792
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
793
|
+
>
|
|
794
|
+
Create space between columns responsively
|
|
795
|
+
</p>
|
|
796
|
+
<Row>
|
|
797
|
+
<div className="col-12 col-md-4" style={colStyle}>
|
|
798
|
+
Left column
|
|
799
|
+
<br />
|
|
800
|
+
.col-md-4
|
|
801
|
+
</div>
|
|
802
|
+
<div
|
|
803
|
+
className="col-12 col-md-4 col-md-offset-4"
|
|
804
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
805
|
+
>
|
|
806
|
+
Right column
|
|
807
|
+
<br />
|
|
808
|
+
.col-md-4.col-md-offset-4
|
|
809
|
+
<br />
|
|
810
|
+
<small>(4 column gap in middle)</small>
|
|
811
|
+
</div>
|
|
812
|
+
</Row>
|
|
813
|
+
</div>
|
|
814
|
+
</div>
|
|
815
|
+
),
|
|
816
|
+
play: async ({ canvasElement, step }) => {
|
|
817
|
+
await step("Responsive offset classes are applied", async () => {
|
|
818
|
+
const mdOffset3 = canvasElement.querySelector(".col-md-offset-3");
|
|
819
|
+
expect(mdOffset3).toBeInTheDocument();
|
|
820
|
+
|
|
821
|
+
const lgOffset2 = canvasElement.querySelector(".col-lg-offset-2");
|
|
822
|
+
expect(lgOffset2).toBeInTheDocument();
|
|
823
|
+
});
|
|
824
|
+
},
|
|
825
|
+
parameters: {
|
|
826
|
+
docs: {
|
|
827
|
+
description: {
|
|
828
|
+
story:
|
|
829
|
+
"Responsive offsets enable different spacing at different breakpoints. Use `.col-{breakpoint}-offset-{0-11}` to push columns right with margin. Perfect for centering or creating responsive gaps between columns.",
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* NEW: Responsive Ordering - Visual Reordering
|
|
837
|
+
* Demonstrates responsive order utilities (.col-*-order-*).
|
|
838
|
+
* Shows columns reordering at different breakpoints.
|
|
839
|
+
*/
|
|
840
|
+
export const ResponsiveOrdering: Story = {
|
|
841
|
+
render: () => (
|
|
842
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
|
|
843
|
+
<div>
|
|
844
|
+
<h3
|
|
845
|
+
style={{
|
|
846
|
+
marginBottom: "0.5rem",
|
|
847
|
+
fontSize: "1.125rem",
|
|
848
|
+
fontWeight: 600,
|
|
849
|
+
}}
|
|
850
|
+
>
|
|
851
|
+
Reverse Order on Desktop
|
|
852
|
+
</h3>
|
|
853
|
+
<p
|
|
854
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
855
|
+
>
|
|
856
|
+
Mobile: 1-2-3 | Desktop ≥1024px: 3-2-1
|
|
857
|
+
</p>
|
|
858
|
+
<Row>
|
|
859
|
+
<div
|
|
860
|
+
className="col-12 col-lg-4 col-lg-order-3"
|
|
861
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
862
|
+
>
|
|
863
|
+
DOM: 1st
|
|
864
|
+
<br />
|
|
865
|
+
Mobile: 1st
|
|
866
|
+
<br />
|
|
867
|
+
Desktop: 3rd
|
|
868
|
+
</div>
|
|
869
|
+
<div
|
|
870
|
+
className="col-12 col-lg-4 col-lg-order-2"
|
|
871
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
872
|
+
>
|
|
873
|
+
DOM: 2nd
|
|
874
|
+
<br />
|
|
875
|
+
Mobile: 2nd
|
|
876
|
+
<br />
|
|
877
|
+
Desktop: 2nd
|
|
878
|
+
</div>
|
|
879
|
+
<div
|
|
880
|
+
className="col-12 col-lg-4 col-lg-order-1"
|
|
881
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
882
|
+
>
|
|
883
|
+
DOM: 3rd
|
|
884
|
+
<br />
|
|
885
|
+
Mobile: 3rd
|
|
886
|
+
<br />
|
|
887
|
+
Desktop: 1st
|
|
888
|
+
</div>
|
|
889
|
+
</Row>
|
|
890
|
+
</div>
|
|
891
|
+
|
|
892
|
+
<div>
|
|
893
|
+
<h3
|
|
894
|
+
style={{
|
|
895
|
+
marginBottom: "0.5rem",
|
|
896
|
+
fontSize: "1.125rem",
|
|
897
|
+
fontWeight: 600,
|
|
898
|
+
}}
|
|
899
|
+
>
|
|
900
|
+
Content Before/After Sidebar
|
|
901
|
+
</h3>
|
|
902
|
+
<p
|
|
903
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
904
|
+
>
|
|
905
|
+
Mobile: sidebar first | Tablet+: sidebar last
|
|
906
|
+
</p>
|
|
907
|
+
<Row>
|
|
908
|
+
<div
|
|
909
|
+
className="col-12 col-md-3 col-md-order-last"
|
|
910
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
911
|
+
>
|
|
912
|
+
Sidebar
|
|
913
|
+
<br />
|
|
914
|
+
.col-md-order-last
|
|
915
|
+
<br />
|
|
916
|
+
<small>(First on mobile, last on tablet+)</small>
|
|
917
|
+
</div>
|
|
918
|
+
<div
|
|
919
|
+
className="col-12 col-md-9 col-md-order-first"
|
|
920
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
921
|
+
>
|
|
922
|
+
Main Content
|
|
923
|
+
<br />
|
|
924
|
+
.col-md-order-first
|
|
925
|
+
<br />
|
|
926
|
+
<small>(Second on mobile, first on tablet+)</small>
|
|
927
|
+
</div>
|
|
928
|
+
</Row>
|
|
929
|
+
</div>
|
|
930
|
+
|
|
931
|
+
<div
|
|
932
|
+
style={{
|
|
933
|
+
padding: "1rem",
|
|
934
|
+
background: "#fef3c7",
|
|
935
|
+
border: "1px solid #f59e0b",
|
|
936
|
+
borderRadius: "0.25rem",
|
|
937
|
+
marginTop: "1rem",
|
|
938
|
+
}}
|
|
939
|
+
>
|
|
940
|
+
<strong>⚠️ Accessibility Note:</strong> Visual order changes don't
|
|
941
|
+
affect DOM order. Screen readers and keyboard navigation follow DOM
|
|
942
|
+
order, not visual order. Use ordering sparingly and ensure content makes
|
|
943
|
+
sense in both orders.
|
|
944
|
+
</div>
|
|
945
|
+
</div>
|
|
946
|
+
),
|
|
947
|
+
play: async ({ canvasElement, step }) => {
|
|
948
|
+
await step("Responsive order classes are applied", async () => {
|
|
949
|
+
const lgOrder1 = canvasElement.querySelector(".col-lg-order-1");
|
|
950
|
+
expect(lgOrder1).toBeInTheDocument();
|
|
951
|
+
|
|
952
|
+
const mdOrderLast = canvasElement.querySelector(".col-md-order-last");
|
|
953
|
+
expect(mdOrderLast).toBeInTheDocument();
|
|
954
|
+
|
|
955
|
+
const mdOrderFirst = canvasElement.querySelector(".col-md-order-first");
|
|
956
|
+
expect(mdOrderFirst).toBeInTheDocument();
|
|
957
|
+
});
|
|
958
|
+
},
|
|
959
|
+
parameters: {
|
|
960
|
+
docs: {
|
|
961
|
+
description: {
|
|
962
|
+
story:
|
|
963
|
+
"Responsive ordering changes visual column order at different breakpoints. Use `.col-{breakpoint}-order-{0-12}` for numeric ordering, or `.col-{breakpoint}-order-first/last` for edge positioning. Remember: this only affects visual order, not DOM/accessibility order.",
|
|
964
|
+
},
|
|
965
|
+
},
|
|
966
|
+
},
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* NEW: Migration from alwaysProportional (DEPRECATED)
|
|
971
|
+
* Shows how to migrate from the deprecated alwaysProportional prop to responsive utilities.
|
|
972
|
+
*/
|
|
973
|
+
export const MigrationFromAlwaysProportional: Story = {
|
|
974
|
+
render: () => (
|
|
975
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
|
|
976
|
+
<div
|
|
977
|
+
style={{
|
|
978
|
+
padding: "1rem",
|
|
979
|
+
background: "#fef3c7",
|
|
980
|
+
border: "1px solid #f59e0b",
|
|
981
|
+
borderRadius: "0.25rem",
|
|
982
|
+
}}
|
|
983
|
+
>
|
|
984
|
+
<strong>⚠️ Deprecation Notice:</strong> The{" "}
|
|
985
|
+
<code>alwaysProportional</code> prop is deprecated and will be removed
|
|
986
|
+
in v5.0.0. Use responsive utility classes instead for better control.
|
|
987
|
+
</div>
|
|
988
|
+
|
|
989
|
+
<div>
|
|
990
|
+
<h3
|
|
991
|
+
style={{
|
|
992
|
+
marginBottom: "0.5rem",
|
|
993
|
+
fontSize: "1.125rem",
|
|
994
|
+
fontWeight: 600,
|
|
995
|
+
}}
|
|
996
|
+
>
|
|
997
|
+
Before (Deprecated) ❌
|
|
998
|
+
</h3>
|
|
999
|
+
<p
|
|
1000
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1001
|
+
>
|
|
1002
|
+
<code>
|
|
1003
|
+
<Row alwaysProportional><Col span={6}
|
|
1004
|
+
/></Row>
|
|
1005
|
+
</code>
|
|
1006
|
+
</p>
|
|
1007
|
+
<Row alwaysProportional>
|
|
1008
|
+
<Col span={6} style={{ ...colStyle, opacity: 0.6 }}>
|
|
1009
|
+
Old approach: span prop
|
|
1010
|
+
</Col>
|
|
1011
|
+
<Col span={6} style={{ ...colStyle, opacity: 0.6 }}>
|
|
1012
|
+
Limited to one breakpoint
|
|
1013
|
+
</Col>
|
|
1014
|
+
</Row>
|
|
1015
|
+
</div>
|
|
1016
|
+
|
|
1017
|
+
<div>
|
|
1018
|
+
<h3
|
|
1019
|
+
style={{
|
|
1020
|
+
marginBottom: "0.5rem",
|
|
1021
|
+
fontSize: "1.125rem",
|
|
1022
|
+
fontWeight: 600,
|
|
1023
|
+
}}
|
|
1024
|
+
>
|
|
1025
|
+
After (Recommended) ✅
|
|
1026
|
+
</h3>
|
|
1027
|
+
<p
|
|
1028
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1029
|
+
>
|
|
1030
|
+
<code><Row><div className="col-sm-6" /></Row></code>
|
|
1031
|
+
</p>
|
|
1032
|
+
<Row>
|
|
1033
|
+
<div className="col-12 col-sm-6" style={colStyle}>
|
|
1034
|
+
New approach: utility classes
|
|
1035
|
+
</div>
|
|
1036
|
+
<div className="col-12 col-sm-6" style={colStyle}>
|
|
1037
|
+
More control across breakpoints
|
|
1038
|
+
</div>
|
|
1039
|
+
</Row>
|
|
1040
|
+
</div>
|
|
1041
|
+
|
|
1042
|
+
<div>
|
|
1043
|
+
<h3
|
|
1044
|
+
style={{
|
|
1045
|
+
marginBottom: "0.5rem",
|
|
1046
|
+
fontSize: "1.125rem",
|
|
1047
|
+
fontWeight: 600,
|
|
1048
|
+
}}
|
|
1049
|
+
>
|
|
1050
|
+
Better: Multiple Breakpoints ✨
|
|
1051
|
+
</h3>
|
|
1052
|
+
<p
|
|
1053
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1054
|
+
>
|
|
1055
|
+
Stack on mobile, 2 cols on tablet, 3 cols on desktop
|
|
1056
|
+
</p>
|
|
1057
|
+
<Row>
|
|
1058
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
1059
|
+
Full control at each breakpoint
|
|
1060
|
+
</div>
|
|
1061
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
1062
|
+
Mobile-first approach
|
|
1063
|
+
</div>
|
|
1064
|
+
<div className="col-12 col-sm-6 col-lg-4" style={colStyle}>
|
|
1065
|
+
Professional responsive layouts
|
|
1066
|
+
</div>
|
|
1067
|
+
</Row>
|
|
1068
|
+
</div>
|
|
1069
|
+
|
|
1070
|
+
<div
|
|
1071
|
+
style={{
|
|
1072
|
+
padding: "1rem",
|
|
1073
|
+
background: "#e0e7ff",
|
|
1074
|
+
border: "1px solid #6366f1",
|
|
1075
|
+
borderRadius: "0.25rem",
|
|
1076
|
+
marginTop: "1rem",
|
|
1077
|
+
}}
|
|
1078
|
+
>
|
|
1079
|
+
<strong>💡 Pro Tip:</strong> You can still use Col component with
|
|
1080
|
+
className:
|
|
1081
|
+
<br />
|
|
1082
|
+
<code>
|
|
1083
|
+
<Col span={12} className="col-sm-6
|
|
1084
|
+
col-lg-4">Content</Col>
|
|
1085
|
+
</code>
|
|
1086
|
+
</div>
|
|
1087
|
+
</div>
|
|
1088
|
+
),
|
|
1089
|
+
play: async ({ canvasElement, step }) => {
|
|
1090
|
+
await step("Deprecated alwaysProportional still works", async () => {
|
|
1091
|
+
const proportionalRow = canvasElement.querySelector(
|
|
1092
|
+
".col-row-proportional"
|
|
1093
|
+
);
|
|
1094
|
+
expect(proportionalRow).toBeInTheDocument();
|
|
1095
|
+
});
|
|
1096
|
+
|
|
1097
|
+
await step("Recommended responsive utilities work", async () => {
|
|
1098
|
+
const sm6Elements = canvasElement.querySelectorAll(".col-sm-6");
|
|
1099
|
+
expect(sm6Elements.length).toBeGreaterThan(0);
|
|
1100
|
+
});
|
|
1101
|
+
},
|
|
1102
|
+
parameters: {
|
|
1103
|
+
docs: {
|
|
1104
|
+
description: {
|
|
1105
|
+
story:
|
|
1106
|
+
"Migration guide from deprecated `alwaysProportional` prop to responsive utility classes. The new approach provides more flexibility with multiple breakpoints (sm/md/lg) and is easier to customize. Both approaches currently work, but responsive utilities are recommended for all new code.",
|
|
1107
|
+
},
|
|
1108
|
+
},
|
|
1109
|
+
},
|
|
1110
|
+
};
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* NEW: Real-World Layout Patterns
|
|
1114
|
+
* Demonstrates common responsive UI patterns found in production applications.
|
|
1115
|
+
* Shows practical examples: dashboard, product grid, pricing table, blog layout.
|
|
1116
|
+
*/
|
|
1117
|
+
export const RealWorldLayouts: Story = {
|
|
1118
|
+
render: () => (
|
|
1119
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "3rem" }}>
|
|
1120
|
+
{/* Dashboard Layout */}
|
|
1121
|
+
<div>
|
|
1122
|
+
<h3
|
|
1123
|
+
style={{
|
|
1124
|
+
marginBottom: "0.5rem",
|
|
1125
|
+
fontSize: "1.125rem",
|
|
1126
|
+
fontWeight: 600,
|
|
1127
|
+
}}
|
|
1128
|
+
>
|
|
1129
|
+
Dashboard Layout
|
|
1130
|
+
</h3>
|
|
1131
|
+
<p
|
|
1132
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1133
|
+
>
|
|
1134
|
+
Mobile: stacked | Tablet: 2 cols | Desktop: 4 cols
|
|
1135
|
+
</p>
|
|
1136
|
+
<Row gap="md">
|
|
1137
|
+
<div
|
|
1138
|
+
className="col-12 col-sm-6 col-lg-3"
|
|
1139
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
1140
|
+
>
|
|
1141
|
+
<strong>Total Users</strong>
|
|
1142
|
+
<br />
|
|
1143
|
+
<div
|
|
1144
|
+
style={{
|
|
1145
|
+
fontSize: "2rem",
|
|
1146
|
+
fontWeight: "bold",
|
|
1147
|
+
margin: "0.5rem 0",
|
|
1148
|
+
}}
|
|
1149
|
+
>
|
|
1150
|
+
1,234
|
|
1151
|
+
</div>
|
|
1152
|
+
<small>+12% from last month</small>
|
|
1153
|
+
</div>
|
|
1154
|
+
<div
|
|
1155
|
+
className="col-12 col-sm-6 col-lg-3"
|
|
1156
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
1157
|
+
>
|
|
1158
|
+
<strong>Revenue</strong>
|
|
1159
|
+
<br />
|
|
1160
|
+
<div
|
|
1161
|
+
style={{
|
|
1162
|
+
fontSize: "2rem",
|
|
1163
|
+
fontWeight: "bold",
|
|
1164
|
+
margin: "0.5rem 0",
|
|
1165
|
+
}}
|
|
1166
|
+
>
|
|
1167
|
+
$45.2K
|
|
1168
|
+
</div>
|
|
1169
|
+
<small>+8% from last month</small>
|
|
1170
|
+
</div>
|
|
1171
|
+
<div
|
|
1172
|
+
className="col-12 col-sm-6 col-lg-3"
|
|
1173
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
1174
|
+
>
|
|
1175
|
+
<strong>Conversions</strong>
|
|
1176
|
+
<br />
|
|
1177
|
+
<div
|
|
1178
|
+
style={{
|
|
1179
|
+
fontSize: "2rem",
|
|
1180
|
+
fontWeight: "bold",
|
|
1181
|
+
margin: "0.5rem 0",
|
|
1182
|
+
}}
|
|
1183
|
+
>
|
|
1184
|
+
892
|
|
1185
|
+
</div>
|
|
1186
|
+
<small>+15% from last month</small>
|
|
1187
|
+
</div>
|
|
1188
|
+
<div
|
|
1189
|
+
className="col-12 col-sm-6 col-lg-3"
|
|
1190
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
1191
|
+
>
|
|
1192
|
+
<strong>Bounce Rate</strong>
|
|
1193
|
+
<br />
|
|
1194
|
+
<div
|
|
1195
|
+
style={{
|
|
1196
|
+
fontSize: "2rem",
|
|
1197
|
+
fontWeight: "bold",
|
|
1198
|
+
margin: "0.5rem 0",
|
|
1199
|
+
}}
|
|
1200
|
+
>
|
|
1201
|
+
34%
|
|
1202
|
+
</div>
|
|
1203
|
+
<small>-5% from last month</small>
|
|
1204
|
+
</div>
|
|
1205
|
+
</Row>
|
|
1206
|
+
</div>
|
|
1207
|
+
|
|
1208
|
+
{/* Product Grid */}
|
|
1209
|
+
<div>
|
|
1210
|
+
<h3
|
|
1211
|
+
style={{
|
|
1212
|
+
marginBottom: "0.5rem",
|
|
1213
|
+
fontSize: "1.125rem",
|
|
1214
|
+
fontWeight: 600,
|
|
1215
|
+
}}
|
|
1216
|
+
>
|
|
1217
|
+
Product Grid
|
|
1218
|
+
</h3>
|
|
1219
|
+
<p
|
|
1220
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1221
|
+
>
|
|
1222
|
+
Mobile: 1 col | Tablet: 2 cols | Desktop: 3 cols
|
|
1223
|
+
</p>
|
|
1224
|
+
<Row gap="lg">
|
|
1225
|
+
{[1, 2, 3, 4, 5, 6].map((item) => (
|
|
1226
|
+
<div
|
|
1227
|
+
key={item}
|
|
1228
|
+
className="col-12 col-sm-6 col-lg-4"
|
|
1229
|
+
style={colStyle}
|
|
1230
|
+
>
|
|
1231
|
+
<div
|
|
1232
|
+
style={{
|
|
1233
|
+
width: "100%",
|
|
1234
|
+
height: "150px",
|
|
1235
|
+
background: "#e5e7eb",
|
|
1236
|
+
borderRadius: "0.25rem",
|
|
1237
|
+
marginBottom: "0.5rem",
|
|
1238
|
+
}}
|
|
1239
|
+
/>
|
|
1240
|
+
<strong>Product {item}</strong>
|
|
1241
|
+
<br />
|
|
1242
|
+
<small>$99.99</small>
|
|
1243
|
+
</div>
|
|
1244
|
+
))}
|
|
1245
|
+
</Row>
|
|
1246
|
+
</div>
|
|
1247
|
+
|
|
1248
|
+
{/* Pricing Table */}
|
|
1249
|
+
<div>
|
|
1250
|
+
<h3
|
|
1251
|
+
style={{
|
|
1252
|
+
marginBottom: "0.5rem",
|
|
1253
|
+
fontSize: "1.125rem",
|
|
1254
|
+
fontWeight: 600,
|
|
1255
|
+
}}
|
|
1256
|
+
>
|
|
1257
|
+
Pricing Table
|
|
1258
|
+
</h3>
|
|
1259
|
+
<p
|
|
1260
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1261
|
+
>
|
|
1262
|
+
Mobile: stacked | Desktop: 3 equal columns
|
|
1263
|
+
</p>
|
|
1264
|
+
<Row gap="md">
|
|
1265
|
+
<div
|
|
1266
|
+
className="col-12 col-md-4"
|
|
1267
|
+
style={{ ...colStyle, background: "#f3f4f6" }}
|
|
1268
|
+
>
|
|
1269
|
+
<strong style={{ fontSize: "1.25rem" }}>Starter</strong>
|
|
1270
|
+
<br />
|
|
1271
|
+
<div
|
|
1272
|
+
style={{
|
|
1273
|
+
fontSize: "2.5rem",
|
|
1274
|
+
fontWeight: "bold",
|
|
1275
|
+
margin: "1rem 0",
|
|
1276
|
+
}}
|
|
1277
|
+
>
|
|
1278
|
+
$9
|
|
1279
|
+
</div>
|
|
1280
|
+
<ul
|
|
1281
|
+
style={{
|
|
1282
|
+
textAlign: "left",
|
|
1283
|
+
paddingLeft: "1.5rem",
|
|
1284
|
+
margin: "1rem 0",
|
|
1285
|
+
}}
|
|
1286
|
+
>
|
|
1287
|
+
<li>5 Projects</li>
|
|
1288
|
+
<li>10 GB Storage</li>
|
|
1289
|
+
<li>Email Support</li>
|
|
1290
|
+
</ul>
|
|
1291
|
+
</div>
|
|
1292
|
+
<div
|
|
1293
|
+
className="col-12 col-md-4"
|
|
1294
|
+
style={{ ...colStyle, background: "#6366f1", color: "white" }}
|
|
1295
|
+
>
|
|
1296
|
+
<strong style={{ fontSize: "1.25rem" }}>Pro ⭐</strong>
|
|
1297
|
+
<br />
|
|
1298
|
+
<div
|
|
1299
|
+
style={{
|
|
1300
|
+
fontSize: "2.5rem",
|
|
1301
|
+
fontWeight: "bold",
|
|
1302
|
+
margin: "1rem 0",
|
|
1303
|
+
}}
|
|
1304
|
+
>
|
|
1305
|
+
$29
|
|
1306
|
+
</div>
|
|
1307
|
+
<ul
|
|
1308
|
+
style={{
|
|
1309
|
+
textAlign: "left",
|
|
1310
|
+
paddingLeft: "1.5rem",
|
|
1311
|
+
margin: "1rem 0",
|
|
1312
|
+
}}
|
|
1313
|
+
>
|
|
1314
|
+
<li>Unlimited Projects</li>
|
|
1315
|
+
<li>100 GB Storage</li>
|
|
1316
|
+
<li>Priority Support</li>
|
|
1317
|
+
</ul>
|
|
1318
|
+
</div>
|
|
1319
|
+
<div
|
|
1320
|
+
className="col-12 col-md-4"
|
|
1321
|
+
style={{ ...colStyle, background: "#f3f4f6" }}
|
|
1322
|
+
>
|
|
1323
|
+
<strong style={{ fontSize: "1.25rem" }}>Enterprise</strong>
|
|
1324
|
+
<br />
|
|
1325
|
+
<div
|
|
1326
|
+
style={{
|
|
1327
|
+
fontSize: "2.5rem",
|
|
1328
|
+
fontWeight: "bold",
|
|
1329
|
+
margin: "1rem 0",
|
|
1330
|
+
}}
|
|
1331
|
+
>
|
|
1332
|
+
$99
|
|
1333
|
+
</div>
|
|
1334
|
+
<ul
|
|
1335
|
+
style={{
|
|
1336
|
+
textAlign: "left",
|
|
1337
|
+
paddingLeft: "1.5rem",
|
|
1338
|
+
margin: "1rem 0",
|
|
1339
|
+
}}
|
|
1340
|
+
>
|
|
1341
|
+
<li>Unlimited Everything</li>
|
|
1342
|
+
<li>1 TB Storage</li>
|
|
1343
|
+
<li>24/7 Phone Support</li>
|
|
1344
|
+
</ul>
|
|
1345
|
+
</div>
|
|
1346
|
+
</Row>
|
|
1347
|
+
</div>
|
|
1348
|
+
|
|
1349
|
+
{/* Blog Layout */}
|
|
1350
|
+
<div>
|
|
1351
|
+
<h3
|
|
1352
|
+
style={{
|
|
1353
|
+
marginBottom: "0.5rem",
|
|
1354
|
+
fontSize: "1.125rem",
|
|
1355
|
+
fontWeight: 600,
|
|
1356
|
+
}}
|
|
1357
|
+
>
|
|
1358
|
+
Blog Layout (Sidebar + Content)
|
|
1359
|
+
</h3>
|
|
1360
|
+
<p
|
|
1361
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1362
|
+
>
|
|
1363
|
+
Mobile: stacked (sidebar first) | Desktop: sidebar (25%) + content
|
|
1364
|
+
(75%)
|
|
1365
|
+
</p>
|
|
1366
|
+
<Row gap="lg">
|
|
1367
|
+
<div
|
|
1368
|
+
className="col-12 col-lg-3 col-lg-order-1"
|
|
1369
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
1370
|
+
>
|
|
1371
|
+
<strong>Sidebar</strong>
|
|
1372
|
+
<br />
|
|
1373
|
+
<ul
|
|
1374
|
+
style={{
|
|
1375
|
+
textAlign: "left",
|
|
1376
|
+
paddingLeft: "1.5rem",
|
|
1377
|
+
marginTop: "0.5rem",
|
|
1378
|
+
}}
|
|
1379
|
+
>
|
|
1380
|
+
<li>Categories</li>
|
|
1381
|
+
<li>Recent Posts</li>
|
|
1382
|
+
<li>Archive</li>
|
|
1383
|
+
<li>Tags</li>
|
|
1384
|
+
</ul>
|
|
1385
|
+
</div>
|
|
1386
|
+
<div
|
|
1387
|
+
className="col-12 col-lg-9 col-lg-order-2"
|
|
1388
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
1389
|
+
>
|
|
1390
|
+
<strong style={{ fontSize: "1.5rem" }}>Article Title</strong>
|
|
1391
|
+
<br />
|
|
1392
|
+
<p style={{ margin: "1rem 0", textAlign: "left" }}>
|
|
1393
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mobile
|
|
1394
|
+
users see this content below the sidebar, while desktop users see
|
|
1395
|
+
it to the right of the sidebar.
|
|
1396
|
+
</p>
|
|
1397
|
+
</div>
|
|
1398
|
+
</Row>
|
|
1399
|
+
</div>
|
|
1400
|
+
</div>
|
|
1401
|
+
),
|
|
1402
|
+
play: async ({ canvasElement, step }) => {
|
|
1403
|
+
await step("Dashboard uses 4-column responsive layout", async () => {
|
|
1404
|
+
const dashboardCols =
|
|
1405
|
+
canvasElement.querySelectorAll(".col-sm-6.col-lg-3");
|
|
1406
|
+
expect(dashboardCols.length).toBeGreaterThan(0);
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
await step("Product grid uses 3-column responsive layout", async () => {
|
|
1410
|
+
const productCols = canvasElement.querySelectorAll(".col-sm-6.col-lg-4");
|
|
1411
|
+
expect(productCols.length).toBeGreaterThan(0);
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
await step("Pricing table uses equal columns", async () => {
|
|
1415
|
+
const pricingCols = canvasElement.querySelectorAll(".col-md-4");
|
|
1416
|
+
expect(pricingCols.length).toBe(3);
|
|
1417
|
+
});
|
|
1418
|
+
},
|
|
1419
|
+
parameters: {
|
|
1420
|
+
docs: {
|
|
1421
|
+
description: {
|
|
1422
|
+
story:
|
|
1423
|
+
"Real-world responsive layout patterns commonly used in production applications. Includes dashboard stats, product grids, pricing tables, and blog layouts. Each pattern demonstrates mobile-first responsive design with appropriate breakpoints.",
|
|
1424
|
+
},
|
|
1425
|
+
},
|
|
1426
|
+
},
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1429
|
+
/**
|
|
1430
|
+
* NEW: Hero Section Patterns
|
|
1431
|
+
* Demonstrates responsive hero section layouts with content and media.
|
|
1432
|
+
* Shows different approaches: centered, split, full-width with offset.
|
|
1433
|
+
*/
|
|
1434
|
+
export const HeroSectionPatterns: Story = {
|
|
1435
|
+
render: () => (
|
|
1436
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "3rem" }}>
|
|
1437
|
+
{/* Centered Hero */}
|
|
1438
|
+
<div>
|
|
1439
|
+
<h3
|
|
1440
|
+
style={{
|
|
1441
|
+
marginBottom: "0.5rem",
|
|
1442
|
+
fontSize: "1.125rem",
|
|
1443
|
+
fontWeight: 600,
|
|
1444
|
+
}}
|
|
1445
|
+
>
|
|
1446
|
+
Centered Hero
|
|
1447
|
+
</h3>
|
|
1448
|
+
<p
|
|
1449
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1450
|
+
>
|
|
1451
|
+
Mobile: full width | Desktop: centered with offset
|
|
1452
|
+
</p>
|
|
1453
|
+
<Row>
|
|
1454
|
+
<div
|
|
1455
|
+
className="col-12 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3"
|
|
1456
|
+
style={{ ...colStyle, padding: "2rem" }}
|
|
1457
|
+
>
|
|
1458
|
+
<h1 style={{ fontSize: "2.5rem", marginBottom: "1rem" }}>
|
|
1459
|
+
Welcome to Our Product
|
|
1460
|
+
</h1>
|
|
1461
|
+
<p
|
|
1462
|
+
style={{
|
|
1463
|
+
fontSize: "1.125rem",
|
|
1464
|
+
marginBottom: "1.5rem",
|
|
1465
|
+
color: "#666",
|
|
1466
|
+
}}
|
|
1467
|
+
>
|
|
1468
|
+
Build amazing things with our platform. Start your free trial
|
|
1469
|
+
today.
|
|
1470
|
+
</p>
|
|
1471
|
+
<div
|
|
1472
|
+
style={{ display: "flex", gap: "1rem", justifyContent: "center" }}
|
|
1473
|
+
>
|
|
1474
|
+
<button style={{ padding: "0.75rem 1.5rem", fontSize: "1rem" }}>
|
|
1475
|
+
Get Started
|
|
1476
|
+
</button>
|
|
1477
|
+
<button style={{ padding: "0.75rem 1.5rem", fontSize: "1rem" }}>
|
|
1478
|
+
Learn More
|
|
1479
|
+
</button>
|
|
1480
|
+
</div>
|
|
1481
|
+
</div>
|
|
1482
|
+
</Row>
|
|
1483
|
+
</div>
|
|
1484
|
+
|
|
1485
|
+
{/* Split Hero (Image + Content) */}
|
|
1486
|
+
<div>
|
|
1487
|
+
<h3
|
|
1488
|
+
style={{
|
|
1489
|
+
marginBottom: "0.5rem",
|
|
1490
|
+
fontSize: "1.125rem",
|
|
1491
|
+
fontWeight: 600,
|
|
1492
|
+
}}
|
|
1493
|
+
>
|
|
1494
|
+
Split Hero (50/50)
|
|
1495
|
+
</h3>
|
|
1496
|
+
<p
|
|
1497
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1498
|
+
>
|
|
1499
|
+
Mobile: stacked | Desktop: side-by-side
|
|
1500
|
+
</p>
|
|
1501
|
+
<Row gap="lg" align="center">
|
|
1502
|
+
<div
|
|
1503
|
+
className="col-12 col-md-6"
|
|
1504
|
+
style={{ ...colStyle, background: "#dbeafe", padding: "2rem" }}
|
|
1505
|
+
>
|
|
1506
|
+
<h2 style={{ fontSize: "2rem", marginBottom: "1rem" }}>
|
|
1507
|
+
Beautiful Design
|
|
1508
|
+
</h2>
|
|
1509
|
+
<p
|
|
1510
|
+
style={{ fontSize: "1rem", marginBottom: "1rem", color: "#666" }}
|
|
1511
|
+
>
|
|
1512
|
+
Create stunning interfaces with our component library. Responsive,
|
|
1513
|
+
accessible, and customizable.
|
|
1514
|
+
</p>
|
|
1515
|
+
<button style={{ padding: "0.75rem 1.5rem" }}>View Features</button>
|
|
1516
|
+
</div>
|
|
1517
|
+
<div
|
|
1518
|
+
className="col-12 col-md-6"
|
|
1519
|
+
style={{
|
|
1520
|
+
...colStyle,
|
|
1521
|
+
background: "#e5e7eb",
|
|
1522
|
+
height: "300px",
|
|
1523
|
+
display: "flex",
|
|
1524
|
+
alignItems: "center",
|
|
1525
|
+
justifyContent: "center",
|
|
1526
|
+
}}
|
|
1527
|
+
>
|
|
1528
|
+
<span style={{ fontSize: "4rem" }}>🖼️</span>
|
|
1529
|
+
</div>
|
|
1530
|
+
</Row>
|
|
1531
|
+
</div>
|
|
1532
|
+
|
|
1533
|
+
{/* Asymmetric Hero */}
|
|
1534
|
+
<div>
|
|
1535
|
+
<h3
|
|
1536
|
+
style={{
|
|
1537
|
+
marginBottom: "0.5rem",
|
|
1538
|
+
fontSize: "1.125rem",
|
|
1539
|
+
fontWeight: 600,
|
|
1540
|
+
}}
|
|
1541
|
+
>
|
|
1542
|
+
Asymmetric Hero (60/40)
|
|
1543
|
+
</h3>
|
|
1544
|
+
<p
|
|
1545
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1546
|
+
>
|
|
1547
|
+
Mobile: stacked | Desktop: 60% content, 40% image
|
|
1548
|
+
</p>
|
|
1549
|
+
<Row gap="lg" align="center">
|
|
1550
|
+
<div
|
|
1551
|
+
className="col-12 col-lg-7"
|
|
1552
|
+
style={{ ...colStyle, background: "#fef3c7", padding: "2rem" }}
|
|
1553
|
+
>
|
|
1554
|
+
<h2 style={{ fontSize: "2rem", marginBottom: "1rem" }}>
|
|
1555
|
+
Enterprise Solutions
|
|
1556
|
+
</h2>
|
|
1557
|
+
<p
|
|
1558
|
+
style={{ fontSize: "1rem", marginBottom: "1rem", color: "#666" }}
|
|
1559
|
+
>
|
|
1560
|
+
Powerful tools for teams of all sizes. Scalable infrastructure,
|
|
1561
|
+
advanced security, and dedicated support.
|
|
1562
|
+
</p>
|
|
1563
|
+
<ul style={{ textAlign: "left", marginBottom: "1rem" }}>
|
|
1564
|
+
<li>99.9% Uptime SLA</li>
|
|
1565
|
+
<li>Advanced Analytics</li>
|
|
1566
|
+
<li>Priority Support</li>
|
|
1567
|
+
</ul>
|
|
1568
|
+
<button style={{ padding: "0.75rem 1.5rem" }}>Contact Sales</button>
|
|
1569
|
+
</div>
|
|
1570
|
+
<div
|
|
1571
|
+
className="col-12 col-lg-5"
|
|
1572
|
+
style={{
|
|
1573
|
+
...colStyle,
|
|
1574
|
+
background: "#e5e7eb",
|
|
1575
|
+
height: "350px",
|
|
1576
|
+
display: "flex",
|
|
1577
|
+
alignItems: "center",
|
|
1578
|
+
justifyContent: "center",
|
|
1579
|
+
}}
|
|
1580
|
+
>
|
|
1581
|
+
<span style={{ fontSize: "5rem" }}>📊</span>
|
|
1582
|
+
</div>
|
|
1583
|
+
</Row>
|
|
1584
|
+
</div>
|
|
1585
|
+
</div>
|
|
1586
|
+
),
|
|
1587
|
+
play: async ({ canvasElement, step }) => {
|
|
1588
|
+
await step("Centered hero uses responsive offset", async () => {
|
|
1589
|
+
const centeredHero = canvasElement.querySelector(
|
|
1590
|
+
".col-md-offset-2.col-lg-offset-3"
|
|
1591
|
+
);
|
|
1592
|
+
expect(centeredHero).toBeInTheDocument();
|
|
1593
|
+
});
|
|
1594
|
+
|
|
1595
|
+
await step("Split hero uses equal columns on desktop", async () => {
|
|
1596
|
+
const splitCols = canvasElement.querySelectorAll(".col-md-6");
|
|
1597
|
+
expect(splitCols.length).toBeGreaterThan(0);
|
|
1598
|
+
});
|
|
1599
|
+
|
|
1600
|
+
await step("Asymmetric hero uses 60/40 split", async () => {
|
|
1601
|
+
const col7 = canvasElement.querySelector(".col-lg-7");
|
|
1602
|
+
const col5 = canvasElement.querySelector(".col-lg-5");
|
|
1603
|
+
expect(col7).toBeInTheDocument();
|
|
1604
|
+
expect(col5).toBeInTheDocument();
|
|
1605
|
+
});
|
|
1606
|
+
},
|
|
1607
|
+
parameters: {
|
|
1608
|
+
docs: {
|
|
1609
|
+
description: {
|
|
1610
|
+
story:
|
|
1611
|
+
"Common hero section patterns for landing pages and marketing sites. Includes centered heroes with responsive offsets, 50/50 split layouts, and asymmetric layouts. All patterns stack on mobile and display side-by-side on larger screens.",
|
|
1612
|
+
},
|
|
1613
|
+
},
|
|
1614
|
+
},
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
/**
|
|
1618
|
+
* NEW: Complex Responsive Combinations
|
|
1619
|
+
* Demonstrates advanced patterns combining spans, offsets, and ordering.
|
|
1620
|
+
* Shows how to create sophisticated layouts with multiple responsive features.
|
|
1621
|
+
*/
|
|
1622
|
+
export const ComplexResponsiveCombinations: Story = {
|
|
1623
|
+
render: () => (
|
|
1624
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "3rem" }}>
|
|
1625
|
+
{/* Responsive Grid with Visual Reordering */}
|
|
1626
|
+
<div>
|
|
1627
|
+
<h3
|
|
1628
|
+
style={{
|
|
1629
|
+
marginBottom: "0.5rem",
|
|
1630
|
+
fontSize: "1.125rem",
|
|
1631
|
+
fontWeight: 600,
|
|
1632
|
+
}}
|
|
1633
|
+
>
|
|
1634
|
+
Content Priority Reordering
|
|
1635
|
+
</h3>
|
|
1636
|
+
<p
|
|
1637
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1638
|
+
>
|
|
1639
|
+
Mobile: Primary content first | Desktop: Image first (visual order
|
|
1640
|
+
change)
|
|
1641
|
+
</p>
|
|
1642
|
+
<Row gap="lg">
|
|
1643
|
+
<div
|
|
1644
|
+
className="col-12 col-md-6 col-md-order-2"
|
|
1645
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
1646
|
+
>
|
|
1647
|
+
<strong>Primary Content</strong>
|
|
1648
|
+
<br />
|
|
1649
|
+
<p style={{ margin: "0.5rem 0", textAlign: "left" }}>
|
|
1650
|
+
On mobile, users see this content first because it's higher in the
|
|
1651
|
+
DOM. On desktop, it appears second (right side) due to visual
|
|
1652
|
+
ordering.
|
|
1653
|
+
</p>
|
|
1654
|
+
</div>
|
|
1655
|
+
<div
|
|
1656
|
+
className="col-12 col-md-6 col-md-order-1"
|
|
1657
|
+
style={{
|
|
1658
|
+
...colStyle,
|
|
1659
|
+
background: "#e5e7eb",
|
|
1660
|
+
height: "200px",
|
|
1661
|
+
display: "flex",
|
|
1662
|
+
alignItems: "center",
|
|
1663
|
+
justifyContent: "center",
|
|
1664
|
+
}}
|
|
1665
|
+
>
|
|
1666
|
+
<span style={{ fontSize: "3rem" }}>📷</span>
|
|
1667
|
+
<br />
|
|
1668
|
+
<small>Image (visual first on desktop)</small>
|
|
1669
|
+
</div>
|
|
1670
|
+
</Row>
|
|
1671
|
+
</div>
|
|
1672
|
+
|
|
1673
|
+
{/* Changing Column Widths AND Offsets */}
|
|
1674
|
+
<div>
|
|
1675
|
+
<h3
|
|
1676
|
+
style={{
|
|
1677
|
+
marginBottom: "0.5rem",
|
|
1678
|
+
fontSize: "1.125rem",
|
|
1679
|
+
fontWeight: 600,
|
|
1680
|
+
}}
|
|
1681
|
+
>
|
|
1682
|
+
Dynamic Widths + Offsets
|
|
1683
|
+
</h3>
|
|
1684
|
+
<p
|
|
1685
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1686
|
+
>
|
|
1687
|
+
Tablet: 2 cols centered | Desktop: 3 cols left-aligned
|
|
1688
|
+
</p>
|
|
1689
|
+
<Row gap="md">
|
|
1690
|
+
<div
|
|
1691
|
+
className="col-12 col-md-5 col-md-offset-1 col-lg-4 col-lg-offset-0"
|
|
1692
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
1693
|
+
>
|
|
1694
|
+
<strong>.col-md-5.col-md-offset-1</strong>
|
|
1695
|
+
<br />
|
|
1696
|
+
<strong>.col-lg-4.col-lg-offset-0</strong>
|
|
1697
|
+
<br />
|
|
1698
|
+
<small>Centered on tablet, left-aligned on desktop</small>
|
|
1699
|
+
</div>
|
|
1700
|
+
<div
|
|
1701
|
+
className="col-12 col-md-5 col-md-offset-0 col-lg-4 col-lg-offset-0"
|
|
1702
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
1703
|
+
>
|
|
1704
|
+
<strong>.col-md-5.col-lg-4</strong>
|
|
1705
|
+
<br />
|
|
1706
|
+
<small>Width changes across breakpoints</small>
|
|
1707
|
+
</div>
|
|
1708
|
+
<div
|
|
1709
|
+
className="col-12 col-md-10 col-md-offset-1 col-lg-4 col-lg-offset-0"
|
|
1710
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
1711
|
+
>
|
|
1712
|
+
<strong>.col-md-10.col-md-offset-1</strong>
|
|
1713
|
+
<br />
|
|
1714
|
+
<strong>.col-lg-4.col-lg-offset-0</strong>
|
|
1715
|
+
<br />
|
|
1716
|
+
<small>Full row centered on tablet, third of row on desktop</small>
|
|
1717
|
+
</div>
|
|
1718
|
+
</Row>
|
|
1719
|
+
</div>
|
|
1720
|
+
|
|
1721
|
+
{/* Magazine-Style Layout */}
|
|
1722
|
+
<div>
|
|
1723
|
+
<h3
|
|
1724
|
+
style={{
|
|
1725
|
+
marginBottom: "0.5rem",
|
|
1726
|
+
fontSize: "1.125rem",
|
|
1727
|
+
fontWeight: 600,
|
|
1728
|
+
}}
|
|
1729
|
+
>
|
|
1730
|
+
Magazine-Style Layout
|
|
1731
|
+
</h3>
|
|
1732
|
+
<p
|
|
1733
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1734
|
+
>
|
|
1735
|
+
Mobile: stacked | Desktop: featured + grid
|
|
1736
|
+
</p>
|
|
1737
|
+
<Row gap="lg">
|
|
1738
|
+
<div
|
|
1739
|
+
className="col-12 col-lg-8"
|
|
1740
|
+
style={{
|
|
1741
|
+
...colStyle,
|
|
1742
|
+
background: "#6366f1",
|
|
1743
|
+
color: "white",
|
|
1744
|
+
padding: "2rem",
|
|
1745
|
+
minHeight: "300px",
|
|
1746
|
+
}}
|
|
1747
|
+
>
|
|
1748
|
+
<h2 style={{ fontSize: "2rem", marginBottom: "1rem" }}>
|
|
1749
|
+
Featured Article
|
|
1750
|
+
</h2>
|
|
1751
|
+
<p>Large featured content area on desktop, full width on mobile</p>
|
|
1752
|
+
</div>
|
|
1753
|
+
<div
|
|
1754
|
+
className="col-12 col-sm-6 col-lg-4"
|
|
1755
|
+
style={{ ...colStyle, background: "#fef3c7" }}
|
|
1756
|
+
>
|
|
1757
|
+
<strong>Sidebar Item 1</strong>
|
|
1758
|
+
<br />
|
|
1759
|
+
<small>Half width on tablet, quarter on desktop</small>
|
|
1760
|
+
</div>
|
|
1761
|
+
<div
|
|
1762
|
+
className="col-12 col-sm-6 col-lg-4"
|
|
1763
|
+
style={{ ...colStyle, background: "#fce7f3" }}
|
|
1764
|
+
>
|
|
1765
|
+
<strong>Article 2</strong>
|
|
1766
|
+
</div>
|
|
1767
|
+
<div
|
|
1768
|
+
className="col-12 col-sm-6 col-lg-4"
|
|
1769
|
+
style={{ ...colStyle, background: "#dbeafe" }}
|
|
1770
|
+
>
|
|
1771
|
+
<strong>Article 3</strong>
|
|
1772
|
+
</div>
|
|
1773
|
+
<div
|
|
1774
|
+
className="col-12 col-sm-6 col-lg-4"
|
|
1775
|
+
style={{ ...colStyle, background: "#e0e7ff" }}
|
|
1776
|
+
>
|
|
1777
|
+
<strong>Article 4</strong>
|
|
1778
|
+
</div>
|
|
1779
|
+
</Row>
|
|
1780
|
+
</div>
|
|
1781
|
+
|
|
1782
|
+
{/* Responsive Gap Pattern */}
|
|
1783
|
+
<div>
|
|
1784
|
+
<h3
|
|
1785
|
+
style={{
|
|
1786
|
+
marginBottom: "0.5rem",
|
|
1787
|
+
fontSize: "1.125rem",
|
|
1788
|
+
fontWeight: 600,
|
|
1789
|
+
}}
|
|
1790
|
+
>
|
|
1791
|
+
Form Layout with Responsive Grouping
|
|
1792
|
+
</h3>
|
|
1793
|
+
<p
|
|
1794
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1795
|
+
>
|
|
1796
|
+
Mobile: stacked | Tablet: 2 cols | Desktop: mixed widths
|
|
1797
|
+
</p>
|
|
1798
|
+
<Row gap="md">
|
|
1799
|
+
<div className="col-12 col-md-6" style={colStyle}>
|
|
1800
|
+
<label
|
|
1801
|
+
style={{
|
|
1802
|
+
display: "block",
|
|
1803
|
+
marginBottom: "0.25rem",
|
|
1804
|
+
fontWeight: 600,
|
|
1805
|
+
}}
|
|
1806
|
+
>
|
|
1807
|
+
First Name
|
|
1808
|
+
</label>
|
|
1809
|
+
<input type="text" style={{ width: "100%", padding: "0.5rem" }} />
|
|
1810
|
+
</div>
|
|
1811
|
+
<div className="col-12 col-md-6" style={colStyle}>
|
|
1812
|
+
<label
|
|
1813
|
+
style={{
|
|
1814
|
+
display: "block",
|
|
1815
|
+
marginBottom: "0.25rem",
|
|
1816
|
+
fontWeight: 600,
|
|
1817
|
+
}}
|
|
1818
|
+
>
|
|
1819
|
+
Last Name
|
|
1820
|
+
</label>
|
|
1821
|
+
<input type="text" style={{ width: "100%", padding: "0.5rem" }} />
|
|
1822
|
+
</div>
|
|
1823
|
+
<div className="col-12" style={colStyle}>
|
|
1824
|
+
<label
|
|
1825
|
+
style={{
|
|
1826
|
+
display: "block",
|
|
1827
|
+
marginBottom: "0.25rem",
|
|
1828
|
+
fontWeight: 600,
|
|
1829
|
+
}}
|
|
1830
|
+
>
|
|
1831
|
+
Email
|
|
1832
|
+
</label>
|
|
1833
|
+
<input type="email" style={{ width: "100%", padding: "0.5rem" }} />
|
|
1834
|
+
</div>
|
|
1835
|
+
<div className="col-12 col-md-8" style={colStyle}>
|
|
1836
|
+
<label
|
|
1837
|
+
style={{
|
|
1838
|
+
display: "block",
|
|
1839
|
+
marginBottom: "0.25rem",
|
|
1840
|
+
fontWeight: 600,
|
|
1841
|
+
}}
|
|
1842
|
+
>
|
|
1843
|
+
Street Address
|
|
1844
|
+
</label>
|
|
1845
|
+
<input type="text" style={{ width: "100%", padding: "0.5rem" }} />
|
|
1846
|
+
</div>
|
|
1847
|
+
<div className="col-12 col-md-4" style={colStyle}>
|
|
1848
|
+
<label
|
|
1849
|
+
style={{
|
|
1850
|
+
display: "block",
|
|
1851
|
+
marginBottom: "0.25rem",
|
|
1852
|
+
fontWeight: 600,
|
|
1853
|
+
}}
|
|
1854
|
+
>
|
|
1855
|
+
ZIP Code
|
|
1856
|
+
</label>
|
|
1857
|
+
<input type="text" style={{ width: "100%", padding: "0.5rem" }} />
|
|
1858
|
+
</div>
|
|
1859
|
+
</Row>
|
|
1860
|
+
</div>
|
|
1861
|
+
</div>
|
|
1862
|
+
),
|
|
1863
|
+
play: async ({ canvasElement, step }) => {
|
|
1864
|
+
await step("Content reordering works across breakpoints", async () => {
|
|
1865
|
+
const orderedCol = canvasElement.querySelector(".col-md-order-2");
|
|
1866
|
+
expect(orderedCol).toBeInTheDocument();
|
|
1867
|
+
});
|
|
1868
|
+
|
|
1869
|
+
await step("Dynamic offsets are applied correctly", async () => {
|
|
1870
|
+
const offsetCol = canvasElement.querySelector(
|
|
1871
|
+
".col-md-offset-1.col-lg-offset-0"
|
|
1872
|
+
);
|
|
1873
|
+
expect(offsetCol).toBeInTheDocument();
|
|
1874
|
+
});
|
|
1875
|
+
|
|
1876
|
+
await step("Magazine layout uses 8-column featured area", async () => {
|
|
1877
|
+
const featured = canvasElement.querySelector(".col-lg-8");
|
|
1878
|
+
expect(featured).toBeInTheDocument();
|
|
1879
|
+
});
|
|
1880
|
+
},
|
|
1881
|
+
parameters: {
|
|
1882
|
+
docs: {
|
|
1883
|
+
description: {
|
|
1884
|
+
story:
|
|
1885
|
+
"Advanced responsive patterns combining multiple features: spans + offsets + ordering. Demonstrates magazine layouts, form grouping, content priority reordering, and complex responsive behaviors. These patterns show how responsive utilities enable sophisticated designs without media queries in your components.",
|
|
1886
|
+
},
|
|
1887
|
+
},
|
|
1888
|
+
},
|
|
1889
|
+
};
|
|
1890
|
+
|
|
1891
|
+
/**
|
|
1892
|
+
* NEW: Responsive with Row Props
|
|
1893
|
+
* Demonstrates combining responsive column utilities with Row component props.
|
|
1894
|
+
* Shows how gap, justify, and align props work with responsive layouts.
|
|
1895
|
+
*/
|
|
1896
|
+
export const ResponsiveWithRowProps: Story = {
|
|
1897
|
+
render: () => (
|
|
1898
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "3rem" }}>
|
|
1899
|
+
{/* Responsive Gap */}
|
|
1900
|
+
<div>
|
|
1901
|
+
<h3
|
|
1902
|
+
style={{
|
|
1903
|
+
marginBottom: "0.5rem",
|
|
1904
|
+
fontSize: "1.125rem",
|
|
1905
|
+
fontWeight: 600,
|
|
1906
|
+
}}
|
|
1907
|
+
>
|
|
1908
|
+
Custom Gap Spacing
|
|
1909
|
+
</h3>
|
|
1910
|
+
<p
|
|
1911
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1912
|
+
>
|
|
1913
|
+
Large gap between columns (mobile stacks, desktop side-by-side)
|
|
1914
|
+
</p>
|
|
1915
|
+
<Row gap="xl">
|
|
1916
|
+
<div className="col-12 col-md-6" style={colStyle}>
|
|
1917
|
+
Column with xl gap
|
|
1918
|
+
</div>
|
|
1919
|
+
<div className="col-12 col-md-6" style={colStyle}>
|
|
1920
|
+
Column with xl gap
|
|
1921
|
+
</div>
|
|
1922
|
+
</Row>
|
|
1923
|
+
</div>
|
|
1924
|
+
|
|
1925
|
+
<div>
|
|
1926
|
+
<h3
|
|
1927
|
+
style={{
|
|
1928
|
+
marginBottom: "0.5rem",
|
|
1929
|
+
fontSize: "1.125rem",
|
|
1930
|
+
fontWeight: 600,
|
|
1931
|
+
}}
|
|
1932
|
+
>
|
|
1933
|
+
Compact Gap
|
|
1934
|
+
</h3>
|
|
1935
|
+
<p
|
|
1936
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1937
|
+
>
|
|
1938
|
+
Minimal gap for dense layouts
|
|
1939
|
+
</p>
|
|
1940
|
+
<Row gap="xs">
|
|
1941
|
+
{[1, 2, 3, 4].map((item) => (
|
|
1942
|
+
<div
|
|
1943
|
+
key={item}
|
|
1944
|
+
className="col-12 col-sm-6 col-lg-3"
|
|
1945
|
+
style={colStyle}
|
|
1946
|
+
>
|
|
1947
|
+
Compact {item}
|
|
1948
|
+
</div>
|
|
1949
|
+
))}
|
|
1950
|
+
</Row>
|
|
1951
|
+
</div>
|
|
1952
|
+
|
|
1953
|
+
{/* Centered Content */}
|
|
1954
|
+
<div>
|
|
1955
|
+
<h3
|
|
1956
|
+
style={{
|
|
1957
|
+
marginBottom: "0.5rem",
|
|
1958
|
+
fontSize: "1.125rem",
|
|
1959
|
+
fontWeight: 600,
|
|
1960
|
+
}}
|
|
1961
|
+
>
|
|
1962
|
+
Centered Columns (justify="center")
|
|
1963
|
+
</h3>
|
|
1964
|
+
<p
|
|
1965
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1966
|
+
>
|
|
1967
|
+
Columns centered horizontally when they don't fill full width
|
|
1968
|
+
</p>
|
|
1969
|
+
<Row justify="center" gap="md">
|
|
1970
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
1971
|
+
Auto width
|
|
1972
|
+
</div>
|
|
1973
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
1974
|
+
Centered
|
|
1975
|
+
</div>
|
|
1976
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
1977
|
+
Content
|
|
1978
|
+
</div>
|
|
1979
|
+
</Row>
|
|
1980
|
+
</div>
|
|
1981
|
+
|
|
1982
|
+
{/* Space Between */}
|
|
1983
|
+
<div>
|
|
1984
|
+
<h3
|
|
1985
|
+
style={{
|
|
1986
|
+
marginBottom: "0.5rem",
|
|
1987
|
+
fontSize: "1.125rem",
|
|
1988
|
+
fontWeight: 600,
|
|
1989
|
+
}}
|
|
1990
|
+
>
|
|
1991
|
+
Spaced Columns (justify="between")
|
|
1992
|
+
</h3>
|
|
1993
|
+
<p
|
|
1994
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
1995
|
+
>
|
|
1996
|
+
Maximum space between columns
|
|
1997
|
+
</p>
|
|
1998
|
+
<Row justify="between" gap="0">
|
|
1999
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
2000
|
+
Left
|
|
2001
|
+
</div>
|
|
2002
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
2003
|
+
Center
|
|
2004
|
+
</div>
|
|
2005
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
2006
|
+
Right
|
|
2007
|
+
</div>
|
|
2008
|
+
</Row>
|
|
2009
|
+
</div>
|
|
2010
|
+
|
|
2011
|
+
{/* Vertical Alignment */}
|
|
2012
|
+
<div>
|
|
2013
|
+
<h3
|
|
2014
|
+
style={{
|
|
2015
|
+
marginBottom: "0.5rem",
|
|
2016
|
+
fontSize: "1.125rem",
|
|
2017
|
+
fontWeight: 600,
|
|
2018
|
+
}}
|
|
2019
|
+
>
|
|
2020
|
+
Vertical Alignment (align="center")
|
|
2021
|
+
</h3>
|
|
2022
|
+
<p
|
|
2023
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
2024
|
+
>
|
|
2025
|
+
Columns with different heights vertically centered
|
|
2026
|
+
</p>
|
|
2027
|
+
<Row align="center" gap="md">
|
|
2028
|
+
<div
|
|
2029
|
+
className="col-12 col-md-4"
|
|
2030
|
+
style={{ ...colStyle, minHeight: "100px" }}
|
|
2031
|
+
>
|
|
2032
|
+
Short content
|
|
2033
|
+
</div>
|
|
2034
|
+
<div
|
|
2035
|
+
className="col-12 col-md-4"
|
|
2036
|
+
style={{ ...colStyle, minHeight: "200px" }}
|
|
2037
|
+
>
|
|
2038
|
+
Tall content
|
|
2039
|
+
<br />
|
|
2040
|
+
with
|
|
2041
|
+
<br />
|
|
2042
|
+
multiple
|
|
2043
|
+
<br />
|
|
2044
|
+
lines
|
|
2045
|
+
</div>
|
|
2046
|
+
<div
|
|
2047
|
+
className="col-12 col-md-4"
|
|
2048
|
+
style={{ ...colStyle, minHeight: "150px" }}
|
|
2049
|
+
>
|
|
2050
|
+
Medium content
|
|
2051
|
+
<br />
|
|
2052
|
+
vertically centered
|
|
2053
|
+
</div>
|
|
2054
|
+
</Row>
|
|
2055
|
+
</div>
|
|
2056
|
+
|
|
2057
|
+
{/* Flex Column with Row Props */}
|
|
2058
|
+
<div>
|
|
2059
|
+
<h3
|
|
2060
|
+
style={{
|
|
2061
|
+
marginBottom: "0.5rem",
|
|
2062
|
+
fontSize: "1.125rem",
|
|
2063
|
+
fontWeight: 600,
|
|
2064
|
+
}}
|
|
2065
|
+
>
|
|
2066
|
+
Flex Columns with Alignment
|
|
2067
|
+
</h3>
|
|
2068
|
+
<p
|
|
2069
|
+
style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#666" }}
|
|
2070
|
+
>
|
|
2071
|
+
Flex-grow columns combined with justify and align
|
|
2072
|
+
</p>
|
|
2073
|
+
<Row justify="between" align="center" gap="md">
|
|
2074
|
+
<div className="col-auto col-md-3" style={colStyle}>
|
|
2075
|
+
Fixed width
|
|
2076
|
+
</div>
|
|
2077
|
+
<div
|
|
2078
|
+
className="col-12 col-md-flex"
|
|
2079
|
+
style={{
|
|
2080
|
+
...colStyle,
|
|
2081
|
+
background: "#fef3c7",
|
|
2082
|
+
borderColor: "#f59e0b",
|
|
2083
|
+
}}
|
|
2084
|
+
>
|
|
2085
|
+
Flex-grow (fills remaining space)
|
|
2086
|
+
</div>
|
|
2087
|
+
<div className="col-auto col-md-auto" style={colStyle}>
|
|
2088
|
+
Auto width
|
|
2089
|
+
</div>
|
|
2090
|
+
</Row>
|
|
2091
|
+
</div>
|
|
2092
|
+
</div>
|
|
2093
|
+
),
|
|
2094
|
+
play: async ({ canvasElement, step }) => {
|
|
2095
|
+
await step("Row gap utilities are applied", async () => {
|
|
2096
|
+
const xlGapRow = canvasElement.querySelector(".col-row-gap-xl");
|
|
2097
|
+
expect(xlGapRow).toBeInTheDocument();
|
|
2098
|
+
|
|
2099
|
+
const xsGapRow = canvasElement.querySelector(".col-row-gap-xs");
|
|
2100
|
+
expect(xsGapRow).toBeInTheDocument();
|
|
2101
|
+
});
|
|
2102
|
+
|
|
2103
|
+
await step("Row justify utilities are applied", async () => {
|
|
2104
|
+
const centerRow = canvasElement.querySelector(".col-row-justify-center");
|
|
2105
|
+
expect(centerRow).toBeInTheDocument();
|
|
2106
|
+
|
|
2107
|
+
const betweenRow = canvasElement.querySelector(
|
|
2108
|
+
".col-row-justify-between"
|
|
2109
|
+
);
|
|
2110
|
+
expect(betweenRow).toBeInTheDocument();
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
await step("Row align utilities are applied", async () => {
|
|
2114
|
+
const alignCenterRow = canvasElement.querySelector(
|
|
2115
|
+
".col-row-align-center"
|
|
2116
|
+
);
|
|
2117
|
+
expect(alignCenterRow).toBeInTheDocument();
|
|
2118
|
+
});
|
|
2119
|
+
|
|
2120
|
+
await step("Flex columns work with Row props", async () => {
|
|
2121
|
+
const flexCol = canvasElement.querySelector(".col-md-flex");
|
|
2122
|
+
expect(flexCol).toBeInTheDocument();
|
|
2123
|
+
});
|
|
2124
|
+
},
|
|
2125
|
+
parameters: {
|
|
2126
|
+
docs: {
|
|
2127
|
+
description: {
|
|
2128
|
+
story:
|
|
2129
|
+
"Demonstrates combining responsive column utilities with Row component props (gap, justify, align). Shows how to control spacing, horizontal alignment, and vertical alignment while maintaining responsive behavior. Flex columns can be combined with Row props for sophisticated layouts.",
|
|
2130
|
+
},
|
|
2131
|
+
},
|
|
2132
|
+
},
|
|
2133
|
+
};
|