linerecttypst

How to prevent squares from going back in line in Typst


I want to make a progress bar for my resume, to show how competent I am in a skill, similar to how stars are displayed when grading a movie on a website. Ideally, I would also like them to be aligned on the right of the box container they are in, so that if I put multiple skills under each other, all the squares are aligned.

I tried creating a function to display this kind of skills as such :

#let skill(level: int, body) = {
  body
  for i in range(5) {
    if i < level {
      square(width: 10pt, fill: black)
    } else {
      square(width: 10pt)
    }
  }
}

But there is a break with every new square, which makes it not look like a horizontal bar.


Solution

  • rect, square, ellipse, etc. are block-style by default (in their own paragraph). You are looking for box, which places elements directly adjacent to each other in the same paragraph block:

    #let skill(level: int, body) = {
      let skill-box = box.with(stroke: black, width: 1em, height: 1em, baseline: 0.25em)
      body
      h(1em)
      for i in range(5){
        if i < level{
          skill-box(fill: black)
        } else {
          skill-box()
        }
      }
    }
    
    #skill(level: 3)[Coding]
    

    enter image description here

    If you prefer vertically-stacked boxes:

    #let skill(level: int, body) = {
      let skill-box = box.with(stroke: black, width: 1em, height: 1em, baseline: 0.25em)
      body
      h(1em)
      let boxes = range(5).map(i => {
        if i < level{
          skill-box(fill: black)
        } else {
          skill-box()
        }
      })
      // btt = bottom-to-top. `ttb` will place the black blocks above white ones
      stack(dir: btt, spacing: 0em, ..boxes)
    }
    

    enter image description here