citry-phosphor-icons
Phosphor Icons as citry components.
Install
pip install citry-phosphor-icons
The library configures itself through a citry extension, so install both:
import citry_phosphor_icons
from citry import Citry
from citry_phosphor_icons import PhosphorIcons
app = Citry(extensions=[PhosphorIcons])
app.register_library(citry_phosphor_icons)
Registration fails with a clear error if the extension is missing, so the two cannot drift apart.
Naming the tag
The component is <c-icon />. To publish it under a different tag, install the
manifest that library() builds:
app.register_library(citry_phosphor_icons.library("ph-icon"))
That gives <c-ph-icon /> and nothing else. A manifest owns the names it
publishes and citry will not retire one, so this replaces the default rather
than adding to it - install either this package or a named manifest, not both.
To keep <c-icon /> and answer to a second name as well, alias the installed
class instead:
from citry_phosphor_icons import Icon
installed = app.register_library(citry_phosphor_icons)
app.register(installed.component(Icon), "ph-icon")
Use
<c-icon name="house" />
<c-icon name="house" weight="bold" />
<c-icon name="house" style="stroke" c-size="24" color="#ff0000" />
| Kwarg | Type | Default | Description |
|---|---|---|---|
name |
str |
— | Icon name, e.g. "house" |
weight |
str |
engine default | bold, duotone, fill, light, regular, thin |
style |
str |
engine default | flat or stroke |
size |
str or int |
None |
Sets width and height; any CSS length ("1.5rem"), an int is read as px |
color |
str |
None |
Sets CSS color |
mirrored |
bool |
False |
Flips the icon horizontally |
attrs |
dict |
None |
Extra attributes passed to the <svg> element |
class and style from attrs are combined with the component's own, not
replaced by them - so passing c-attrs="{'class': 'me-2'}" keeps whatever the
component already sets, and size still wins over a conflicting width.
Settings
Defaults belong to the engine, not the process, so two Citry instances can
differ:
app = Citry(
extensions=[PhosphorIcons],
extensions_defaults={"phosphor": {"default_weight": "bold", "default_style": "stroke"}},
)
A caller's keyword argument beats the engine default, and a component may pin its own. Because a library definition cannot carry engine-specific fields, pin it on the installed class:
installed = app.register_library(citry_phosphor_icons)
class ThinIcon(installed.component(Icon)):
class Phosphor:
default_weight = "thin"
Unknown fields and invalid values are rejected when the engine is built, not at the first render.
Rendering is cached per unique set of keyword arguments. Citry reads
Cache.enabled as a literal on the component class, so turning it off is a
property of the manifest rather than an engine setting:
app.register_library(citry_phosphor_icons.library(cache=False))
Subclassing
Kwargs is inherited, so a subclass only declares what it changes.
get_attrs() returns what the component sets on the <svg> itself,
get_default_attrs() what the caller's attrs may override. Subclass the
definition and ship it as your own library:
from citry import ComponentLibrary, merge_attrs
from citry_phosphor_icons import Icon
class MyIcon(Icon):
def get_attrs(self, kwargs):
return merge_attrs({"class": "icon"}, super().get_attrs(kwargs))
__citry_library__ = ComponentLibrary(
name="my-icons",
components=(MyIcon,),
required_extensions=("phosphor",),
)
Previews
The component ships examples for citry's preview extension: one per weight and
style, plus the presentation arguments. preview_app.py in this repository
wires an engine for it:
uv run citry --app preview_app:app ext run preview serve
Open the printed gallery URL. Variants are plain keyword arguments rather than a preview template, so they keep working under a different tag name.
An icon carries no width or height of its own - it takes the size of its
surroundings, like a letter does. Every variant therefore asks for a size,
and the preview frame is only a little larger.
The gallery documents the component. For the icon set itself, browse the catalogue in py-phosphor-icons, which has search, a size slider and a colour picker across all 1512 icons in every weight and style.
Search and metadata
The icons, the loader and search over the icon metadata live in py-phosphor-icons, which this package builds on:
from py_phosphor_icons import get_svg, get_svg_inner, icon_names, search_icons
search_icons("arrow left") # ranked, best match first
search_icons("roledex") # matches on tags: address-book
get_svg("house", weight="bold")
The same search answers a wrong name, so <c-icon name="cart" /> raises
Did you mean: shopping-cart, shopping-cart-simple, car?, narrowed to icons
that exist in the requested weight and style.
Development
uv sync
uv run pytest
uv run ruff check .
uv run ruff format .
The icon set and its metadata are maintained in py-phosphor-icons; the sync scripts live there.
Known icon issues
A few icons are incomplete in the upstream Phosphor release and fail to render in certain weight and style combinations. The current list is maintained in py-phosphor-icons, which is where the icon set is synced.
Metadata
Release files for citry-phosphor-icons 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| citry_phosphor_icons-0.1.0.tar.gz | 46.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| citry_phosphor_icons-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.8 kB
Release files / citry_phosphor_icons-0.1.0.tar.gz
| Download URL | citry_phosphor_icons-0.1.0.tar.gz |
|---|---|
| Size | 46.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
41cf69801c744cadc5ceaec6682e00a6311fb1231255db6d8aef5591fee84314
|
|
BLAKE2b-256 checksum How to use checksums |
5f607d375eec316fd1311b769781f4e1f993a06464c25b9c2aceb38df40a1ddd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / citry_phosphor_icons-0.1.0-py3-none-any.whl
| Download URL | citry_phosphor_icons-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90462ce730acc095e6f95e2dfe1418425b10c5584bf8f1030e07b1ec56f81a61
|
|
BLAKE2b-256 checksum How to use checksums |
2cdcaa88032aa03bbf1d3aa749440888ae81d61d4efbf4dd2f46d44a9b61afe1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log