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.
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.Renders
<a class="btn btn-primary" id="m">with an empty label, and nothing anywhere says why. Verified againstmain.This is the last of #31's original five rows that is both silent and name-level.
typo-nwas 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.
::labelin 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:That is the wrong default for the only thing bare declarations would plausibly be used for. Boolean flags default false —
bootstrap-kit/parts/badge.htmdeclares::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 inpackages/core/src/html/parser.tslists+/!as the composite-attribute operators (class+=,class!=), andclass!=/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:
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.