@blurrow/ui 0.1.0 → 0.2.1
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/README.md +60 -20
- package/dist/Accordion.d.ts +17 -0
- package/dist/Accordion.js +138 -0
- package/dist/Accordion.js.map +1 -0
- package/dist/Alert.d.ts +13 -0
- package/dist/Alert.js +69 -0
- package/dist/Alert.js.map +1 -0
- package/dist/AuthorCard.d.ts +12 -0
- package/dist/AuthorCard.js +57 -0
- package/dist/AuthorCard.js.map +1 -0
- package/dist/Avatar.d.ts +21 -0
- package/dist/Avatar.js +96 -0
- package/dist/Avatar.js.map +1 -0
- package/dist/Badge.d.ts +12 -0
- package/dist/Badge.js +46 -0
- package/dist/Badge.js.map +1 -0
- package/dist/Banner.d.ts +15 -0
- package/dist/Banner.js +68 -0
- package/dist/Banner.js.map +1 -0
- package/dist/Breadcrumb.d.ts +13 -0
- package/dist/Breadcrumb.js +45 -0
- package/dist/Breadcrumb.js.map +1 -0
- package/dist/Button.d.ts +19 -0
- package/dist/Button.js +282 -0
- package/dist/Button.js.map +1 -0
- package/dist/ButtonGroup.d.ts +19 -0
- package/dist/ButtonGroup.js +62 -0
- package/dist/ButtonGroup.js.map +1 -0
- package/dist/Card.d.ts +40 -0
- package/dist/Card.js +175 -0
- package/dist/Card.js.map +1 -0
- package/dist/CardShell.d.ts +18 -0
- package/dist/CardShell.js +58 -0
- package/dist/CardShell.js.map +1 -0
- package/dist/Carousel.d.ts +22 -0
- package/dist/Carousel.js +247 -0
- package/dist/Carousel.js.map +1 -0
- package/dist/Checkbox.d.ts +15 -0
- package/dist/Checkbox.js +84 -0
- package/dist/Checkbox.js.map +1 -0
- package/dist/CloseButton.d.ts +12 -0
- package/dist/CloseButton.js +63 -0
- package/dist/CloseButton.js.map +1 -0
- package/dist/CodeBlock.d.ts +12 -0
- package/dist/CodeBlock.js +221 -0
- package/dist/CodeBlock.js.map +1 -0
- package/dist/ColorPicker.d.ts +24 -0
- package/dist/ColorPicker.js +366 -0
- package/dist/ColorPicker.js.map +1 -0
- package/dist/Combobox.d.ts +34 -0
- package/dist/Combobox.js +255 -0
- package/dist/Combobox.js.map +1 -0
- package/dist/CommandPalette.d.ts +25 -0
- package/dist/CommandPalette.js +304 -0
- package/dist/CommandPalette.js.map +1 -0
- package/dist/ContextMenu.d.ts +16 -0
- package/dist/ContextMenu.js +209 -0
- package/dist/ContextMenu.js.map +1 -0
- package/dist/DataList.d.ts +15 -0
- package/dist/DataList.js +42 -0
- package/dist/DataList.js.map +1 -0
- package/dist/DatePicker.d.ts +65 -0
- package/dist/DatePicker.js +391 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/DateRangePicker.d.ts +34 -0
- package/dist/DateRangePicker.js +180 -0
- package/dist/DateRangePicker.js.map +1 -0
- package/dist/Drawer.d.ts +17 -0
- package/dist/Drawer.js +132 -0
- package/dist/Drawer.js.map +1 -0
- package/dist/DropdownMenu.d.ts +23 -0
- package/dist/DropdownMenu.js +185 -0
- package/dist/DropdownMenu.js.map +1 -0
- package/dist/EmptyState.d.ts +13 -0
- package/dist/EmptyState.js +55 -0
- package/dist/EmptyState.js.map +1 -0
- package/dist/FieldMessage.d.ts +26 -0
- package/dist/FieldMessage.js +95 -0
- package/dist/FieldMessage.js.map +1 -0
- package/dist/FileUpload.d.ts +32 -0
- package/dist/FileUpload.js +253 -0
- package/dist/FileUpload.js.map +1 -0
- package/dist/Floating.d.ts +32 -0
- package/dist/Floating.js +95 -0
- package/dist/Floating.js.map +1 -0
- package/dist/HoverCard.d.ts +18 -0
- package/dist/HoverCard.js +90 -0
- package/dist/HoverCard.js.map +1 -0
- package/dist/Input.d.ts +17 -0
- package/dist/Input.js +96 -0
- package/dist/Input.js.map +1 -0
- package/dist/Kbd.d.ts +9 -0
- package/dist/Kbd.js +24 -0
- package/dist/Kbd.js.map +1 -0
- package/dist/Modal.d.ts +15 -0
- package/dist/Modal.js +109 -0
- package/dist/Modal.js.map +1 -0
- package/dist/NumberInput.d.ts +23 -0
- package/dist/NumberInput.js +162 -0
- package/dist/NumberInput.js.map +1 -0
- package/dist/OtpInput.d.ts +26 -0
- package/dist/OtpInput.js +173 -0
- package/dist/OtpInput.js.map +1 -0
- package/dist/Pagination.d.ts +11 -0
- package/dist/Pagination.js +148 -0
- package/dist/Pagination.js.map +1 -0
- package/dist/Popover.d.ts +13 -0
- package/dist/Popover.js +98 -0
- package/dist/Popover.js.map +1 -0
- package/dist/Progress.d.ts +12 -0
- package/dist/Progress.js +61 -0
- package/dist/Progress.js.map +1 -0
- package/dist/QuoteCard.d.ts +13 -0
- package/dist/QuoteCard.js +92 -0
- package/dist/QuoteCard.js.map +1 -0
- package/dist/Radio.d.ts +19 -0
- package/dist/Radio.js +161 -0
- package/dist/Radio.js.map +1 -0
- package/dist/RadioCards.d.ts +27 -0
- package/dist/RadioCards.js +205 -0
- package/dist/RadioCards.js.map +1 -0
- package/dist/ReactionBar.d.ts +15 -0
- package/dist/ReactionBar.js +92 -0
- package/dist/ReactionBar.js.map +1 -0
- package/dist/ReadingProgress.d.ts +8 -0
- package/dist/ReadingProgress.js +51 -0
- package/dist/ReadingProgress.js.map +1 -0
- package/dist/ReadingTime.d.ts +9 -0
- package/dist/ReadingTime.js +39 -0
- package/dist/ReadingTime.js.map +1 -0
- package/dist/Select.d.ts +20 -0
- package/dist/Select.js +244 -0
- package/dist/Select.js.map +1 -0
- package/dist/Separator.d.ts +14 -0
- package/dist/Separator.js +33 -0
- package/dist/Separator.js.map +1 -0
- package/dist/ShareButtons.d.ts +10 -0
- package/dist/ShareButtons.js +107 -0
- package/dist/ShareButtons.js.map +1 -0
- package/dist/Sidebar.d.ts +30 -0
- package/dist/Sidebar.js +140 -0
- package/dist/Sidebar.js.map +1 -0
- package/dist/Skeleton.d.ts +15 -0
- package/dist/Skeleton.js +67 -0
- package/dist/Skeleton.js.map +1 -0
- package/dist/Slider.d.ts +27 -0
- package/dist/Slider.js +182 -0
- package/dist/Slider.js.map +1 -0
- package/dist/Spinner.d.ts +12 -0
- package/dist/Spinner.js +24 -0
- package/dist/Spinner.js.map +1 -0
- package/dist/SpotlightCard.d.ts +17 -0
- package/dist/SpotlightCard.js +87 -0
- package/dist/SpotlightCard.js.map +1 -0
- package/dist/Stat.d.ts +19 -0
- package/dist/Stat.js +71 -0
- package/dist/Stat.js.map +1 -0
- package/dist/StatCard.d.ts +24 -0
- package/dist/StatCard.js +212 -0
- package/dist/StatCard.js.map +1 -0
- package/dist/Steps.d.ts +14 -0
- package/dist/Steps.js +94 -0
- package/dist/Steps.js.map +1 -0
- package/dist/Table.d.ts +21 -0
- package/dist/Table.js +93 -0
- package/dist/Table.js.map +1 -0
- package/dist/TableOfContents.d.ts +17 -0
- package/dist/TableOfContents.js +92 -0
- package/dist/TableOfContents.js.map +1 -0
- package/dist/Tabs.d.ts +17 -0
- package/dist/Tabs.js +123 -0
- package/dist/Tabs.js.map +1 -0
- package/dist/TagInput.d.ts +16 -0
- package/dist/TagInput.js +169 -0
- package/dist/TagInput.js.map +1 -0
- package/dist/Textarea.d.ts +13 -0
- package/dist/Textarea.js +74 -0
- package/dist/Textarea.js.map +1 -0
- package/dist/TimePicker.d.ts +28 -0
- package/dist/TimePicker.js +264 -0
- package/dist/TimePicker.js.map +1 -0
- package/dist/Timeline.d.ts +19 -0
- package/dist/Timeline.js +76 -0
- package/dist/Timeline.js.map +1 -0
- package/dist/Toast.d.ts +18 -0
- package/dist/Toast.js +318 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Toggle.d.ts +13 -0
- package/dist/Toggle.js +84 -0
- package/dist/Toggle.js.map +1 -0
- package/dist/Tooltip.d.ts +13 -0
- package/dist/Tooltip.js +138 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/cli.js +1644 -0
- package/dist/index.d.ts +68 -631
- package/dist/index.js +67 -5558
- package/dist/index.js.map +1 -1
- package/dist/registry/Accordion.tsx +140 -0
- package/dist/registry/Alert.tsx +95 -0
- package/dist/registry/AuthorCard.tsx +67 -0
- package/dist/registry/Avatar.tsx +116 -0
- package/dist/registry/Badge.tsx +55 -0
- package/dist/registry/Banner.tsx +86 -0
- package/dist/registry/Breadcrumb.tsx +60 -0
- package/dist/registry/Button.tsx +361 -0
- package/dist/registry/ButtonGroup.tsx +82 -0
- package/dist/registry/Card.tsx +241 -0
- package/dist/registry/CardShell.tsx +78 -0
- package/dist/registry/Carousel.tsx +296 -0
- package/dist/registry/Checkbox.tsx +104 -0
- package/dist/registry/CloseButton.tsx +68 -0
- package/dist/registry/CodeBlock.tsx +202 -0
- package/dist/registry/ColorPicker.tsx +404 -0
- package/dist/registry/Combobox.tsx +318 -0
- package/dist/registry/CommandPalette.tsx +356 -0
- package/dist/registry/ContextMenu.tsx +241 -0
- package/dist/registry/DataList.tsx +49 -0
- package/dist/registry/DatePicker.tsx +494 -0
- package/dist/registry/DateRangePicker.tsx +232 -0
- package/dist/registry/Drawer.tsx +166 -0
- package/dist/registry/DropdownMenu.tsx +219 -0
- package/dist/registry/EmptyState.tsx +55 -0
- package/dist/registry/FieldMessage.tsx +123 -0
- package/dist/registry/FileUpload.tsx +318 -0
- package/dist/registry/Floating.tsx +134 -0
- package/dist/registry/HoverCard.tsx +113 -0
- package/dist/registry/Input.tsx +108 -0
- package/dist/registry/Kbd.tsx +23 -0
- package/dist/registry/Modal.tsx +130 -0
- package/dist/registry/NumberInput.tsx +183 -0
- package/dist/registry/OtpInput.tsx +219 -0
- package/dist/registry/Pagination.tsx +160 -0
- package/dist/registry/Popover.tsx +116 -0
- package/dist/registry/Progress.tsx +66 -0
- package/dist/registry/QuoteCard.tsx +93 -0
- package/dist/registry/Radio.tsx +205 -0
- package/dist/registry/RadioCards.tsx +247 -0
- package/dist/registry/ReactionBar.tsx +101 -0
- package/dist/registry/ReadingProgress.tsx +51 -0
- package/dist/registry/ReadingTime.tsx +35 -0
- package/dist/registry/Select.tsx +265 -0
- package/dist/registry/Separator.tsx +52 -0
- package/dist/registry/ShareButtons.tsx +134 -0
- package/dist/registry/Sidebar.tsx +182 -0
- package/dist/registry/Skeleton.tsx +83 -0
- package/dist/registry/Slider.tsx +229 -0
- package/dist/registry/Spinner.tsx +32 -0
- package/dist/registry/SpotlightCard.tsx +106 -0
- package/dist/registry/Stat.tsx +82 -0
- package/dist/registry/StatCard.tsx +256 -0
- package/dist/registry/Steps.tsx +109 -0
- package/dist/registry/Table.tsx +123 -0
- package/dist/registry/TableOfContents.tsx +116 -0
- package/dist/registry/Tabs.tsx +136 -0
- package/dist/registry/TagInput.tsx +191 -0
- package/dist/registry/Textarea.tsx +84 -0
- package/dist/registry/TimePicker.tsx +315 -0
- package/dist/registry/Timeline.tsx +102 -0
- package/dist/registry/Toast.tsx +388 -0
- package/dist/registry/Toggle.tsx +96 -0
- package/dist/registry/Tooltip.tsx +160 -0
- package/dist/registry/styles.css +1207 -0
- package/dist/registry/useFloatingPanel.ts +112 -0
- package/dist/registry/useModalBehavior.ts +77 -0
- package/dist/styles.css +868 -62
- package/dist/useFloatingPanel.d.ts +24 -0
- package/dist/useFloatingPanel.js +89 -0
- package/dist/useFloatingPanel.js.map +1 -0
- package/dist/useModalBehavior.d.ts +15 -0
- package/dist/useModalBehavior.js +57 -0
- package/dist/useModalBehavior.js.map +1 -0
- package/package.json +23 -6
package/README.md
CHANGED
|
@@ -1,20 +1,56 @@
|
|
|
1
|
+
<a href="https://www.blurrow.org">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/manyports/blurrow/main/.github/readme/banner.png" alt="blurrow/ui: buttons you want to press, fields you want to fill in" width="100%">
|
|
3
|
+
</a>
|
|
4
|
+
|
|
1
5
|
# @blurrow/ui
|
|
2
6
|
|
|
3
|
-
buttons
|
|
7
|
+
62 react components that look and feel like physical things. buttons sit in a bezel and sink when you press them, text fields are cut into the surface, and every shadow agrees on where the light is coming from.
|
|
8
|
+
|
|
9
|
+
free, mit licensed, and built for react 19 and tailwind css v4. made with care by [@manyports](https://manyports.com).
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
**[website](https://www.blurrow.org)** · [docs](https://www.blurrow.org/docs) · [all components](https://www.blurrow.org/docs/components) · [github](https://github.com/manyports/blurrow)
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
<img src="https://raw.githubusercontent.com/manyports/blurrow/main/.github/readme/favourites.png" alt="nine blurrow components: buttons, toggles, an input, tabs, pagination, a radio group, a select, a stat card and an alert" width="100%">
|
|
14
|
+
|
|
15
|
+
## getting started
|
|
8
16
|
|
|
9
17
|
```bash
|
|
10
|
-
|
|
18
|
+
npx @blurrow/ui init
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
that's the whole setup. it installs the package, adds two lines to your stylesheet, loads the archivo font and wraps your app in `ToastProvider`, showing you each change before it writes anything.
|
|
22
|
+
|
|
23
|
+
<img src="https://raw.githubusercontent.com/manyports/blurrow/main/.github/readme/cli.png" alt="the blurrow cli setting up a next.js project" width="560">
|
|
24
|
+
|
|
25
|
+
then use whatever you like:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Button, Input, Toggle } from "@blurrow/ui";
|
|
29
|
+
|
|
30
|
+
export default function Settings() {
|
|
31
|
+
return (
|
|
32
|
+
<form className="flex flex-col gap-4">
|
|
33
|
+
<Input label="display name" placeholder="ada" />
|
|
34
|
+
<Toggle label="email me when someone replies" defaultChecked />
|
|
35
|
+
<Button variant="primary">save</Button>
|
|
36
|
+
</form>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
11
39
|
```
|
|
12
40
|
|
|
13
|
-
|
|
41
|
+
they drop straight into server components. the interactive ones are marked `"use client"`, and the static ones (badges, cards, avatars, skeletons…) render on the server and send no javascript.
|
|
42
|
+
|
|
43
|
+
## setting it up by hand
|
|
44
|
+
|
|
45
|
+
if you'd rather not run `init`, it does four things:
|
|
46
|
+
|
|
47
|
+
**1. install**
|
|
14
48
|
|
|
15
|
-
|
|
49
|
+
```bash
|
|
50
|
+
npm install @blurrow/ui
|
|
51
|
+
```
|
|
16
52
|
|
|
17
|
-
**
|
|
53
|
+
**2. styles.** add the tokens after tailwind, and let tailwind see the classes the components use. the `@source` path is relative to your css file.
|
|
18
54
|
|
|
19
55
|
```css
|
|
20
56
|
/* app/globals.css */
|
|
@@ -24,9 +60,7 @@ you'll need react 19 and tailwind css v4.
|
|
|
24
60
|
@source "../node_modules/@blurrow/ui";
|
|
25
61
|
```
|
|
26
62
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
**2. font.** everything is set in archivo. load it as the `--font-archivo` variable. with next.js:
|
|
63
|
+
**3. font.** everything is set in archivo, loaded as the `--font-archivo` variable. with next.js:
|
|
30
64
|
|
|
31
65
|
```tsx
|
|
32
66
|
// app/layout.tsx
|
|
@@ -39,7 +73,7 @@ const archivo = Archivo({ subsets: ["latin"], variable: "--font-archivo" });
|
|
|
39
73
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
40
74
|
return (
|
|
41
75
|
<html lang="en" className={archivo.variable}>
|
|
42
|
-
<body className="bg-
|
|
76
|
+
<body className="bg-page font-sans text-ink antialiased">
|
|
43
77
|
<ToastProvider>{children}</ToastProvider>
|
|
44
78
|
</body>
|
|
45
79
|
</html>
|
|
@@ -47,20 +81,26 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
47
81
|
}
|
|
48
82
|
```
|
|
49
83
|
|
|
50
|
-
`ToastProvider` is only needed if you use
|
|
84
|
+
**4. toasts.** `ToastProvider` above is only needed if you use `useToast()`.
|
|
51
85
|
|
|
52
|
-
##
|
|
86
|
+
## dark mode
|
|
53
87
|
|
|
54
|
-
|
|
55
|
-
import { Button } from "@blurrow/ui";
|
|
88
|
+
every colour, shadow and gradient is a css variable with a light and a dark value. put `data-theme="dark"` on `<html>` (or the class `dark`), or on any element to darken just that part. `data-theme="system"` follows the os setting, and an explicit `light` or `dark` always wins. `bg-page` and `text-ink` let your own page follow along. more in [the docs](https://www.blurrow.org/docs/installation#dark-mode).
|
|
56
89
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
90
|
+
## the cli
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx @blurrow/ui init # set up a project, safe to run again
|
|
94
|
+
npx @blurrow/ui add [names…] # copy components' source in, with anything they need
|
|
95
|
+
npx @blurrow/ui list # every component, and which ones you've copied
|
|
96
|
+
npx @blurrow/ui diff [name] # what you've changed in your copies
|
|
97
|
+
npx @blurrow/ui doctor [--fix] # check the setup, and repair the css if it's off
|
|
60
98
|
```
|
|
61
99
|
|
|
62
|
-
|
|
100
|
+
`add` with no names opens a picker: type to filter, space to choose. names are forgiving (`button`, `Button` and `button-group` all work) and typos get a suggestion. files you've edited are never overwritten unless you pass `--overwrite`.
|
|
101
|
+
|
|
102
|
+
everything takes `--yes`, `--dry-run` and `--cwd <path>`. settings live in `blurrow.json`. once the package is installed, `npx blurrow` works as a shorter name.
|
|
63
103
|
|
|
64
104
|
## license
|
|
65
105
|
|
|
66
|
-
|
|
106
|
+
mit. issues and ideas are welcome on [github](https://github.com/manyports/blurrow/issues).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface AccordionItem {
|
|
5
|
+
key: string;
|
|
6
|
+
title: string;
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface AccordionProps {
|
|
11
|
+
items: AccordionItem[];
|
|
12
|
+
allowMultiple?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
declare function Accordion({ items, allowMultiple, className }: AccordionProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { Accordion };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// ../../components/ui/Accordion.tsx
|
|
4
|
+
import { useState, useCallback, useId } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function Accordion({ items, allowMultiple = false, className }) {
|
|
7
|
+
const [openKeys, setOpenKeys] = useState(() => {
|
|
8
|
+
const defaults = /* @__PURE__ */ new Set();
|
|
9
|
+
for (const item of items) {
|
|
10
|
+
if (item.defaultOpen) {
|
|
11
|
+
defaults.add(item.key);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return defaults;
|
|
15
|
+
});
|
|
16
|
+
const toggle = useCallback(
|
|
17
|
+
(key) => {
|
|
18
|
+
setOpenKeys((prev) => {
|
|
19
|
+
const next = new Set(prev);
|
|
20
|
+
if (next.has(key)) {
|
|
21
|
+
next.delete(key);
|
|
22
|
+
} else {
|
|
23
|
+
if (allowMultiple) {
|
|
24
|
+
next.add(key);
|
|
25
|
+
} else {
|
|
26
|
+
next.clear();
|
|
27
|
+
next.add(key);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return next;
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
[allowMultiple]
|
|
34
|
+
);
|
|
35
|
+
const uid = useId();
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
"div",
|
|
38
|
+
{
|
|
39
|
+
className: ["rounded-[18px] p-1.5", className].filter(Boolean).join(" "),
|
|
40
|
+
style: { background: "var(--panel-bezel)", boxShadow: "var(--panel-shadow)" },
|
|
41
|
+
children: /* @__PURE__ */ jsx(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
className: "bg-panel-face rounded-[13px] overflow-hidden p-1",
|
|
45
|
+
style: { boxShadow: "var(--panel-face-shadow)" },
|
|
46
|
+
children: items.map((item, index) => {
|
|
47
|
+
const isOpen = openKeys.has(item.key);
|
|
48
|
+
const isLast = index === items.length - 1;
|
|
49
|
+
const headerId = `${uid}-${item.key}-header`;
|
|
50
|
+
const panelId = `${uid}-${item.key}-panel`;
|
|
51
|
+
return /* @__PURE__ */ jsxs(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
className: [
|
|
55
|
+
"relative",
|
|
56
|
+
// Hairline between rows, inset so it doesn't touch the rounded corners
|
|
57
|
+
!isLast && "after:absolute after:left-3 after:right-3 after:bottom-0 after:h-px after:bg-line"
|
|
58
|
+
].filter(Boolean).join(" "),
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsx("h3", { children: /* @__PURE__ */ jsxs(
|
|
61
|
+
"button",
|
|
62
|
+
{
|
|
63
|
+
type: "button",
|
|
64
|
+
id: headerId,
|
|
65
|
+
"aria-expanded": isOpen,
|
|
66
|
+
"aria-controls": panelId,
|
|
67
|
+
onClick: () => toggle(item.key),
|
|
68
|
+
className: [
|
|
69
|
+
"group/acc w-full flex items-center justify-between gap-3 py-3 px-3 text-left text-[13.5px] font-medium cursor-pointer rounded-[10px]",
|
|
70
|
+
"transition-colors duration-150",
|
|
71
|
+
isOpen ? "text-ink" : "text-ink-label hover:text-ink hover:bg-surface-hover"
|
|
72
|
+
].join(" "),
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsx("span", { children: item.title }),
|
|
75
|
+
/* @__PURE__ */ jsxs(
|
|
76
|
+
"span",
|
|
77
|
+
{
|
|
78
|
+
"aria-hidden": true,
|
|
79
|
+
className: "relative shrink-0 w-6 h-6 rounded-[7px] flex items-center justify-center text-ink-muted group-hover/acc:text-ink transition-colors",
|
|
80
|
+
style: { background: "var(--face)", boxShadow: "var(--face-shadow)" },
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsx("span", { className: "absolute w-2.5 h-[1.5px] rounded-full bg-current" }),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"span",
|
|
85
|
+
{
|
|
86
|
+
className: "absolute w-2.5 h-[1.5px] rounded-full bg-current",
|
|
87
|
+
style: {
|
|
88
|
+
transform: isOpen ? "rotate(0deg)" : "rotate(90deg)",
|
|
89
|
+
transition: "transform 300ms var(--ease-spring)"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
) }),
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
id: panelId,
|
|
103
|
+
role: "region",
|
|
104
|
+
"aria-labelledby": headerId,
|
|
105
|
+
inert: !isOpen,
|
|
106
|
+
style: {
|
|
107
|
+
display: "grid",
|
|
108
|
+
gridTemplateRows: isOpen ? "1fr" : "0fr",
|
|
109
|
+
transition: "grid-template-rows 320ms var(--ease-out-soft)"
|
|
110
|
+
},
|
|
111
|
+
children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
className: "px-3 pb-4 pt-0.5 text-[13px] text-ink-body leading-relaxed",
|
|
115
|
+
style: {
|
|
116
|
+
opacity: isOpen ? 1 : 0,
|
|
117
|
+
transform: isOpen ? "translateY(0)" : "translateY(-4px)",
|
|
118
|
+
transition: "opacity 240ms ease-out, transform 320ms var(--ease-out-soft)"
|
|
119
|
+
},
|
|
120
|
+
children: item.content
|
|
121
|
+
}
|
|
122
|
+
) })
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
item.key
|
|
128
|
+
);
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
export {
|
|
136
|
+
Accordion
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=Accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../components/ui/Accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useCallback, useId, ReactNode } from \"react\";\n\ninterface AccordionItem {\n key: string;\n title: string;\n content: ReactNode;\n defaultOpen?: boolean;\n}\n\ninterface AccordionProps {\n items: AccordionItem[];\n allowMultiple?: boolean;\n className?: string;\n}\n\nexport function Accordion({ items, allowMultiple = false, className }: AccordionProps) {\n const [openKeys, setOpenKeys] = useState<Set<string>>(() => {\n const defaults = new Set<string>();\n for (const item of items) {\n if (item.defaultOpen) {\n defaults.add(item.key);\n }\n }\n return defaults;\n });\n\n const toggle = useCallback(\n (key: string) => {\n setOpenKeys((prev) => {\n const next = new Set(prev);\n if (next.has(key)) {\n next.delete(key);\n } else {\n if (allowMultiple) {\n next.add(key);\n } else {\n next.clear();\n next.add(key);\n }\n }\n return next;\n });\n },\n [allowMultiple]\n );\n const uid = useId();\n\n return (\n <div\n className={[\"rounded-[18px] p-1.5\", className].filter(Boolean).join(\" \")}\n style={{ background: \"var(--panel-bezel)\", boxShadow: \"var(--panel-shadow)\" }}\n >\n <div\n className=\"bg-panel-face rounded-[13px] overflow-hidden p-1\"\n style={{ boxShadow: \"var(--panel-face-shadow)\" }}\n >\n {items.map((item, index) => {\n const isOpen = openKeys.has(item.key);\n const isLast = index === items.length - 1;\n const headerId = `${uid}-${item.key}-header`;\n const panelId = `${uid}-${item.key}-panel`;\n\n return (\n <div\n key={item.key}\n className={[\n \"relative\",\n // Hairline between rows, inset so it doesn't touch the rounded corners\n !isLast &&\n \"after:absolute after:left-3 after:right-3 after:bottom-0 after:h-px after:bg-line\",\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <h3>\n <button\n type=\"button\"\n id={headerId}\n aria-expanded={isOpen}\n aria-controls={panelId}\n onClick={() => toggle(item.key)}\n className={[\n \"group/acc w-full flex items-center justify-between gap-3 py-3 px-3 text-left text-[13.5px] font-medium cursor-pointer rounded-[10px]\",\n \"transition-colors duration-150\",\n isOpen ? \"text-ink\" : \"text-ink-label hover:text-ink hover:bg-surface-hover\",\n ].join(\" \")}\n >\n <span>{item.title}</span>\n {/* Plus that turns into a minus: says \"more inside\", not \"navigate\" */}\n <span\n aria-hidden\n className=\"relative shrink-0 w-6 h-6 rounded-[7px] flex items-center justify-center text-ink-muted group-hover/acc:text-ink transition-colors\"\n style={{ background: \"var(--face)\", boxShadow: \"var(--face-shadow)\" }}\n >\n <span className=\"absolute w-2.5 h-[1.5px] rounded-full bg-current\" />\n <span\n className=\"absolute w-2.5 h-[1.5px] rounded-full bg-current\"\n style={{\n transform: isOpen ? \"rotate(0deg)\" : \"rotate(90deg)\",\n transition: \"transform 300ms var(--ease-spring)\",\n }}\n />\n </span>\n </button>\n </h3>\n\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={headerId}\n // Closed panels are removed from the tab order and the a11y tree\n inert={!isOpen}\n style={{\n display: \"grid\",\n gridTemplateRows: isOpen ? \"1fr\" : \"0fr\",\n transition: \"grid-template-rows 320ms var(--ease-out-soft)\",\n }}\n >\n <div className=\"overflow-hidden\">\n <div\n className=\"px-3 pb-4 pt-0.5 text-[13px] text-ink-body leading-relaxed\"\n style={{\n opacity: isOpen ? 1 : 0,\n transform: isOpen ? \"translateY(0)\" : \"translateY(-4px)\",\n transition: \"opacity 240ms ease-out, transform 320ms var(--ease-out-soft)\",\n }}\n >\n {item.content}\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/Alert.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type AlertVariant = "default" | "success" | "warning" | "error";
|
|
4
|
+
interface AlertProps {
|
|
5
|
+
variant?: AlertVariant;
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
onDismiss?: () => void;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function Alert({ variant, title, description, onDismiss, className }: AlertProps): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { Alert };
|
package/dist/Alert.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// ../../components/ui/Alert.tsx
|
|
2
|
+
import { CloseButton } from "./CloseButton.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
var variantConfig = {
|
|
5
|
+
default: {
|
|
6
|
+
tile: "var(--face-inverse)",
|
|
7
|
+
icon: /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "1.75", viewBox: "0 0 24 24", children: [
|
|
8
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
9
|
+
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M12 8v4m0 4h.01" })
|
|
10
|
+
] })
|
|
11
|
+
},
|
|
12
|
+
success: {
|
|
13
|
+
tile: "var(--tile-success)",
|
|
14
|
+
icon: /* @__PURE__ */ jsx("svg", { width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) })
|
|
15
|
+
},
|
|
16
|
+
warning: {
|
|
17
|
+
tile: "var(--tile-warning)",
|
|
18
|
+
icon: /* @__PURE__ */ jsx("svg", { width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "1.75", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" }) })
|
|
19
|
+
},
|
|
20
|
+
error: {
|
|
21
|
+
tile: "var(--tile-error)",
|
|
22
|
+
icon: /* @__PURE__ */ jsx("svg", { width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function Alert({ variant = "default", title, description, onDismiss, className = "" }) {
|
|
26
|
+
const { tile, icon } = variantConfig[variant];
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
"div",
|
|
29
|
+
{
|
|
30
|
+
role: variant === "error" || variant === "warning" ? "alert" : "status",
|
|
31
|
+
className: ["rounded-[18px] p-1.5", className].join(" "),
|
|
32
|
+
style: { background: "var(--panel-bezel)", boxShadow: "var(--panel-shadow)" },
|
|
33
|
+
children: /* @__PURE__ */ jsxs(
|
|
34
|
+
"div",
|
|
35
|
+
{
|
|
36
|
+
className: "bg-panel-face rounded-[13px] pl-3 pr-2 py-3 flex items-start gap-3",
|
|
37
|
+
style: { boxShadow: "var(--panel-face-shadow)" },
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
"aria-hidden": true,
|
|
43
|
+
className: [
|
|
44
|
+
"shrink-0 w-7 h-7 rounded-[8px] flex items-center justify-center",
|
|
45
|
+
// the default tile is the inverse face; status tiles stay white-on-colour
|
|
46
|
+
tile === "var(--face-inverse)" ? "text-ink-inverse" : "text-white"
|
|
47
|
+
].join(" "),
|
|
48
|
+
style: {
|
|
49
|
+
background: tile,
|
|
50
|
+
boxShadow: "var(--tile-status-shadow)"
|
|
51
|
+
},
|
|
52
|
+
children: icon
|
|
53
|
+
}
|
|
54
|
+
),
|
|
55
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 pt-[5px]", children: [
|
|
56
|
+
/* @__PURE__ */ jsx("p", { className: "text-[13px] font-semibold text-ink leading-tight tracking-[-0.01em]", children: title }),
|
|
57
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-ink-muted mt-1 leading-relaxed", children: description })
|
|
58
|
+
] }),
|
|
59
|
+
onDismiss && /* @__PURE__ */ jsx(CloseButton, { size: "sm", label: "Dismiss", onClick: onDismiss })
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
Alert
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=Alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../components/ui/Alert.tsx"],"sourcesContent":["import React from \"react\";\nimport { CloseButton } from \"./CloseButton\";\n\ntype AlertVariant = \"default\" | \"success\" | \"warning\" | \"error\";\n\ninterface AlertProps {\n variant?: AlertVariant;\n title: string;\n description?: string;\n onDismiss?: () => void;\n className?: string;\n}\n\n/* Tiles share Toast's lit-from-above gradients, so an alert and the toast\n it came from look like the same object. */\nconst variantConfig: Record<AlertVariant, {\n tile: string;\n icon: React.ReactNode;\n}> = {\n default: {\n tile: \"var(--face-inverse)\",\n icon: (\n <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path strokeLinecap=\"round\" d=\"M12 8v4m0 4h.01\" />\n </svg>\n ),\n },\n success: {\n tile: \"var(--tile-success)\",\n icon: (\n <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n ),\n },\n warning: {\n tile: \"var(--tile-warning)\",\n icon: (\n <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z\" />\n </svg>\n ),\n },\n error: {\n tile: \"var(--tile-error)\",\n icon: (\n <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ),\n },\n};\n\nexport function Alert({ variant = \"default\", title, description, onDismiss, className = \"\" }: AlertProps) {\n const { tile, icon } = variantConfig[variant];\n\n return (\n <div\n // Errors and warnings interrupt; everything else waits its turn\n role={variant === \"error\" || variant === \"warning\" ? \"alert\" : \"status\"}\n className={[\"rounded-[18px] p-1.5\", className].join(\" \")}\n style={{ background: \"var(--panel-bezel)\", boxShadow: \"var(--panel-shadow)\" }}\n >\n <div\n className=\"bg-panel-face rounded-[13px] pl-3 pr-2 py-3 flex items-start gap-3\"\n style={{ boxShadow: \"var(--panel-face-shadow)\" }}\n >\n <div\n aria-hidden\n className={[\n \"shrink-0 w-7 h-7 rounded-[8px] flex items-center justify-center\",\n // the default tile is the inverse face; status tiles stay white-on-colour\n tile === \"var(--face-inverse)\" ? \"text-ink-inverse\" : \"text-white\",\n ].join(\" \")}\n style={{\n background: tile,\n boxShadow: \"var(--tile-status-shadow)\",\n }}\n >\n {icon}\n </div>\n\n <div className=\"flex-1 min-w-0 pt-[5px]\">\n <p className=\"text-[13px] font-semibold text-ink leading-tight tracking-[-0.01em]\">{title}</p>\n {description && (\n <p className=\"text-[12.5px] text-ink-muted mt-1 leading-relaxed\">{description}</p>\n )}\n </div>\n\n {onDismiss && <CloseButton size=\"sm\" label=\"Dismiss\" onClick={onDismiss} />}\n </div>\n </div>\n );\n}\n"],"mappings":";AACA,SAAS,mBAAmB;AAqBtB,SACE,KADF;AAPN,IAAM,gBAGD;AAAA,EACH,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MACE,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,MAAK,QAAO,QAAO,gBAAe,aAAY,QAAO,SAAQ,aACvF;AAAA,0BAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK;AAAA,MAC/B,oBAAC,UAAK,eAAc,SAAQ,GAAE,mBAAkB;AAAA,OAClD;AAAA,EAEJ;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MACE,oBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,SAAQ,aACpF,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,kBAAiB,GACxE;AAAA,EAEJ;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MACE,oBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,MAAK,QAAO,QAAO,gBAAe,aAAY,QAAO,SAAQ,aACvF,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,sGAAqG,GAC5J;AAAA,EAEJ;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MACE,oBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,SAAQ,aACpF,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,wBAAuB,GAC9E;AAAA,EAEJ;AACF;AAEO,SAAS,MAAM,EAAE,UAAU,WAAW,OAAO,aAAa,WAAW,YAAY,GAAG,GAAe;AACxG,QAAM,EAAE,MAAM,KAAK,IAAI,cAAc,OAAO;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MAEC,MAAM,YAAY,WAAW,YAAY,YAAY,UAAU;AAAA,MAC/D,WAAW,CAAC,wBAAwB,SAAS,EAAE,KAAK,GAAG;AAAA,MACvD,OAAO,EAAE,YAAY,sBAAsB,WAAW,sBAAsB;AAAA,MAE5E;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,WAAW,2BAA2B;AAAA,UAE/C;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,eAAW;AAAA,gBACX,WAAW;AAAA,kBACP;AAAA;AAAA,kBAEA,SAAS,wBAAwB,qBAAqB;AAAA,gBACxD,EAAE,KAAK,GAAG;AAAA,gBACZ,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,WAAW;AAAA,gBACb;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA,YAEA,qBAAC,SAAI,WAAU,2BACb;AAAA,kCAAC,OAAE,WAAU,uEAAuE,iBAAM;AAAA,cACzF,eACC,oBAAC,OAAE,WAAU,qDAAqD,uBAAY;AAAA,eAElF;AAAA,YAEC,aAAa,oBAAC,eAAY,MAAK,MAAK,OAAM,WAAU,SAAS,WAAW;AAAA;AAAA;AAAA,MAC3E;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface AuthorCardProps {
|
|
4
|
+
name: string;
|
|
5
|
+
bio?: string;
|
|
6
|
+
avatarSrc?: string;
|
|
7
|
+
onFollow?: () => void;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function AuthorCard({ name, bio, avatarSrc, onFollow, className, }: AuthorCardProps): react_jsx_runtime.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { AuthorCard };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// ../../components/ui/AuthorCard.tsx
|
|
2
|
+
import { Avatar } from "./Avatar.js";
|
|
3
|
+
import { Button } from "./Button.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function AuthorCard({
|
|
6
|
+
name,
|
|
7
|
+
bio,
|
|
8
|
+
avatarSrc,
|
|
9
|
+
onFollow,
|
|
10
|
+
className = ""
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"div",
|
|
14
|
+
{
|
|
15
|
+
className: [
|
|
16
|
+
"rim relative rounded-[22px] p-1.5",
|
|
17
|
+
className
|
|
18
|
+
].filter(Boolean).join(" "),
|
|
19
|
+
style: { background: "var(--panel-bezel)", boxShadow: "var(--card-shadow)" },
|
|
20
|
+
children: /* @__PURE__ */ jsxs("div", { className: "relative bg-panel-face rounded-[17px] overflow-hidden", style: { boxShadow: "var(--panel-face-shadow)" }, children: [
|
|
21
|
+
/* @__PURE__ */ jsx(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
"aria-hidden": true,
|
|
25
|
+
className: "h-20 relative overflow-hidden",
|
|
26
|
+
style: {
|
|
27
|
+
background: "var(--cover)",
|
|
28
|
+
boxShadow: "var(--cover-shadow)"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ jsxs("div", { className: "px-6 pb-6", children: [
|
|
33
|
+
/* @__PURE__ */ jsx("div", { className: "-mt-8 mb-4", children: /* @__PURE__ */ jsx(
|
|
34
|
+
Avatar,
|
|
35
|
+
{
|
|
36
|
+
src: avatarSrc,
|
|
37
|
+
name,
|
|
38
|
+
size: "lg",
|
|
39
|
+
className: "ring-[3.5px] ring-panel-face shadow-[var(--avatar-lift)]"
|
|
40
|
+
}
|
|
41
|
+
) }),
|
|
42
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
43
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
44
|
+
/* @__PURE__ */ jsx("p", { className: "text-[15px] font-semibold text-ink leading-snug truncate tracking-[-0.01em]", children: name }),
|
|
45
|
+
bio && /* @__PURE__ */ jsx("p", { className: "text-[13px] text-ink-muted leading-relaxed mt-1 line-clamp-2", children: bio })
|
|
46
|
+
] }),
|
|
47
|
+
onFollow && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: onFollow, className: "shrink-0", children: "follow" })
|
|
48
|
+
] })
|
|
49
|
+
] })
|
|
50
|
+
] })
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
AuthorCard
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=AuthorCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../components/ui/AuthorCard.tsx"],"sourcesContent":["import React from \"react\";\nimport { Avatar } from \"./Avatar\";\nimport { Button } from \"./Button\";\n\ninterface AuthorCardProps {\n name: string;\n bio?: string;\n avatarSrc?: string;\n onFollow?: () => void;\n className?: string;\n}\n\nexport function AuthorCard({\n name,\n bio,\n avatarSrc,\n onFollow,\n className = \"\",\n}: AuthorCardProps) {\n return (\n <div\n className={[\n \"rim relative rounded-[22px] p-1.5\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ background: \"var(--panel-bezel)\", boxShadow: \"var(--card-shadow)\" }}\n >\n <div className=\"relative bg-panel-face rounded-[17px] overflow-hidden\" style={{ boxShadow: \"var(--panel-face-shadow)\" }}>\n {/* Cover: a sunken well, so the avatar visibly sits on top of it */}\n <div\n aria-hidden\n className=\"h-20 relative overflow-hidden\"\n style={{\n background:\n \"var(--cover)\",\n boxShadow: \"var(--cover-shadow)\",\n }}\n />\n <div className=\"px-6 pb-6\">\n <div className=\"-mt-8 mb-4\">\n <Avatar\n src={avatarSrc}\n name={name}\n size=\"lg\"\n className=\"ring-[3.5px] ring-panel-face shadow-[var(--avatar-lift)]\"\n />\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-[15px] font-semibold text-ink leading-snug truncate tracking-[-0.01em]\">{name}</p>\n {bio && (\n <p className=\"text-[13px] text-ink-muted leading-relaxed mt-1 line-clamp-2\">{bio}</p>\n )}\n </div>\n {onFollow && (\n <Button variant=\"primary\" size=\"sm\" onClick={onFollow} className=\"shrink-0\">\n follow\n </Button>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AACA,SAAS,cAAc;AACvB,SAAS,cAAc;AA6Bf,cAmBI,YAnBJ;AAnBD,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,OAAO,EAAE,YAAY,sBAAsB,WAAW,qBAAqB;AAAA,MAE3E,+BAAC,SAAI,WAAU,yDAAwD,OAAO,EAAE,WAAW,2BAA2B,GAEpH;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,WAAU;AAAA,YACV,OAAO;AAAA,cACL,YACE;AAAA,cACF,WAAW;AAAA,YACb;AAAA;AAAA,QACF;AAAA,QACA,qBAAC,SAAI,WAAU,aACb;AAAA,8BAAC,SAAI,WAAU,cACb;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL;AAAA,cACA,MAAK;AAAA,cACL,WAAU;AAAA;AAAA,UACZ,GACF;AAAA,UACA,qBAAC,SAAI,WAAU,0CACb;AAAA,iCAAC,SAAI,WAAU,kBACb;AAAA,kCAAC,OAAE,WAAU,+EAA+E,gBAAK;AAAA,cAChG,OACC,oBAAC,OAAE,WAAU,gEAAgE,eAAI;AAAA,eAErF;AAAA,YACC,YACC,oBAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,UAAU,WAAU,YAAW,oBAE5E;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
package/dist/Avatar.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type AvatarSize = "sm" | "md" | "lg";
|
|
5
|
+
interface AvatarProps {
|
|
6
|
+
src?: string;
|
|
7
|
+
alt?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
size?: AvatarSize;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function Avatar({ src, alt, name, size, className, }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
interface AvatarGroupProps {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
max?: number;
|
|
16
|
+
size?: AvatarSize;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
declare function AvatarGroup({ children, max, size, className, }: AvatarGroupProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
|
|
21
|
+
export { Avatar, AvatarGroup };
|
package/dist/Avatar.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// ../../components/ui/Avatar.tsx
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
var sizeStyles = {
|
|
5
|
+
sm: "w-7 h-7 text-[10px]",
|
|
6
|
+
md: "w-9 h-9 text-[12px]",
|
|
7
|
+
lg: "w-12 h-12 text-[14px]"
|
|
8
|
+
};
|
|
9
|
+
function getInitials(name) {
|
|
10
|
+
return name.split(" ").map((w) => w[0]).slice(0, 2).join("").toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
function Avatar({
|
|
13
|
+
src,
|
|
14
|
+
alt = "",
|
|
15
|
+
name,
|
|
16
|
+
size = "md",
|
|
17
|
+
className = ""
|
|
18
|
+
}) {
|
|
19
|
+
const initials = name ? getInitials(name) : "?";
|
|
20
|
+
return /* @__PURE__ */ jsxs(
|
|
21
|
+
"div",
|
|
22
|
+
{
|
|
23
|
+
className: [
|
|
24
|
+
"relative shrink-0 rounded-full overflow-hidden flex items-center justify-center font-semibold text-ink-body select-none",
|
|
25
|
+
sizeStyles[size],
|
|
26
|
+
className
|
|
27
|
+
].filter(Boolean).join(" "),
|
|
28
|
+
style: { background: "var(--face)" },
|
|
29
|
+
children: [
|
|
30
|
+
src ? (
|
|
31
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
32
|
+
/* @__PURE__ */ jsx("img", { src, alt: alt || name || "", loading: "lazy", className: "w-full h-full object-cover" })
|
|
33
|
+
) : /* @__PURE__ */ jsx("span", { role: "img", "aria-label": name ?? "Unknown", children: initials }),
|
|
34
|
+
/* @__PURE__ */ jsx(
|
|
35
|
+
"span",
|
|
36
|
+
{
|
|
37
|
+
"aria-hidden": true,
|
|
38
|
+
className: "pointer-events-none absolute inset-0 rounded-full",
|
|
39
|
+
style: {
|
|
40
|
+
boxShadow: "var(--avatar-rim)"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
var overlapStyles = {
|
|
49
|
+
sm: "-ml-2",
|
|
50
|
+
md: "-ml-2.5",
|
|
51
|
+
lg: "-ml-3"
|
|
52
|
+
};
|
|
53
|
+
function AvatarGroup({
|
|
54
|
+
children,
|
|
55
|
+
max = 5,
|
|
56
|
+
size = "md",
|
|
57
|
+
className = ""
|
|
58
|
+
}) {
|
|
59
|
+
const items = React.Children.toArray(children);
|
|
60
|
+
const visible = items.slice(0, max);
|
|
61
|
+
const overflow = items.length - max;
|
|
62
|
+
return /* @__PURE__ */ jsxs("div", { className: ["flex items-center", className].join(" "), children: [
|
|
63
|
+
visible.map((child, i) => /* @__PURE__ */ jsx(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: [
|
|
67
|
+
"ring-2 ring-panel-face rounded-full",
|
|
68
|
+
i > 0 ? overlapStyles[size] : ""
|
|
69
|
+
].join(" "),
|
|
70
|
+
children: child
|
|
71
|
+
},
|
|
72
|
+
i
|
|
73
|
+
)),
|
|
74
|
+
overflow > 0 && /* @__PURE__ */ jsxs(
|
|
75
|
+
"div",
|
|
76
|
+
{
|
|
77
|
+
className: [
|
|
78
|
+
"ring-2 ring-panel-face rounded-full flex items-center justify-center font-semibold text-ink-body select-none",
|
|
79
|
+
overlapStyles[size],
|
|
80
|
+
sizeStyles[size]
|
|
81
|
+
].join(" "),
|
|
82
|
+
style: { background: "var(--well)", boxShadow: "var(--well-shadow)" },
|
|
83
|
+
"aria-label": `${overflow} more`,
|
|
84
|
+
children: [
|
|
85
|
+
"+",
|
|
86
|
+
overflow
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
] });
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
Avatar,
|
|
94
|
+
AvatarGroup
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=Avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../components/ui/Avatar.tsx"],"sourcesContent":["import React from \"react\";\n\ntype AvatarSize = \"sm\" | \"md\" | \"lg\";\n\ninterface AvatarProps {\n src?: string;\n alt?: string;\n name?: string;\n size?: AvatarSize;\n className?: string;\n}\n\nconst sizeStyles: Record<AvatarSize, string> = {\n sm: \"w-7 h-7 text-[10px]\",\n md: \"w-9 h-9 text-[12px]\",\n lg: \"w-12 h-12 text-[14px]\",\n};\n\nfunction getInitials(name: string): string {\n return name\n .split(\" \")\n .map((w) => w[0])\n .slice(0, 2)\n .join(\"\")\n .toLowerCase();\n}\n\nexport function Avatar({\n src,\n alt = \"\",\n name,\n size = \"md\",\n className = \"\",\n}: AvatarProps) {\n const initials = name ? getInitials(name) : \"?\";\n\n return (\n <div\n className={[\n \"relative shrink-0 rounded-full overflow-hidden flex items-center justify-center font-semibold text-ink-body select-none\",\n sizeStyles[size],\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ background: \"var(--face)\" }}\n >\n {src ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={src} alt={alt || name || \"\"} loading=\"lazy\" className=\"w-full h-full object-cover\" />\n ) : (\n <span role=\"img\" aria-label={name ?? \"Unknown\"}>{initials}</span>\n )}\n <span\n aria-hidden\n className=\"pointer-events-none absolute inset-0 rounded-full\"\n style={{\n boxShadow: \"var(--avatar-rim)\",\n }}\n />\n </div>\n );\n}\n\ninterface AvatarGroupProps {\n children: React.ReactNode;\n max?: number;\n size?: AvatarSize;\n className?: string;\n}\n\nconst overlapStyles: Record<AvatarSize, string> = {\n sm: \"-ml-2\",\n md: \"-ml-2.5\",\n lg: \"-ml-3\",\n};\n\nexport function AvatarGroup({\n children,\n max = 5,\n size = \"md\",\n className = \"\",\n}: AvatarGroupProps) {\n const items = React.Children.toArray(children);\n const visible = items.slice(0, max);\n const overflow = items.length - max;\n\n return (\n <div className={[\"flex items-center\", className].join(\" \")}>\n {visible.map((child, i) => (\n <div\n key={i}\n className={[\n \"ring-2 ring-panel-face rounded-full\",\n i > 0 ? overlapStyles[size] : \"\",\n ].join(\" \")}\n >\n {child}\n </div>\n ))}\n {overflow > 0 && (\n <div\n className={[\n \"ring-2 ring-panel-face rounded-full flex items-center justify-center font-semibold text-ink-body select-none\",\n overlapStyles[size],\n sizeStyles[size],\n ].join(\" \")}\n style={{ background: \"var(--well)\", boxShadow: \"var(--well-shadow)\" }}\n aria-label={`${overflow} more`}\n >\n +{overflow}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";AAAA,OAAO,WAAW;AAqCd,SAYI,KAZJ;AAzBJ,IAAM,aAAyC;AAAA,EAC7C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,SAAS,YAAY,MAAsB;AACzC,SAAO,KACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACf,MAAM,GAAG,CAAC,EACV,KAAK,EAAE,EACP,YAAY;AACjB;AAEO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AACd,GAAgB;AACd,QAAM,WAAW,OAAO,YAAY,IAAI,IAAI;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW,IAAI;AAAA,QACf;AAAA,MACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,OAAO,EAAE,YAAY,cAAc;AAAA,MAElC;AAAA;AAAA;AAAA,UAEC,oBAAC,SAAI,KAAU,KAAK,OAAO,QAAQ,IAAI,SAAQ,QAAO,WAAU,8BAA6B;AAAA,YAE7F,oBAAC,UAAK,MAAK,OAAM,cAAY,QAAQ,WAAY,oBAAS;AAAA,QAE5D;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,WAAU;AAAA,YACV,OAAO;AAAA,cACL,WAAW;AAAA,YACb;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AASA,IAAM,gBAA4C;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AACd,GAAqB;AACnB,QAAM,QAAQ,MAAM,SAAS,QAAQ,QAAQ;AAC7C,QAAM,UAAU,MAAM,MAAM,GAAG,GAAG;AAClC,QAAM,WAAW,MAAM,SAAS;AAEhC,SACE,qBAAC,SAAI,WAAW,CAAC,qBAAqB,SAAS,EAAE,KAAK,GAAG,GACtD;AAAA,YAAQ,IAAI,CAAC,OAAO,MACnB;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,IAAI,IAAI,cAAc,IAAI,IAAI;AAAA,QAChC,EAAE,KAAK,GAAG;AAAA,QAET;AAAA;AAAA,MANI;AAAA,IAOP,CACD;AAAA,IACA,WAAW,KACV;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,cAAc,IAAI;AAAA,UAClB,WAAW,IAAI;AAAA,QACjB,EAAE,KAAK,GAAG;AAAA,QACV,OAAO,EAAE,YAAY,eAAe,WAAW,qBAAqB;AAAA,QACpE,cAAY,GAAG,QAAQ;AAAA,QACxB;AAAA;AAAA,UACG;AAAA;AAAA;AAAA,IACJ;AAAA,KAEJ;AAEJ;","names":[]}
|
package/dist/Badge.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type BadgeVariant = "default" | "muted" | "accent";
|
|
5
|
+
interface BadgeProps {
|
|
6
|
+
variant?: BadgeVariant;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function Badge({ variant, children, className, }: BadgeProps): react_jsx_runtime.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { Badge };
|