@dogsbay/ui 0.2.0-beta.127 → 0.2.0-beta.129
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.
- package/package.json +4 -4
- package/src/alert/CollapsibleAlert.astro +11 -5
- package/src/alert/icon.ts +8 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dogsbay/ui",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.129",
|
|
4
4
|
"description": "Accessible UI components for Astro, inspired by Base UI and shadcn",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"katex": "^0.16.47",
|
|
23
23
|
"maplibre-gl": "^5.24.0",
|
|
24
24
|
"shiki": "^4.3.1",
|
|
25
|
-
"@dogsbay/elements": "0.2.0-beta.
|
|
26
|
-
"@dogsbay/icons": "0.2.0-beta.
|
|
27
|
-
"@dogsbay/primitives": "0.2.0-beta.
|
|
25
|
+
"@dogsbay/elements": "0.2.0-beta.129",
|
|
26
|
+
"@dogsbay/icons": "0.2.0-beta.129",
|
|
27
|
+
"@dogsbay/primitives": "0.2.0-beta.129"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"src",
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* Composes with the same variant tokens as Alert.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
* <CollapsibleAlert variant="warning" title="Warning" open>
|
|
9
|
+
* <CollapsibleAlert variant="warning" title="Warning" icon="lucide:rocket" open>
|
|
10
10
|
* <p>Body content here.</p>
|
|
11
11
|
* </CollapsibleAlert>
|
|
12
|
+
*
|
|
13
|
+
* A title with markup goes in the `title` slot: `<Fragment slot="title">Run <code>init</code></Fragment>`.
|
|
12
14
|
*/
|
|
13
15
|
import { tv, type VariantProps } from "tailwind-variants";
|
|
14
16
|
import { contentVariants, icons, chevronSvg } from "./variants.js";
|
|
17
|
+
import { resolveIcon } from "./icon.js";
|
|
15
18
|
|
|
16
19
|
const wrapper = tv({
|
|
17
20
|
base: "relative w-full rounded-lg border overflow-hidden [&>summary]:list-none [&>summary::-webkit-details-marker]:hidden",
|
|
@@ -80,20 +83,23 @@ interface Props {
|
|
|
80
83
|
title?: string;
|
|
81
84
|
/** Whether the details starts open */
|
|
82
85
|
open?: boolean;
|
|
86
|
+
/** An icon name in place of the variant's (`lucide:rocket`, `compass`, an emoji shortcode); unknown names keep the variant's. */
|
|
87
|
+
icon?: string;
|
|
83
88
|
class?: string;
|
|
84
89
|
/** id, data-*, aria-*: passed to the <details> (an `id` is a link target) */
|
|
85
90
|
[key: string]: unknown;
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
|
|
89
|
-
const { variant = "note", title, open = false, class: className, icon: _icon, ...rest } = Astro.props;
|
|
93
|
+
const { variant = "note", title, open = false, class: className, icon: iconName, ...rest } = Astro.props;
|
|
90
94
|
const v = variant || "note";
|
|
91
95
|
|
|
92
96
|
// `plain` is chrome — a disclosure, nothing more. No role at all:
|
|
93
97
|
// role="note"/"status" on collapsed context misinforms assistive tech
|
|
94
98
|
// (and "status" would make it a live region).
|
|
95
99
|
const role = v === "plain" ? undefined : contentVariants.has(v) ? "note" : "status";
|
|
96
|
-
|
|
100
|
+
// The author's icon, as Alert draws it; else the variant's (`plain` has none)
|
|
101
|
+
const icon = (iconName ? resolveIcon(iconName) : null) ?? (contentVariants.has(v) ? icons[v] : null);
|
|
102
|
+
const fallbackTitle = title || v.charAt(0).toUpperCase() + v.slice(1);
|
|
97
103
|
---
|
|
98
104
|
|
|
99
105
|
{/*
|
|
@@ -114,7 +120,7 @@ const icon = contentVariants.has(v) ? icons[v] : null;
|
|
|
114
120
|
titleBg[v],
|
|
115
121
|
]}>
|
|
116
122
|
{icon && <span class:list={["shrink-0 [&>svg]:size-4", iconColor[v]]} set:html={icon} />}
|
|
117
|
-
<span class="flex-1 text-foreground" data-part="title">{
|
|
123
|
+
<span class="flex-1 text-foreground" data-part="title"><slot name="title">{fallbackTitle}</slot></span>
|
|
118
124
|
<span class="shrink-0 text-muted-foreground group-open/collapsible:rotate-180 transition-transform duration-200" set:html={chevronSvg} />
|
|
119
125
|
</summary>
|
|
120
126
|
<div class:list={["px-4 py-3 text-sm [&_p]:leading-relaxed", bodyBg[v]]} role={role}>
|
package/src/alert/icon.ts
CHANGED
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve an icon
|
|
2
|
+
* Resolve an icon name for Alert and CollapsibleAlert.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - `
|
|
6
|
-
* - bare
|
|
4
|
+
* The same names as Icon.astro and dogsbay-ssg (`@dogsbay/icons` resolveIcon):
|
|
5
|
+
* - `pack:name` — e.g. "lucide:rocket", "material:check-circle", "simple:github"
|
|
6
|
+
* - a bare name — an emoji shortcode first ("rocket" → 🚀), then a Lucide icon ("compass")
|
|
7
7
|
*
|
|
8
8
|
* Returns an inline SVG string or a span with the emoji character. Returns
|
|
9
|
-
* null when the
|
|
9
|
+
* null when the name can't be resolved (caller should fall back to the
|
|
10
10
|
* variant's default icon).
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
const registry = createIconRegistry();
|
|
12
|
+
import { resolveIcon as resolveName } from "@dogsbay/icons";
|
|
15
13
|
|
|
16
14
|
export function resolveIcon(shortcode: string): string | null {
|
|
17
|
-
const
|
|
18
|
-
const [library, name] = colonIdx >= 0
|
|
19
|
-
? [shortcode.slice(0, colonIdx), shortcode.slice(colonIdx + 1)]
|
|
20
|
-
: ["emoji", shortcode];
|
|
21
|
-
|
|
22
|
-
const resolved = registry.resolve(library, name);
|
|
15
|
+
const resolved = resolveName(shortcode);
|
|
23
16
|
if (!resolved) return null;
|
|
24
17
|
|
|
25
18
|
// Emoji resolve to Unicode characters; wrap for consistent sizing/positioning
|
|
26
19
|
// with the SVG icons in the Alert layout.
|
|
27
|
-
if (
|
|
20
|
+
if (!resolved.startsWith("<")) {
|
|
28
21
|
return `<span aria-hidden="true" style="font-size:1em;line-height:1;display:inline-block;width:1em;text-align:center;">${resolved}</span>`;
|
|
29
22
|
}
|
|
30
23
|
|