### Run a Go PDF Example Source: https://github.com/carlos7ags/folio/blob/main/examples/README.md Execute a specific Go PDF example by navigating to its directory and running the go command. ```bash go run ./examples/hello ``` -------------------------------- ### Install Folio Go Package Source: https://github.com/carlos7ags/folio/blob/main/README.md Use 'go get' to install the Folio library. Requires Go 1.25+ and depends on several Go extended standard library packages. ```bash go get github.com/carlos7ags/folio ``` -------------------------------- ### Quick Start: Generate a PDF with Folio Source: https://github.com/carlos7ags/folio/blob/main/README.md A basic example demonstrating how to create a new PDF document, add a title, set auto-bookmarks, and include a heading and paragraph with specified font and size. The generated PDF is saved as 'hello.pdf'. ```go package main import ( "github.com/carlos7ags/folio/document" "github.com/carlos7ags/folio/font" "github.com/carlos7ags/folio/layout" ) func main() { doc := document.NewDocument(document.PageSizeA4) doc.Info.Title = "Hello World" doc.SetAutoBookmarks(true) doc.Add(layout.NewHeading("Hello, Folio!", layout.H1)) doc.Add(layout.NewParagraph( "A PDF generated from Go code.", font.Helvetica, 12, )) doc.Save("hello.pdf") } ``` -------------------------------- ### Clone Repository and Run Tests Source: https://github.com/carlos7ags/folio/blob/main/README.md Clone the Folio repository, navigate into the directory, and run all Go tests. Ensure you have Go installed. ```bash git clone https://github.com/carlos7ags/folio cd folio go test ./... ``` -------------------------------- ### Install and Use Folio CLI Source: https://github.com/carlos7ags/folio/blob/main/README.md Install the Folio CLI tool and use commands for merging PDFs, retrieving document information, extracting text, and creating blank PDF files. ```bash go install github.com/carlos7ags/folio/cmd/folio@latest folio merge -o combined.pdf doc1.pdf doc2.pdf folio info document.pdf folio text document.pdf folio blank -o empty.pdf -size a4 -pages 5 ``` -------------------------------- ### Set PDF Footer Source: https://github.com/carlos7ags/folio/blob/main/README.md Configure a footer for all pages of a PDF document. This example adds a page number indicator. ```go doc.SetFooter(func(ctx document.PageContext, page *document.Page) { text := fmt.Sprintf("Page %d of %d", ctx.PageIndex+1, ctx.TotalPages) page.AddText(text, font.Helvetica, 9, 280, 30) }) ``` -------------------------------- ### Grid Column Span Example Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Demonstrates how to make grid items span multiple columns. Useful for creating varied column layouts within a grid. ```CSS .grid-span { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; } .span-2 { grid-column: span 2; } .span-3 { grid-column: span 3; } .span-4 { grid-column: span 4; } ``` -------------------------------- ### Programmatic PDF Layout with Folio Source: https://github.com/carlos7ags/folio/blob/main/README.md Create PDF documents programmatically using Folio's layout engine. This example demonstrates adding a title, author, auto-bookmarks, headings, paragraphs with styling, and a table to a document. ```go doc := document.NewDocument(document.PageSizeLetter) doc.Info.Title = "Quarterly Report" doc.Info.Author = "Finance Team" doc.SetAutoBookmarks(true) doc.Add(layout.NewHeading("Q3 Revenue Report", layout.H1)) doc.Add(layout.NewParagraph("Revenue grew 23% year over year.", font.Helvetica, 12). SetAlign(layout.AlignJustify). SetSpaceAfter(10)) tbl := layout.NewTable().SetAutoColumnWidths() h := tbl.AddHeaderRow() h.AddCell("Product", font.HelveticaBold, 10) h.AddCell("Units", font.HelveticaBold, 10) h.AddCell("Revenue", font.HelveticaBold, 10) r := tbl.AddRow() r.AddCell("Widget A", font.Helvetica, 10) r.AddCell("1,200", font.Helvetica, 10) r.AddCell("$48,000", font.Helvetica, 10) doc.Add(tbl) doc.Save("report.pdf") ``` -------------------------------- ### Use Folio C Shared Library API Source: https://github.com/carlos7ags/folio/blob/main/README.md Example of using the Folio C shared library to create a new PDF document, add a page, add text, and save the document. ```c #include "folio.h" uint64_t doc = folio_document_new(595.28, 841.89); uint64_t page = folio_document_add_page(doc); folio_page_add_text(page, "Hello from C", folio_font_helvetica(), 24, 72, 750); folio_document_save(doc, "hello.pdf"); folio_document_free(doc); ``` -------------------------------- ### Create Table with Auto Column Widths Source: https://github.com/carlos7ags/folio/blob/main/README.md Shows how to create a table with automatically calculated column widths. ```go tbl := layout.NewTable().SetAutoColumnWidths() // Or explicit widths: tbl.SetColumnUnitWidths([]layout.UnitValue{ layout.Pct(30), layout.Pct(70), }) // Header rows repeat automatically on page breaks h := tbl.AddHeaderRow() h.AddCell("Name", font.HelveticaBold, 10) h.AddCell("Value", font.HelveticaBold, 10) r := tbl.AddRow() cell := r.AddCell("Styled cell", font.Helvetica, 10) cell.SetBorders(layout.AllBorders(layout.DashedBorder(1, layout.ColorBlue))) cell.SetBackground(layout.ColorLightGray) cell.SetVAlign(layout.VAlignMiddle) ``` -------------------------------- ### Build and Test Folio Packages Source: https://github.com/carlos7ags/folio/blob/main/CONTRIBUTING.md Use these make commands to build all packages, run tests with race detection, or perform comprehensive checks including formatting, vet, and tests. ```bash make build ``` ```bash make test ``` ```bash make check ``` ```bash make fmt ``` -------------------------------- ### Create Styled Paragraph Source: https://github.com/carlos7ags/folio/blob/main/README.md Demonstrates how to create a paragraph with different text styles, including bold, color, and underline. ```go p := layout.NewStyledParagraph( layout.NewRun("Normal text ", font.Helvetica, 12), layout.NewRun("bold ", font.HelveticaBold, 12), layout.NewRun("colored and underlined", font.Helvetica, 12). WithColor(layout.ColorRed). WithUnderline(), ) doc.Add(p) ``` -------------------------------- ### Configure Logger for Asset Load Errors Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md Optionally configure `Options.Logger` to receive warnings for asset loading failures. This is opt-in and does not affect existing silent behavior. ```go opts := &html.Options{ BaseFS: os.DirFS("./assets"), Logger: slog.New(slog.NewTextHandler(os.Stderr, nil)), } ``` -------------------------------- ### Reproduce Performance Benchmarks Source: https://github.com/carlos7ags/folio/blob/main/README.md Run performance benchmarks locally to measure the pipeline's speed. This command executes all benchmarks and includes memory allocation statistics. ```bash go test -run='^$' -bench=. -benchmem ./document/ ``` -------------------------------- ### Folio Architecture Overview Source: https://github.com/carlos7ags/folio/blob/main/README.md Illustrates the core data flow and drawing operations within the Folio architecture. Key principles include immutability during layout, content splitting, intrinsic sizing, deterministic output, and limited external dependencies. ```go Element.PlanLayout(area) -> LayoutPlan (immutable) PlacedBlock.Draw(ctx, x, y) -> PDF operators ``` -------------------------------- ### Build Folio C Shared Library Source: https://github.com/carlos7ags/folio/blob/main/README.md Build the Folio C shared library using Go's CGO capabilities. This library can be used with languages supporting FFI. ```bash CGO_ENABLED=1 go build -buildmode=c-shared -o libfolio.so ./export/ ``` -------------------------------- ### Set PDF Standards and Compliance Source: https://github.com/carlos7ags/folio/blob/main/README.md Configure PDF standards like PDF/UA for screen readers and text extraction, PDF/A for archival, auto-generate bookmarks from headings, and set custom page labels. ```go doc.SetTagged(true) // PDF/UA — screen readers, text extraction doc.SetPdfA(document.PdfAConfig{Level: document.PdfA2B}) // archival doc.SetAutoBookmarks(true) // auto-generate from headings doc.SetPageLabels( document.PageLabelRange{PageIndex: 0, Style: document.LabelRomanLower}, document.PageLabelRange{PageIndex: 4, Style: document.LabelDecimal}, ) ``` -------------------------------- ### Create Interactive PDF Forms Source: https://github.com/carlos7ags/folio/blob/main/README.md Build interactive forms with text fields, checkboxes, and dropdowns. Define field names, positions, and options as needed. The form is then applied to the document. ```go import "github.com/carlos7ags/folio/forms" form := forms.NewAcroForm() form.Add(forms.NewTextField("name", [4]float64{72, 700, 300, 720}, 0)) form.Add(forms.NewCheckbox("agree", [4]float64{72, 670, 92, 690}, 0, false)) form.Add(forms.NewDropdown("role", [4]float64{72, 640, 250, 660}, 0, []string{"Developer", "Designer", "Manager"})) doc.SetAcroForm(form) doc.Save("form.pdf") ``` -------------------------------- ### Migrate html.Options.BasePath to BaseFS Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md Replace `BasePath` with `BaseFS` for resolving local assets in HTML documents. `BaseFS` accepts any `fs.FS` implementation. ```go // before opts := &html.Options{BasePath: "./assets"} // after opts := &html.Options{BaseFS: os.DirFS("./assets")} ``` -------------------------------- ### Apply PDF Output Size Optimization Options Source: https://github.com/carlos7ags/folio/blob/main/README.md Save a PDF document with various optimization passes enabled to reduce file size. These options are opt-in and do not affect encrypted documents. The zero value preserves byte-identical output. ```go doc.SaveWithOptions("out.pdf", document.WriteOptions{ UseXRefStream: true, // §7.5.8 cross-reference stream UseObjectStreams: true, // §7.5.7 compressed object streams OrphanSweep: true, // drop unreachable objects CleanContentStreams: true, // §7.8 empty q/Q, identity cm DeduplicateObjects: true, // merge byte-identical objects RecompressStreams: true, // re-Flate at BestCompression }) ``` -------------------------------- ### Run All Stress Tests with Folio CLI Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/README.md Iterate through all HTML stress test files in the specified directory and render them using the Folio CLI. This is useful for a comprehensive test run. ```sh for f in examples/stress-tests/*.html; do go run ./examples/html-to-pdf "$f" done ``` -------------------------------- ### Format Folio Code Source: https://github.com/carlos7ags/folio/blob/main/CONTRIBUTING.md Execute 'gofmt -s -w .' to format the code according to standard Go conventions. CI will reject unformatted code, so ensure this is run before committing. ```bash gofmt -s -w . ``` -------------------------------- ### Run Single Stress Test with Folio CLI Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/README.md Execute a specific HTML stress test file using the Folio CLI. Ensure the Folio CLI is built and accessible. ```sh go run ./examples/html-to-pdf examples/stress-tests/columns.html ``` -------------------------------- ### Implement ResolvableLength for BackgroundImage Position Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md The `layout.BackgroundImage.Position` field changed from `[2]float64` to `[2]layout.ResolvableLength`. Out-of-tree code constructing `BackgroundImage` directly must implement the `ResolvableLength` interface for each axis. A `ptLen` wrapper is the smallest viable shape. ```go type ResolvableLength interface { Resolve(container, fontSize float64) float64 } ``` ```go type ptLen float64 func (p ptLen) Resolve(_, _ float64) float64 { return float64(p) } ``` ```go // before bg := &layout.BackgroundImage{ Image: img, Position: [2]float64{10, 20}, } ``` ```go // after bg := &layout.BackgroundImage{ Image: img, Position: [2]layout.ResolvableLength{ptLen(10), ptLen(20)}, FontSize: 12, // only consulted by em / rem leaves } ``` -------------------------------- ### Check Folio Code Locally Source: https://github.com/carlos7ags/folio/blob/main/CONTRIBUTING.md Run 'make check' to ensure your changes pass all CI checks locally, including formatting, go vet, and the full test suite, before submitting a PR. ```bash make check ``` -------------------------------- ### Import Page into New PDF Document Source: https://github.com/carlos7ags/folio/blob/main/README.md Load an existing PDF as a template and import its content into a new document. Dynamic content like invoice numbers can then be added on top. ```go r, _ := reader.Load("template.pdf") imp, _ := reader.ExtractPageImport(r, 0) doc := document.NewDocument(document.PageSizeLetter) p := doc.AddPage() p.ImportPage(imp.ContentStream, imp.Resources, imp.Width, imp.Height) p.AddText("Invoice #1042", font.HelveticaBold, 14, 72, 700) doc.Save("filled.pdf") ``` -------------------------------- ### Auto-placement with Dense Packing Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Enables dense packing for the auto-placement algorithm, filling gaps more effectively. Use when minimizing empty space is a priority. ```CSS .grid-auto { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-flow: dense; gap: 8px; } .auto-span2 { grid-column: span 2; } ``` -------------------------------- ### Set PDF Watermark Configuration Source: https://github.com/carlos7ags/folio/blob/main/README.md Configure watermark settings for a PDF document, including text, font size, opacity, and angle. ```go doc.SetWatermarkConfig(document.WatermarkConfig{ Text: "DRAFT", FontSize: 72, Opacity: 0.15, Angle: 45, }) ``` -------------------------------- ### Apply Digital Signatures to PDF Source: https://github.com/carlos7ags/folio/blob/main/README.md Sign PDF documents using local or external signers. Supports PAdES B-B, B-T, and B-LT levels. Ensure you have your private key and certificate available. ```go import "github.com/carlos7ags/folio/sign" signer, _ := sign.NewLocalSigner(privateKey, []*x509.Certificate{cert}) signed, _ := sign.SignPDF(pdfBytes, sign.Options{ Signer: signer, Level: sign.LevelBB, Reason: "Approved", Location: "New York", }) os.WriteFile("signed.pdf", signed, 0644) ``` -------------------------------- ### Basic 3-Column Equal Grid Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Use this for creating a simple layout with three equally sized columns. Heights are determined by content. ```CSS .grid-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; } ``` -------------------------------- ### Package Dependency Diagram Source: https://github.com/carlos7ags/folio/blob/main/ARCHITECTURE.md Illustrates the hierarchical import flow between different packages in the project. Imports should only go downwards. ```text document / | \ html layout sign / | | \ \ svg font image barcode \ \ | / \ content forms reader \ / / core ``` -------------------------------- ### Flex Grow Variants Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/flexbox.html Shows how `flex-grow` distributes available space among flex items. Items with higher `flex-grow` values take up more space. `flex-basis` is set to provide an initial size. ```css .flex-grow-test { display: flex; gap: 8px; } ``` ```css .grow-0 { flex-grow: 0; flex-basis: 60px; border: 1px solid #94a3b8; background: white; padding: 6px; font-size: 7.5pt; text-align: center; } ``` ```css .grow-1 { flex-grow: 1; border: 1px solid #0d9488; background: #f0fdfa; padding: 6px; font-size: 7.5pt; text-align: center; } ``` ```css .grow-2 { flex-grow: 2; border: 1px solid #334155; background: #f8fafc; padding: 6px; font-size: 7.5pt; text-align: center; } ``` ```css .grow-3 { flex-grow: 3; border: 1px solid #b85c4a; background: #fdf8f7; padding: 6px; font-size: 7.5pt; text-align: center; } ``` -------------------------------- ### Convert HTML to PDF Source: https://github.com/carlos7ags/folio/blob/main/README.md Use AddHTML to convert an HTML string into a PDF document. This method handles normal-flow elements, page settings, headers, footers, and positioned elements. It runs in-process without external dependencies. ```go import "github.com/carlos7ags/folio/document" doc := document.NewDocument(document.PageSizeLetter) doc.AddHTML( "

Invoice #1042

\n

Bill to: Acme Corp

\n \n \n \n
ItemAmount
Consulting$1,200
", nil) doc.Save("invoice.pdf") ``` -------------------------------- ### Rename sign.LoadPKCS12 to sign.ParsePKCS12 Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md The `sign.LoadPKCS12` function has been renamed to `sign.ParsePKCS12` to align with the `Parse*` naming convention. This change affects how PKCS12 data is processed. ```go // Before signer, err := sign.LoadPKCS12(data, "password") ``` ```go // After signer, err := sign.ParsePKCS12(data, "password") ``` -------------------------------- ### Repeat with Minmax Function Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Use repeat() with minmax() to define columns that have a minimum width but can grow. Ensures responsiveness and prevents content overflow. ```CSS .grid-minmax { display: grid; grid-template-columns: repeat(3, minmax(80px, 1fr)); gap: 8px; } ``` -------------------------------- ### Nested Grid Layout Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Shows how to create a grid within another grid. Useful for complex UIs where distinct sections need their own grid structure. ```CSS .grid-outer { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .grid-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; } ``` -------------------------------- ### Automated Constructor Renaming Script Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md This bash script automatically renames constructors in Go files to comply with the new `New*`, `Load*`, and `Parse*` conventions. It uses `find` and `sed` to perform the replacements. ```bash find . -name '*.go' -exec sed -i '' \ -e 's/reader\.Open(/reader.Load(/g' \ -e 's/barcode\.QRWithECC(/barcode.NewQRWithECC(/g' \ -e 's/barcode\.QR(/barcode.NewQR(/g' \ -e 's/barcode\.Code128(/barcode.NewCode128(/g' \ -e 's/barcode\.EAN13(/barcode.NewEAN13(/g' \ -e 's/layout\.RunEmbedded(/layout.NewRunEmbedded(/g' \ -e 's/layout\.Run(/layout.NewRun(/g' \ -e 's/sign\.LoadPKCS12(/sign.ParsePKCS12(/g' \ -e 's/forms\.MultilineTextField(/forms.NewMultilineTextField(/g' \ -e 's/forms\.PasswordField(/forms.NewPasswordField(/g' \ -e 's/forms\.SignatureField(/forms.NewSignatureField(/g' \ -e 's/forms\.TextField(/forms.NewTextField(/g' \ -e 's/forms\.Checkbox(/forms.NewCheckbox(/g' \ -e 's/forms\.Dropdown(/forms.NewDropdown(/g' \ -e 's/forms\.ListBox(/forms.NewListBox(/g' \ -e 's/forms\.RadioGroup(/forms.NewRadioGroup(/g' \ {} + ``` -------------------------------- ### Read and Merge PDF Documents Source: https://github.com/carlos7ags/folio/blob/main/README.md Load existing PDF files, extract information such as page count and text, and merge multiple PDFs into a single document. The merged document can then be saved. ```go import "github.com/carlos7ags/folio/reader" // Read r, _ := reader.Load("document.pdf") fmt.Println("Pages:", r.PageCount()) page, _ := r.Page(0) text, _ := page.ExtractText() // Merge r1, _ := reader.Load("doc1.pdf") r2, _ := reader.Load("doc2.pdf") m, _ := reader.Merge(r1, r2) m.SaveTo("merged.pdf") ``` -------------------------------- ### Folio Package Structure Source: https://github.com/carlos7ags/folio/blob/main/README.md Details the organization of the Folio library into distinct packages, each responsible for specific functionalities such as PDF object modeling, content streaming, document API, font handling, image processing, layout engine, barcode generation, forms, HTML/SVG conversion, digital signatures, PDF parsing, template integration, grapheme cluster handling, and a C shared library export. ```go folio/\ core/ PDF object model content/ Content stream builder document/ Document API (pages, outlines, PDF/A, watermarks, page import, WriteOptions) font/ Standard 14 + TrueType/OpenType embedding, subsetting, GSUB, GPOS image/ JPEG, PNG, TIFF, WebP, GIF layout/ Layout engine: elements, rendering, bidi, Arabic/Devanagari shaping, CJK barcode/ Code128, QR, EAN-13 forms/ AcroForms (text, checkbox, radio, dropdown, signature) html/ HTML + CSS to PDF conversion svg/ SVG to PDF rendering sign/ Digital signatures (PAdES, CMS, timestamps) reader/ PDF parser, text extraction, merge, redaction, page import tmpl/ html/template integration: execute a template, then convert unicode/grapheme/ UAX #29 grapheme clusters export/ C shared library (372 exported functions) cmd/folio/ CLI tool ``` -------------------------------- ### Flex Shrink Variants Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/flexbox.html Demonstrates `flex-shrink` which controls how flex items shrink if there isn't enough space. Items with higher `flex-shrink` values shrink more. `flex-basis` is set to provide an initial size. ```css .flex-shrink-test { display: flex; gap: 8px; width: 100%; } ``` ```css .shrink-0 { flex-shrink: 0; flex-basis: 200px; border: 1px solid #94a3b8; background: white; padding: 6px; font-size: 7.5pt; } ``` ```css .shrink-1 { flex-shrink: 1; flex-basis: 200px; border: 1px solid #0d9488; background: #f0fdfa; padding: 6px; font-size: 7.5pt; } ``` ```css .shrink-3 { flex-shrink: 3; flex-basis: 200px; border: 1px solid #b85c4a; background: #fdf8f7; padding: 6px; font-size: 7.5pt; } ``` -------------------------------- ### Basic Flex Row Layout Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/flexbox.html Establishes a flex container with items that grow to fill available space. Use for simple horizontal layouts. ```css .flex-row { display: flex; gap: 12px; } .flex-row > * { flex: 1; } ``` -------------------------------- ### Flex Order Property Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/flexbox.html Demonstrates the `order` property, which allows you to change the visual order of flex items independent of their source order. Lower order values appear first. ```css .order-test { display: flex; gap: 8px; } ``` ```css .order-test > div { flex: 1; padding: 6px; font-size: 8pt; text-align: center; } ``` ```css .o1 { order: 3; border: 1px solid #94a3b8; background: #f8fafc; } ``` ```css .o2 { order: 1; border: 1px solid #0d9488; background: #f0fdfa; } ``` ```css .o3 { order: 2; border: 1px solid #b85c4a; background: #fdf8f7; } ``` -------------------------------- ### Define Colors in Folio Source: https://github.com/carlos7ags/folio/blob/main/README.md Utilize predefined named colors or create custom colors using RGB, CMYK, Hex strings, or grayscale values. ```go layout.ColorRed // 16 named colors layout.RGB(0.2, 0.4, 0.8) // RGB layout.CMYK(1, 0, 0, 0) // CMYK for print layout.Hex("#FF8800") // hex string layout.Gray(0.5) // grayscale ``` -------------------------------- ### Flex Wrap Behavior Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/flexbox.html Demonstrates how `flex-wrap: wrap` allows flex items to move to the next line when they exceed the container's width. Use when you need items to reflow. ```css .flex-wrap { display: flex; flex-wrap: wrap; gap: 8px; } ``` -------------------------------- ### Generate Barcodes in PDF Source: https://github.com/carlos7ags/folio/blob/main/README.md Add QR codes, Code128, and EAN13 barcodes to a PDF document. Ensure the layout package is imported for element creation. ```go import "github.com/carlos7ags/folio/barcode" qr, _ := barcode.NewQR("https://example.com") doc.Add(layout.NewBarcodeElement(qr, 100).SetAlign(layout.AlignCenter)) bc, _ := barcode.NewCode128("SHIP-2024-001") doc.Add(layout.NewBarcodeElement(bc, 200)) ean, _ := barcode.NewEAN13("590123412345") doc.Add(layout.NewBarcodeElement(ean, 150)) ``` -------------------------------- ### Compare UnitValue Fields Separately Source: https://github.com/carlos7ags/folio/blob/main/MIGRATING.md Previously, `layout.UnitValue` could be compared directly with `==`. This is no longer possible due to the addition of a `func` field. Compare the variant tag and the resolved value separately. ```go // before if a == b { ... } ``` ```go // after — compare the variant tag and the resolved value separately if a.Type == b.Type && a.Pt(width) == b.Pt(width) { ... } ``` -------------------------------- ### Mixed Column Widths Grid Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Apply this to create a grid where the first column is twice the width of the others. Ensures columns sum to full width. ```CSS .grid-mixed { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; } ``` -------------------------------- ### Justify and Align Items in Grid Source: https://github.com/carlos7ags/folio/blob/main/examples/stress-tests/grid.html Demonstrates centering grid items both horizontally and vertically within their cells. Useful for consistent item alignment. ```CSS .grid-align { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; height: 120px; justify-items: center; align-items: center; border: 1px dashed #cbd5e1; padding: 8px; } .align-item { border: 1px solid #94a3b8; background: white; padding: 4px 8px; font-size: 8pt; } ```