Skip to content

A parameter cannot say it is required: omitting it renders a default nobody chose #46

Description

@fcapolini

Split out of #31, which its own narrowing comment calls "the one with no design space to speak of and the clearest failure today". #31 keeps the value-level half.

The gap

A <:define> can give a parameter a default. It cannot say there is no sensible default and the usage site must supply one.

<:define tag="ui-btn:a"
  ::variant=${'primary'}
  ::label=${''}          // required in practice, no sensible default
  class=${`btn btn-${variant}`}
>${label}<:slot /></:define>

<ui-btn id="m" />

Renders <a class="btn btn-primary" id="m"> with an empty label, and nothing anywhere says why. Verified against main.

This is the last of #31's original five rows that is both silent and name-level. typo-n was closed by ::; the two that remain beside this one (::variant="primry", ::variant=${42}) are about the value, and stay in #31.

Proposed spelling: a declaration with no default is required

No new syntax. ::label in a <:define> declares a required parameter; ::label=${…} declares an optional one with that default.

What it costs, measured. Across the 31 files in kits/ that contain a <:define>, there are 251 :: parameter declarations and every one carries a default. Not one bare declaration exists, so nothing in either kit changes meaning.

What the shape means today, and why it is worth taking. A bare declaration currently means default true:

<:define tag="ui-btn:a" ::label class="btn">${label}|</:define>
<ui-btn />   <!-- renders: true| -->

That is the wrong default for the only thing bare declarations would plausibly be used for. Boolean flags default false — bootstrap-kit/parts/badge.htm declares ::pill=${false}, and every flag in the kit follows. So the shape being repurposed is unused and currently backwards.

Note the bare form at a usage site is unaffected and keeps meaning "pass true" — <bs-link ::button ::outline>. Different position, no ambiguity: one is inside a <:define> tag, the other on an instance.

Why not ::label! or ::label!=

Both were considered and neither pays.

  • ! is already spoken for. skipName()'s doc comment in packages/core/src/html/parser.ts lists +/! as the composite-attribute operators (class+=, class!=), and class!=/style!= is still an open TODO. A second, unrelated meaning for ! in attribute position is the overloading the no-magic policy usually refuses.
  • != has no right-hand side to take. Required means no default, so ::label!=${x} is self-contradictory. The only coherent form is ::label!, which is a bare name with a sigil — i.e. the no-default rule above, plus a character that has to be explained.

What the error should say

At the usage site, naming what is missing and where it is declared — the shape the existing parameter diagnostics already use:

<ui-btn> requires "::label", declared in ui-btn.htm:4

Compile-time only. Nothing to check at runtime: every usage site is known.

Out of scope

Value and type constraints stay in #31. This issue is only about presence.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions