htmui 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. htmui-0.1.0/LICENSE +21 -0
  2. htmui-0.1.0/PKG-INFO +159 -0
  3. htmui-0.1.0/README.md +146 -0
  4. htmui-0.1.0/htmui/__init__.py +1 -0
  5. htmui-0.1.0/htmui/basecoat/__init__.py +0 -0
  6. htmui-0.1.0/htmui/basecoat/accordion.py +76 -0
  7. htmui-0.1.0/htmui/basecoat/alert.py +44 -0
  8. htmui-0.1.0/htmui/basecoat/avatar.py +52 -0
  9. htmui-0.1.0/htmui/basecoat/badge.py +32 -0
  10. htmui-0.1.0/htmui/basecoat/breadcrumb.py +46 -0
  11. htmui-0.1.0/htmui/basecoat/button.py +36 -0
  12. htmui-0.1.0/htmui/basecoat/button_group.py +22 -0
  13. htmui-0.1.0/htmui/basecoat/card.py +32 -0
  14. htmui-0.1.0/htmui/basecoat/cdn.py +14 -0
  15. htmui-0.1.0/htmui/basecoat/chart.py +86 -0
  16. htmui-0.1.0/htmui/basecoat/codeblock.py +109 -0
  17. htmui-0.1.0/htmui/basecoat/combobox.py +190 -0
  18. htmui-0.1.0/htmui/basecoat/command.py +128 -0
  19. htmui-0.1.0/htmui/basecoat/dialog.py +165 -0
  20. htmui-0.1.0/htmui/basecoat/drawer.py +66 -0
  21. htmui-0.1.0/htmui/basecoat/dropdown_menu.py +59 -0
  22. htmui-0.1.0/htmui/basecoat/field.py +91 -0
  23. htmui-0.1.0/htmui/basecoat/input_group.py +49 -0
  24. htmui-0.1.0/htmui/basecoat/item.py +94 -0
  25. htmui-0.1.0/htmui/basecoat/menu.py +131 -0
  26. htmui-0.1.0/htmui/basecoat/pagination.py +60 -0
  27. htmui-0.1.0/htmui/basecoat/popover.py +69 -0
  28. htmui-0.1.0/htmui/basecoat/progress.py +57 -0
  29. htmui-0.1.0/htmui/basecoat/radio_group.py +83 -0
  30. htmui-0.1.0/htmui/basecoat/select.py +190 -0
  31. htmui-0.1.0/htmui/basecoat/separator.py +8 -0
  32. htmui-0.1.0/htmui/basecoat/sidebar.py +270 -0
  33. htmui-0.1.0/htmui/basecoat/slider.py +50 -0
  34. htmui-0.1.0/htmui/basecoat/spinner.py +43 -0
  35. htmui-0.1.0/htmui/basecoat/switch.py +50 -0
  36. htmui-0.1.0/htmui/basecoat/table.py +38 -0
  37. htmui-0.1.0/htmui/basecoat/tabs.py +109 -0
  38. htmui-0.1.0/htmui/basecoat/theme_switcher.py +58 -0
  39. htmui-0.1.0/htmui/basecoat/toast.py +97 -0
  40. htmui-0.1.0/htmui/basecoat/typing.py +21 -0
  41. htmui-0.1.0/htmui/cli.py +257 -0
  42. htmui-0.1.0/pyproject.toml +110 -0
htmui-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Peter Volf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
htmui-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.1
2
+ Name: htmui
3
+ Version: 0.1.0
4
+ Summary: htmy component library
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: fastapi[standard]>=0.136.3
7
+ Requires-Dist: holm>=0.10.0
8
+ Requires-Dist: htmy[lxml]>=0.13.1
9
+ Requires-Dist: pydantic-settings>=2.15.0
10
+ Requires-Dist: typer>=0.27.1
11
+ Requires-Dist: uvicorn>=0.52.1
12
+ Description-Content-Type: text/markdown
13
+
14
+ ![Linters](https://github.com/volfpeter/htmui/actions/workflows/linters.yml/badge.svg)
15
+
16
+ **Source code**: [https://github.com/volfpeter/htmui](https://github.com/volfpeter/htmui)
17
+
18
+ **Live demo**: [https://htmui.vercel.app](https://htmui.vercel.app)
19
+
20
+ # htmui
21
+
22
+ Python UI components for [htmy](https://volfpeter.github.io/htmy/), wrapping [BasecoatUI](https://basecoatui.com/) and [Tailwind CSS](https://tailwindcss.com/).
23
+
24
+ `htmui` is designed with hypermedia applications, and specifically [HTMX](https://htmx.org/), in mind. Components reproduce Basecoat's documented markup so Basecoat's runtime can enhance them.
25
+
26
+ `htmy` and `holm` have built-in Jinja support. If you use another templating engine, converting the components is straightforward, because `htmy` mimics HTML.
27
+
28
+ ## Key features
29
+
30
+ - **Vendored**: copy the components you need into your project and adapt them.
31
+ - **`htmui init` CLI** that copies selected components, their dependencies, and shared utilities.
32
+ - **BasecoatUI** components as typed `htmy` functions: buttons, dialogs, sidebars, forms, and more.
33
+ - Extra helpers such as `codeblock` that are not part of Basecoat.
34
+ - Works anywhere `htmy` works, including [holm](https://volfpeter.github.io/holm/).
35
+
36
+ ## Prerequisites
37
+
38
+ You need [htmy](https://volfpeter.github.io/htmy/) in your project:
39
+
40
+ ```bash
41
+ pip install htmy
42
+ ```
43
+
44
+ For the best developer experience, it is recommended to use [holm](https://volfpeter.github.io/holm/). It brings built-in `htmy` and HTMX support, and is built around FastAPI.
45
+
46
+ The copied components also need [BasecoatUI](https://basecoatui.com/) and [Tailwind CSS](https://tailwindcss.com/) on the page. CDN snippets are included (see [Assets](#assets)).
47
+
48
+ ## Usage
49
+
50
+ `htmui` is designed to be vendored. You do not install it as a runtime dependency. Instead, you copy the components you need into your project and adjust them.
51
+
52
+ ```bash
53
+ uvx htmui init
54
+ ```
55
+
56
+ This copies the full catalog into `./components`. Use `-c` to copy only the components you need. Dependencies are included automatically:
57
+
58
+ ```bash
59
+ uvx htmui init -c dialog -c select
60
+ ```
61
+
62
+ Useful options:
63
+
64
+ ```bash
65
+ uvx htmui init --src # install into src/components/
66
+ uvx htmui init -p ui # install into ./ui
67
+ uvx htmui init -c dialog --dry-run # print the plan, write nothing
68
+ uvx htmui init --force # overwrite existing files
69
+ uvx htmui init --skip-existing # keep existing files
70
+ uvx htmui version # package and per-component versions
71
+ ```
72
+
73
+ You can also copy files from `htmui/basecoat/` by hand.
74
+
75
+ ### Example
76
+
77
+ After `htmui init`:
78
+
79
+ ```python
80
+ from htmy import ComponentType, html
81
+
82
+ from components.alert import alert
83
+ from components.button import button
84
+
85
+
86
+ def saved() -> ComponentType:
87
+ return html.div(
88
+ alert("Your changes have been saved.", title="Saved"),
89
+ button("Continue"),
90
+ )
91
+ ```
92
+
93
+ Every component has a live example and its Python source in the sidebar.
94
+
95
+ ## Assets
96
+
97
+ You can add the CDN snippets from `cdn` to your document head:
98
+
99
+ ```python
100
+ from htmy import ComponentType, html
101
+
102
+ from components import cdn
103
+
104
+
105
+ def head() -> ComponentType:
106
+ return html.head(
107
+ cdn.css,
108
+ cdn.tailwind_css,
109
+ cdn.js,
110
+ )
111
+ ```
112
+
113
+ Some Basecoat classes may not work with the Tailwind CDN setup, so a local JS/CSS setup is recommended for production. The [demo application](https://github.com/volfpeter/htmui/tree/main/app) shows one such setup.
114
+
115
+ `codeblock` includes optional [Highlight.js](https://highlightjs.org/) helpers for syntax highlighting.
116
+
117
+ ## Related projects
118
+
119
+ - [htmy](https://volfpeter.github.io/htmy/): async Python server-side rendering.
120
+ - [holm](https://volfpeter.github.io/holm/): Next.js-like developer experience on FastAPI, `htmy`, and FastHX.
121
+ - [FastHX](https://volfpeter.github.io/fasthx/): HTMX rendering for FastAPI.
122
+ - [BasecoatUI](https://basecoatui.com/): the design system these components wrap.
123
+
124
+ ## Support
125
+
126
+ Consider supporting the project through [sponsoring](https://buymeacoffee.com/volfpeter), or reach out for [consulting](https://www.volfp.com/contact?subject=Consulting%20-%20htmui) so you can get the most out of the library.
127
+
128
+ ## Development
129
+
130
+ Python:
131
+
132
+ - `uv` for project and dependency management.
133
+ - `poethepoet` for tasks. Run `uv run poe` to see them.
134
+ - `mypy` for static analysis.
135
+ - `ruff` for formatting and linting.
136
+
137
+ JavaScript:
138
+
139
+ - `npm` for the demo app's Tailwind and Basecoat tooling.
140
+
141
+ To get started:
142
+
143
+ ```bash
144
+ uv sync
145
+ npm install
146
+ honcho start
147
+ ```
148
+
149
+ `honcho start` runs the demo app and the Tailwind watcher together. You can also run `uv run poe dev` and `uv run poe build-dev-css --watch` separately.
150
+
151
+ The index page of the demo is generated from this README (`uv run poe build-content`).
152
+
153
+ ## License
154
+
155
+ The package is open-sourced under the conditions of the [MIT license](https://choosealicense.com/licenses/mit/).
156
+
157
+ ## Credits
158
+
159
+ This project wouldn't exist without the components and documentation of [BasecoatUI](https://basecoatui.com/).
htmui-0.1.0/README.md ADDED
@@ -0,0 +1,146 @@
1
+ ![Linters](https://github.com/volfpeter/htmui/actions/workflows/linters.yml/badge.svg)
2
+
3
+ **Source code**: [https://github.com/volfpeter/htmui](https://github.com/volfpeter/htmui)
4
+
5
+ **Live demo**: [https://htmui.vercel.app](https://htmui.vercel.app)
6
+
7
+ # htmui
8
+
9
+ Python UI components for [htmy](https://volfpeter.github.io/htmy/), wrapping [BasecoatUI](https://basecoatui.com/) and [Tailwind CSS](https://tailwindcss.com/).
10
+
11
+ `htmui` is designed with hypermedia applications, and specifically [HTMX](https://htmx.org/), in mind. Components reproduce Basecoat's documented markup so Basecoat's runtime can enhance them.
12
+
13
+ `htmy` and `holm` have built-in Jinja support. If you use another templating engine, converting the components is straightforward, because `htmy` mimics HTML.
14
+
15
+ ## Key features
16
+
17
+ - **Vendored**: copy the components you need into your project and adapt them.
18
+ - **`htmui init` CLI** that copies selected components, their dependencies, and shared utilities.
19
+ - **BasecoatUI** components as typed `htmy` functions: buttons, dialogs, sidebars, forms, and more.
20
+ - Extra helpers such as `codeblock` that are not part of Basecoat.
21
+ - Works anywhere `htmy` works, including [holm](https://volfpeter.github.io/holm/).
22
+
23
+ ## Prerequisites
24
+
25
+ You need [htmy](https://volfpeter.github.io/htmy/) in your project:
26
+
27
+ ```bash
28
+ pip install htmy
29
+ ```
30
+
31
+ For the best developer experience, it is recommended to use [holm](https://volfpeter.github.io/holm/). It brings built-in `htmy` and HTMX support, and is built around FastAPI.
32
+
33
+ The copied components also need [BasecoatUI](https://basecoatui.com/) and [Tailwind CSS](https://tailwindcss.com/) on the page. CDN snippets are included (see [Assets](#assets)).
34
+
35
+ ## Usage
36
+
37
+ `htmui` is designed to be vendored. You do not install it as a runtime dependency. Instead, you copy the components you need into your project and adjust them.
38
+
39
+ ```bash
40
+ uvx htmui init
41
+ ```
42
+
43
+ This copies the full catalog into `./components`. Use `-c` to copy only the components you need. Dependencies are included automatically:
44
+
45
+ ```bash
46
+ uvx htmui init -c dialog -c select
47
+ ```
48
+
49
+ Useful options:
50
+
51
+ ```bash
52
+ uvx htmui init --src # install into src/components/
53
+ uvx htmui init -p ui # install into ./ui
54
+ uvx htmui init -c dialog --dry-run # print the plan, write nothing
55
+ uvx htmui init --force # overwrite existing files
56
+ uvx htmui init --skip-existing # keep existing files
57
+ uvx htmui version # package and per-component versions
58
+ ```
59
+
60
+ You can also copy files from `htmui/basecoat/` by hand.
61
+
62
+ ### Example
63
+
64
+ After `htmui init`:
65
+
66
+ ```python
67
+ from htmy import ComponentType, html
68
+
69
+ from components.alert import alert
70
+ from components.button import button
71
+
72
+
73
+ def saved() -> ComponentType:
74
+ return html.div(
75
+ alert("Your changes have been saved.", title="Saved"),
76
+ button("Continue"),
77
+ )
78
+ ```
79
+
80
+ Every component has a live example and its Python source in the sidebar.
81
+
82
+ ## Assets
83
+
84
+ You can add the CDN snippets from `cdn` to your document head:
85
+
86
+ ```python
87
+ from htmy import ComponentType, html
88
+
89
+ from components import cdn
90
+
91
+
92
+ def head() -> ComponentType:
93
+ return html.head(
94
+ cdn.css,
95
+ cdn.tailwind_css,
96
+ cdn.js,
97
+ )
98
+ ```
99
+
100
+ Some Basecoat classes may not work with the Tailwind CDN setup, so a local JS/CSS setup is recommended for production. The [demo application](https://github.com/volfpeter/htmui/tree/main/app) shows one such setup.
101
+
102
+ `codeblock` includes optional [Highlight.js](https://highlightjs.org/) helpers for syntax highlighting.
103
+
104
+ ## Related projects
105
+
106
+ - [htmy](https://volfpeter.github.io/htmy/): async Python server-side rendering.
107
+ - [holm](https://volfpeter.github.io/holm/): Next.js-like developer experience on FastAPI, `htmy`, and FastHX.
108
+ - [FastHX](https://volfpeter.github.io/fasthx/): HTMX rendering for FastAPI.
109
+ - [BasecoatUI](https://basecoatui.com/): the design system these components wrap.
110
+
111
+ ## Support
112
+
113
+ Consider supporting the project through [sponsoring](https://buymeacoffee.com/volfpeter), or reach out for [consulting](https://www.volfp.com/contact?subject=Consulting%20-%20htmui) so you can get the most out of the library.
114
+
115
+ ## Development
116
+
117
+ Python:
118
+
119
+ - `uv` for project and dependency management.
120
+ - `poethepoet` for tasks. Run `uv run poe` to see them.
121
+ - `mypy` for static analysis.
122
+ - `ruff` for formatting and linting.
123
+
124
+ JavaScript:
125
+
126
+ - `npm` for the demo app's Tailwind and Basecoat tooling.
127
+
128
+ To get started:
129
+
130
+ ```bash
131
+ uv sync
132
+ npm install
133
+ honcho start
134
+ ```
135
+
136
+ `honcho start` runs the demo app and the Tailwind watcher together. You can also run `uv run poe dev` and `uv run poe build-dev-css --watch` separately.
137
+
138
+ The index page of the demo is generated from this README (`uv run poe build-content`).
139
+
140
+ ## License
141
+
142
+ The package is open-sourced under the conditions of the [MIT license](https://choosealicense.com/licenses/mit/).
143
+
144
+ ## Credits
145
+
146
+ This project wouldn't exist without the components and documentation of [BasecoatUI](https://basecoatui.com/).
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
File without changes
@@ -0,0 +1,76 @@
1
+ from htmy import ComponentType, PropertyValue, SafeStr, XBool, html, join_classes
2
+
3
+ __version__ = "0.2.0"
4
+ __framework__ = "BasecoatUI"
5
+ __framework_version__ = "1"
6
+ __framework_url__ = "https://basecoatui.com/components/accordion/"
7
+
8
+ js = SafeStr(
9
+ '<script src="https://cdn.jsdelivr.net/npm/basecoat-css@1/dist/js/accordion.min.js" defer></script>'
10
+ )
11
+
12
+ accordion_icon = SafeStr(
13
+ '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" '
14
+ 'stroke="currentColor">'
15
+ '<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>'
16
+ )
17
+ """`chevron-down` icon from https://heroicons.com/."""
18
+
19
+
20
+ def accordion_item(
21
+ *content: ComponentType,
22
+ summary: ComponentType,
23
+ open: bool = False,
24
+ disabled: bool = False,
25
+ icon: ComponentType | None = accordion_icon,
26
+ class_: str | None = None,
27
+ **kwargs: PropertyValue,
28
+ ) -> ComponentType:
29
+ """
30
+ Accordion item.
31
+
32
+ Arguments:
33
+ *content: The content of the accordion item.
34
+ summary: The summary (trigger) of the item.
35
+ open: Whether the item is open by default.
36
+ disabled: Whether the item is disabled.
37
+ icon: Optional trailing icon in the summary. Defaults to a chevron icon.
38
+ class_: Extra CSS classes for the root component.
39
+ **kwargs: Extra attributes for the root component.
40
+ """
41
+ if open:
42
+ kwargs["open"] = XBool.true
43
+ if disabled:
44
+ kwargs["aria_disabled"] = "true"
45
+
46
+ return html.details(
47
+ html.summary(summary, icon),
48
+ html.section(*content),
49
+ class_=class_,
50
+ **kwargs,
51
+ )
52
+
53
+
54
+ def accordion(
55
+ *children: ComponentType,
56
+ multiple: bool = False,
57
+ class_: str | None = None,
58
+ **kwargs: PropertyValue,
59
+ ) -> ComponentType:
60
+ """
61
+ Accordion root. Children are usually created with `accordion_item()`.
62
+
63
+ Arguments:
64
+ *children: Accordion items.
65
+ multiple: Allow more than one item open at a time.
66
+ class_: Extra CSS classes for the root component.
67
+ **kwargs: Extra attributes for the root component.
68
+ """
69
+ if multiple:
70
+ kwargs["data_multiple"] = ""
71
+
72
+ return html.section(
73
+ *children,
74
+ class_=join_classes("accordion", class_),
75
+ **kwargs,
76
+ )
@@ -0,0 +1,44 @@
1
+ from htmy import ComponentType, PropertyValue, html, join_classes
2
+
3
+ __version__ = "0.2.0"
4
+ __framework__ = "BasecoatUI"
5
+ __framework_version__ = "1"
6
+ __framework_url__ = "https://basecoatui.com/components/alert/"
7
+
8
+
9
+ def alert(
10
+ *children: ComponentType,
11
+ title: ComponentType,
12
+ icon: ComponentType = None,
13
+ footer: ComponentType | None = None,
14
+ class_: str | None = None,
15
+ content_class: str | None = None,
16
+ title_class: str | None = None,
17
+ destructive: bool = False,
18
+ **kwargs: PropertyValue,
19
+ ) -> ComponentType:
20
+ """
21
+ Alert component with optional icon, description, and action region.
22
+
23
+ Arguments:
24
+ *children: Optional content below the title.
25
+ title: Alert title.
26
+ icon: Optional icon.
27
+ footer: Optional footer, typically an `html.footer(...)`.
28
+ class_: Extra CSS classes for the root element.
29
+ content_class: Extra CSS classes for the description section.
30
+ title_class: Extra CSS classes for the title.
31
+ destructive: Whether to use the destructive variant.
32
+ **kwargs: Extra attributes for the root element.
33
+ """
34
+ if destructive:
35
+ kwargs["data_variant"] = "destructive"
36
+
37
+ return html.div(
38
+ icon,
39
+ html.h2(title, class_=title_class),
40
+ html.section(*children, class_=content_class) if len(children) > 0 else None,
41
+ footer,
42
+ class_=join_classes("alert", class_),
43
+ **kwargs,
44
+ )
@@ -0,0 +1,52 @@
1
+ from typing import Literal, TypeAlias
2
+
3
+ from htmy import ComponentType, PropertyValue, html, join_classes
4
+
5
+ __version__ = "0.2.0"
6
+ __framework__ = "BasecoatUI"
7
+ __framework_version__ = "1"
8
+ __framework_url__ = "https://basecoatui.com/components/avatar/"
9
+
10
+ AvatarSize: TypeAlias = Literal["sm", "lg"]
11
+
12
+
13
+ def avatar(
14
+ *children: ComponentType,
15
+ size: AvatarSize | None = None,
16
+ class_: str | None = None,
17
+ **kwargs: PropertyValue,
18
+ ) -> ComponentType:
19
+ """
20
+ Avatar component.
21
+
22
+ Arguments:
23
+ *children: Avatar content.
24
+ size: Avatar size.
25
+ class_: Extra CSS classes for the avatar.
26
+ **kwargs: Extra attributes for the avatar.
27
+ """
28
+ if size is not None:
29
+ kwargs["data_size"] = size
30
+
31
+ return html.span(*children, class_=join_classes("avatar", class_), **kwargs)
32
+
33
+
34
+ def avatar_group(
35
+ *children: ComponentType,
36
+ count: ComponentType | str | None = None,
37
+ class_: str | None = None,
38
+ **kwargs: PropertyValue,
39
+ ) -> ComponentType:
40
+ """
41
+ Group of overlapping avatars with an optional trailing count indicator.
42
+
43
+ Arguments:
44
+ *children: Avatar components.
45
+ count: Content of the trailing `data-count` indicator.
46
+ class_: Extra CSS classes for the group.
47
+ **kwargs: Extra attributes for the root element.
48
+ """
49
+ if count is not None:
50
+ children = (*children, html.span(count, data_count=""))
51
+
52
+ return html.div(*children, class_=join_classes("avatar-group", class_), **kwargs)
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Literal
4
+
5
+ from htmy import html
6
+ from htmy.utils import join
7
+
8
+ if TYPE_CHECKING:
9
+ from htmy import ComponentType, PropertyValue
10
+
11
+
12
+ __version__ = "0.2.0"
13
+ __framework__ = "BasecoatUI"
14
+ __framework_version__ = "1"
15
+ __framework_url__ = "https://basecoatui.com/components/badge/"
16
+
17
+ BadgeVariant = Literal["secondary", "destructive", "outline", "ghost"]
18
+
19
+
20
+ def badge(
21
+ *children: ComponentType,
22
+ variant: BadgeVariant | None = None,
23
+ class_: str | None = None,
24
+ **kwargs: PropertyValue,
25
+ ) -> ComponentType:
26
+ if variant is not None:
27
+ kwargs["data_variant"] = variant
28
+ return html.span(
29
+ *children,
30
+ class_=join("badge", class_),
31
+ **kwargs,
32
+ )
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+
3
+ from htmy import ComponentType, PropertyValue, SafeStr, html
4
+ from htmy.utils import join, join_components
5
+
6
+ __version__ = "0.2.0"
7
+ __framework__ = "BasecoatUI"
8
+ __framework_version__ = "1"
9
+ __framework_url__ = "https://basecoatui.com/components/breadcrumb/"
10
+
11
+ chevron_right_icon = SafeStr(
12
+ '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" '
13
+ 'stroke="currentColor" class="size-4"><path stroke-linecap="round" stroke-linejoin="round" '
14
+ 'd="m8.25 4.5 7.5 7.5-7.5 7.5" /></svg>'
15
+ )
16
+ """`chevron-right` icon from https://heroicons.com/ with small adjustments."""
17
+
18
+
19
+ def breadcrumb(
20
+ *children: ComponentType,
21
+ separator: ComponentType = chevron_right_icon,
22
+ class_: str | None = None,
23
+ aria_label: str = "Breadcrumb",
24
+ **kwargs: PropertyValue,
25
+ ) -> ComponentType:
26
+ """
27
+ Breadcrumb navigation component.
28
+
29
+ Arguments:
30
+ *children: Breadcrumb items.
31
+ separator: Separator to be inserted between items.
32
+ class_: Extra CSS classes for the root element.
33
+ aria_label: Accessible name for the breadcrumb.
34
+ **kwargs: Extra attributes for the root element.
35
+ """
36
+ return html.nav(
37
+ html.ol(
38
+ *join_components(
39
+ tuple(html.li(child) for child in children if child is not None),
40
+ html.li(separator, aria_hidden="true"),
41
+ ),
42
+ ),
43
+ class_=join("breadcrumb", class_),
44
+ aria_label=aria_label,
45
+ **kwargs,
46
+ )
@@ -0,0 +1,36 @@
1
+ from typing import Literal, TypeAlias
2
+
3
+ from htmy import ComponentType, PropertyValue, html, join_classes
4
+
5
+ __version__ = "0.2.0"
6
+ __framework__ = "BasecoatUI"
7
+ __framework_version__ = "1"
8
+ __framework_url__ = "https://basecoatui.com/components/button/"
9
+
10
+ ButtonVariant: TypeAlias = Literal["outline", "secondary", "ghost", "destructive", "link"]
11
+
12
+ ButtonSize: TypeAlias = Literal["xs", "sm", "default", "lg", "icon", "icon-xs", "icon-sm", "icon-lg"]
13
+
14
+
15
+ def button(
16
+ *children: ComponentType,
17
+ variant: ButtonVariant | None = None,
18
+ size: ButtonSize | None = None,
19
+ class_: str | None = None,
20
+ **kwargs: PropertyValue,
21
+ ) -> ComponentType:
22
+ """
23
+ Button component.
24
+
25
+ Arguments:
26
+ *children: Button content.
27
+ variant: Button variant.
28
+ size: Button size.
29
+ class_: Extra CSS classes for the button.
30
+ **kwargs: Extra attributes for the button.
31
+ """
32
+ if variant is not None:
33
+ kwargs["data_variant"] = variant
34
+ if size is not None:
35
+ kwargs["data_size"] = size
36
+ return html.button(*children, class_=join_classes("btn", class_), type_="button", **kwargs)
@@ -0,0 +1,22 @@
1
+ from htmy import ComponentType, PropertyValue, html
2
+ from htmy.utils import join
3
+
4
+ __version__ = "0.2.0"
5
+ __framework__ = "BasecoatUI"
6
+ __framework_version__ = "1"
7
+ __framework_url__ = "https://basecoatui.com/components/button-group/"
8
+
9
+
10
+ def button_group(
11
+ *children: ComponentType,
12
+ class_: str = "",
13
+ vertical: bool = False,
14
+ **kwargs: PropertyValue,
15
+ ) -> ComponentType:
16
+ if "role" not in kwargs:
17
+ kwargs["role"] = "group"
18
+
19
+ if vertical:
20
+ kwargs["data-orientation"] = "vertical"
21
+
22
+ return html.div(*children, class_=join("button-group", class_), **kwargs)
@@ -0,0 +1,32 @@
1
+ from typing import Literal
2
+
3
+ from htmy import ComponentType, PropertyValue, html
4
+ from htmy.utils import join
5
+
6
+ __version__ = "0.2.0"
7
+ __framework__ = "BasecoatUI"
8
+ __framework_version__ = "1"
9
+ __framework_url__ = "https://basecoatui.com/components/card/"
10
+
11
+ CardSize = Literal["sm"]
12
+
13
+
14
+ def card(
15
+ *children: ComponentType,
16
+ class_: str | None = None,
17
+ size: CardSize | None = None,
18
+ **kwargs: PropertyValue,
19
+ ) -> ComponentType:
20
+ """
21
+ Card container.
22
+
23
+ Arguments:
24
+ *children: Card content.
25
+ class_: Extra CSS classes for the root element.
26
+ size: Optional denser layout size.
27
+ **kwargs: Extra attributes for the root element.
28
+ """
29
+ if size is not None:
30
+ kwargs["data_size"] = size
31
+
32
+ return html.div(*children, class_=join("card", class_), **kwargs)