Skip to content

Promote CSS-length converter to #v0/utilities#toUnit #206

@johnleider

Description

@johnleider

Problem

PR #201 adds a padding prop to Carousel.Root that accepts number | string and converts numbers (and numeric strings) to px. The conversion is inlined in CarouselRoot.vue:

padding: toRef(() => {
  if (isNullOrUndefined(padding)) return undefined
  if (isNumber(padding)) return `${padding}px`
  return /^-?\d+(\.\d+)?$/.test(padding) ? `${padding}px` : padding
}),

This is the first CSS-length prop in v0. The next one (Dialog width, Popover offset, Slider thumbSize, Image size, etc.) will copy-paste and drift on edge cases (empty string, whitespace, scientific notation, NaN).

Proposal

Add toUnit(value, unit = 'px') to #v0/utilities when a second caller lands. Signature and semantics roughly matching Vuetify 3's convertToUnit, named toUnit to match the to* prefix convention (PHILOSOPHY §3.3):

export function toUnit (value: number | string | null | undefined, unit = 'px'): string | undefined {
  if (isNullOrUndefined(value) || value === '') return undefined
  if (isNumber(value)) return `${value}${unit}`
  return /^-?\d+(\.\d+)?$/.test(value) ? `${value}${unit}` : value
}

Tree-shakeable, #__NO_SIDE_EFFECTS__, fits alongside clamp / range.

Open questions

Decide before promoting:

  • ""undefined or ""?
  • "0""0px" or passthrough?
  • " 10 " (whitespace) — trim or fail?
  • "1e3" — convert or passthrough?
  • Separate toUnit vs. generic toCssValue — does a consumer ever need units other than px?

Pick semantics explicitly; don't inherit by accident.

Acceptance

  • Helper lives at packages/0/src/utilities/helpers.ts with tests covering every edge case listed above.
  • CarouselRoot.vue padding: block replaced with toUnit(padding).
  • At least one additional caller wired up in the same PR (otherwise the "2+ callers" bar isn't met and this stays inline).

Context

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions