Osy#betaRun it on Osyrin: osyrin.com

Reference / UI

qualified element (Owner.Name.Element)

One.Kit.Card(title: "x") · Osysharp.Ui.Badge("hi") · Osysharp.Button("hi")

Names the package whose component or control you mean, as Owner.Name.Element. Use it when your own declaration shadows a package's, or when two packages declare the same name — which is an error until you qualify it.

stable1 example compiled by CIuipackagesnamespacesauthoring

Summary#

In a render block, an element may be written namespace-qualified — One.Kit.Card(…) — to name the package whose component or control you mean. You need it in exactly two situations: your app declares a component of the same name and you want the package's anyway, or two packages declare the name and a bare reference is therefore refused.

Signature#

render {
  Card("mine");                    // bare — your own declaration wins if you have one
  One.Kit.Card(title: "theirs");   // qualified — this package's, whatever else is in scope
  Osysharp.Ui.Badge("new");        // a kit is an ordinary package, so the same spelling reaches it
  Osysharp.Button("hi");           // TWO segments — a different thing: the platform's ATOM
}

Description#

When you need it#

Most render blocks never contain one. Reach for it when:

SituationWhat happens bareThe qualified form
You declared a component with the same name as a package'sYours wins, everywhere — which is the point of osy get ui/<control>Osysharp.Ui.Card(…) reaches the package's
Two packages declare the nameRefused, naming both and offering both spellingsEither one, explicitly
A package keeps the declaration internalRefused, naming the packageAlso refused — see below

Two packages, one name#

If two packages in scope declare a Card, a bare Card(…) cannot mean one of them rather than the other, so it is a compile error that names both and both spellings:

`Card` is declared by 2 of the packages this app imports — `One.Kit` and `Two.Kit`. Name the one you mean: `One.Kit.Card(…)` or `Two.Kit.Card(…)`.

This is checked where you use the name, not where the packages are loaded: two packages may both ship a Card and your app may use neither, or use one of them by its qualified name throughout.

Declaring it yourself is the other answer, and often the better one. Your own declaration owns the name — no ambiguity, and every call site stays short:

[Composable] component Card(string title) { render { One.Kit.Card(title: title); } }

Your own declaration always wins#

A name your app declares beats any package's, with no ambiguity — the same rule C# applies to a using import. That is what makes forking safe: osy get ui/card writes the kit's Card into your ui/lib/, and from then on every Card(…) in your app — including inside the kit's own components that reference it by name — renders yours. The qualified spelling is how you reach the original when you want it side by side with your fork.

What it cannot reach#

A qualified name reaches a namespace's surface, never past it. A package's internal component or control is refused whichever way you spell it:

`Chevron` is internal to `One.Kit`, so it is not part of what that code offers. Only its public declarations are reachable from here.

See type visibility (public / internal) for the axis that decides this, and why it is a different question from [AllowAnonymous].

How the spelling is decided#

A qualified element is Owner.Name.Element — three or more segments. That is not arbitrary: a package's identity is its repository, so a package namespace is always at least two segments (package.osy). Two consequences you can rely on:

  • due.Add(p); is two segments, so it is still read as a method call used as a statement, and still gets the diagnostic written for that mistake. A render block declares values and draws them; it does not run statements.
  • Osysharp.Button("hi") is two segments, so it keeps its own meaning: the platform's atom, named explicitly because a control of that name shadows it. osy kit atoms lists those.

The namespace segments are PascalCase, which is how order.Lines.Clear(); — three segments, a lowercase receiver — stays a method call too.

Examples#

using Osysharp.Ui;

/// Our own `Card` — flatter than the kit's. Every bare `Card(…)` in this app is now this one.
[Composable] component Card(string title = "") {
  variants { base { Bg = Colors.Surface; P = Space.Gutter; } }
  render { Text(title, fontWeight: FontWeight.Semibold); }
}

[Route("/")] [AllowAnonymous] component Home() {
  render {
    Stack(gap: 2) {
      Card("ours");
      Osysharp.Ui.Card(title: "the kit's, for comparison");
    }
  }
}

See also#

Related

component

The one archetype for all UI: a bounded reactive unit — typed props, reactive members (fields, `live`…

control — foreign UI controls (charts, grids, maps)

A `control` block declares the contract of a foreign UI widget — a chart, a data grid, a map — that a small JavaScript…

type visibility (public / internal)

A top-level declaration carries a public or internal visibility that decides whether code outside its package can name…

namespace

Declares the namespace a file's types belong to, written once at the top of the file. It is optional — a file without…

package.osy

The manifest that makes a git repository a publishable Osy# package. It names the package, says which of the…

When your name is already the platform's

The platform puts 70 ordinary English words in scope in every app with no `using` — `Group`, `Match`, `Point`, `Month`…