Kent Situ
Snippets

A space to collect reusable code.

Filtering in SwiftUI

A way to filter a list with any kind of filter key and any kind of entity from CoreData. Snippet from 100 Days of SwiftUI.

FilteredList.swift
import CoreData
import SwiftUI

struct FilteredList<T: NSManagedObject, Content: View>: View {
    @FetchRequest var fetchRequest: FetchedResults<T>

    // this is our content closure; we'll call this once for each item in the list
    let content: (T) -> Content

    var body: some View {
        List(fetchRequest, id: \.self) { singer in
            self.content(singer)
        }
    }

    init(filterKey: String, filterValue: String, @ViewBuilder content: @escaping (T) -> Content) {
        _fetchRequest = FetchRequest<T>(sortDescriptors: [], predicate: NSPredicate(format: "%K BEGINSWITH %@", filterKey, filterValue))
        self.content = content
    }
}

Masonry Layout

There's quick way to do it with Tailwind CSS: columns-2. But the problem with this method is it doesn't sort the dates from left to right. React Masonry CSS by Paul Collett helps solve this problem.

npm i react-masonry-css

Add this block of code to the tailwind.css file.

tailwind.css
/* to see list of all values, go to the React Masonry CSS link above */
.my-masonry-grid {
  display: flex;
  width: auto;
  margin: -10px; /* gutter size offset */
}
.my-masonry-grid_column {
  padding: 10px; /* gutter size */
  background-clip: padding-box;
}

/* style items */
.my-masonry-grid_column > div { /* change div to reference elements in <Masonry> */
  margin-bottom: 20px;
}

Then add this to your react component.

index.tsx
import Masonry from 'react-masonry-css'

const breakpointColumnsObj = {
  default: 2, // default number of columns
  768: 1, // breakpoint of going to 1 column
}

<Masonry
  breakpointCols={breakpointColumnsObj}
  className="my-masonry-grid"
  columnClassName="my-masonry-grid_column"
>
...
</Masonry>

Media Inside Photo

In my previous website, I could just create a video with the same background as the website to blend it in. This wouldn't work for this website iteration, because of light/dark mode. I had to record the video and then put it into an iPhone mockup.

<div className="group block object-scale-down py-4">
  <div className="relative flex flex-col items-center justify-center">
    // places iPhone screen over video
    <div className="absolute z-10">
      // adjust width and height to fit over video
      <Image alt="iPhone screen" src={iPhone.png} width={x1} height={y1} />
    </div>
    <div>
      <video />
    </div>
  </div>
</div>

Using calc()

I used calc() to help me calculate height of viewport with navbar/footer. Useful snippet for width and height calculations in Tailwind CSS.

// x is in pixels
h-[calc(100vh-x)]
w-[calc(100vh-x)]

// use for mobile screens dvh = dynamic viewport height
supports-[height:100dvh]:h-[calc(100dvh-x)]