@haruhimemoe/ui 0.5.1 → 0.6.0
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/CHANGELOG.md +8 -1
- package/README.md +3 -0
- package/dist/components/shell/SiteFooter.d.ts +10 -3
- package/dist/components/shell/SiteFooter.js +8 -2
- package/dist/components/shell/haruhimeTools.d.ts +46 -0
- package/dist/components/shell/haruhimeTools.js +30 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.6.0] - 2026-09-28
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `SiteFooter`'s `tools` prop: a "haruhime tools" column linking the other live haruhime.moe tools (packs, pools, bb) and "All tools" on www, with the current tool left out. `HARUHIME_TOOLS` and `haruhimeToolsColumn` export the same data for a custom footer.
|
|
14
|
+
|
|
9
15
|
## [0.5.1] - 2026-09-28
|
|
10
16
|
|
|
11
17
|
### Security
|
|
@@ -92,7 +98,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
92
98
|
- `className` on every component, and the extras passed to `buttonClasses` and `fieldClasses`, merge with tailwind-merge: a caller's class replaces a built-in one that sets the same property (`fieldClasses("w-auto")` drops `w-full`).
|
|
93
99
|
- Shell: `SiteHeader` (brand slot, nav links as data with `aria-current`, actions slot), `NavLinks`, `SiteFooter` (link columns as data, fine print, the haruhime.moe wordmark and a GitHub link) and `PageShell` (skip link, header, main, footer).
|
|
94
100
|
|
|
95
|
-
[unreleased]: https://github.com/haruhimemoe/ui/compare/v0.
|
|
101
|
+
[unreleased]: https://github.com/haruhimemoe/ui/compare/v0.6.0...HEAD
|
|
102
|
+
[0.6.0]: https://github.com/haruhimemoe/ui/compare/v0.5.1...v0.6.0
|
|
96
103
|
[0.5.1]: https://github.com/haruhimemoe/ui/compare/v0.5.0...v0.5.1
|
|
97
104
|
[0.5.0]: https://github.com/haruhimemoe/ui/compare/v0.4.0...v0.5.0
|
|
98
105
|
[0.4.0]: https://github.com/haruhimemoe/ui/compare/v0.3.0...v0.4.0
|
package/README.md
CHANGED
|
@@ -760,6 +760,7 @@ Link columns, an extra slot, fine print, the haruhime.moe wordmark, a GitHub ico
|
|
|
760
760
|
| Prop | Type | Default | What it does |
|
|
761
761
|
| --- | --- | --- | --- |
|
|
762
762
|
| `columns` | `readonly SiteFooterColumn[]` | `[]` | Each column is a `<nav>` named by its title, which shows above the list. Up to four columns side by side from `sm` up. |
|
|
763
|
+
| `tools` | `HaruhimeToolsOptions` | none | Adds a "haruhime tools" column: the other live haruhime.moe tools as "name: blurb" links, then "All tools" on www. Options: `current` (the tool this footer is on, left out), `title` (`"haruhime tools"`), `allLabel` (`"All tools"`, `false` drops it), `allHref` (`"https://www.haruhime.moe"`), `position` (where among `columns`, default `1`, clamped). Since 0.6.0. |
|
|
763
764
|
| `extra` | `ReactNode` | none | Shown above the fine print, e.g. a "clear local data" button. |
|
|
764
765
|
| `finePrint` | `ReactNode` | none | One line of small print, in a `<p>`. |
|
|
765
766
|
| `parentLink` | `boolean` | `true` | Show the haruhime.moe wordmark linking the parent site. With it, the last row holds the wordmark and the icons, and the fine print sits above. Without it, the fine print shares the row with the icons. |
|
|
@@ -769,6 +770,8 @@ Link columns, an extra slot, fine print, the haruhime.moe wordmark, a GitHub ico
|
|
|
769
770
|
| `discordHref` | `string` | none | Where the Discord icon links, such as your server's invite (`https://discord.gg/...`). Without it there is no Discord icon. The icon sits before the GitHub icon at the same size. It stays white (`text-c1`) and dims on hover instead of changing color, since Discord's brand guidelines ask that the logo not be recolored. Since 0.3.0. |
|
|
770
771
|
| `discordLabel` | `string` | `"Discord"` | The Discord link's accessible name. Since 0.4.0. |
|
|
771
772
|
|
|
773
|
+
`HARUHIME_TOOLS` (each `{ id, name, href, blurb }`, type `HaruhimeTool`, ids `HaruhimeToolId`: `"packs" | "pools" | "bb"`) and `haruhimeToolsColumn(options)` (the same column as plain data, for a footer you lay out yourself) are exported too. Since 0.6.0. They are the one place outside the wordmark that names the haruhime.moe tools: a tool joins the list when it goes live.
|
|
774
|
+
|
|
772
775
|
#### `LinkTabs`
|
|
773
776
|
|
|
774
777
|
Since 0.4.0. A row of link tabs (Pools / Maps, All / Hidden): a named `<nav>` with a list of pill links. The current one gets `aria-current="page"` and a `b3` pill (underlined in forced colors mode). These are links, not ARIA tabs, since each loads its own URL. A Server Component: you say which is current. Every native `<nav>` prop except `children`. Type: `LinkTabItem`.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file src/components/shell/SiteFooter.tsx
|
|
3
3
|
* @desc Site footer: labelled link columns from data (entries without an href show as text with
|
|
4
|
-
* a small note, like "soon"), an optional
|
|
4
|
+
* a small note, like "soon"), an optional "haruhime tools" column linking the other tools,
|
|
5
|
+
* an optional extra slot, one line of fine print, the
|
|
5
6
|
* haruhime.moe wordmark linking the parent site, a GitHub icon link, and an optional
|
|
6
7
|
* Discord icon link beside it (white, as Discord's brand guidelines ask).
|
|
7
8
|
* @author David @dvhsh (https://dvh.sh)
|
|
@@ -9,6 +10,7 @@
|
|
|
9
10
|
* @modified Mon Sep 28, 2026
|
|
10
11
|
*/
|
|
11
12
|
import type { ComponentProps, ReactNode } from "react";
|
|
13
|
+
import { type HaruhimeToolsOptions } from "./haruhimeTools.js";
|
|
12
14
|
import { type SiteLinkItem } from "./links.js";
|
|
13
15
|
/** One footer column: a title (also the nav landmark's name) and its entries. */
|
|
14
16
|
export type SiteFooterColumn = {
|
|
@@ -19,6 +21,11 @@ export type SiteFooterColumn = {
|
|
|
19
21
|
export type SiteFooterProps = Omit<ComponentProps<"footer">, "children"> & {
|
|
20
22
|
/** Link columns, left to right. Internal hrefs use `next/link`, external ones a plain `<a>`. */
|
|
21
23
|
columns?: readonly SiteFooterColumn[] | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Adds the "haruhime tools" column (haruhimeToolsColumn): the other haruhime.moe tools and
|
|
26
|
+
* "All tools". `current` leaves this tool out; `position` places it (default 1).
|
|
27
|
+
*/
|
|
28
|
+
tools?: HaruhimeToolsOptions | undefined;
|
|
22
29
|
/** Rendered above the fine print, e.g. a "clear local data" control. */
|
|
23
30
|
extra?: ReactNode;
|
|
24
31
|
/** One line of small print, e.g. a trademark notice. */
|
|
@@ -38,8 +45,8 @@ export type SiteFooterProps = Omit<ComponentProps<"footer">, "children"> & {
|
|
|
38
45
|
};
|
|
39
46
|
/**
|
|
40
47
|
* @function SiteFooter
|
|
41
|
-
* @param props {SiteFooterProps} columns, extra slot, fine print, parent, GitHub and Discord
|
|
48
|
+
* @param props {SiteFooterProps} columns, the tools column, extra slot, fine print, parent, GitHub and Discord
|
|
42
49
|
* links and their names, and native footer props
|
|
43
50
|
* @returns {JSX.Element} the footer: columns on top, then extra, fine print and the brand row
|
|
44
51
|
*/
|
|
45
|
-
export declare function SiteFooter({ columns, extra, finePrint, parentLink, parentHref, githubHref, githubLabel, discordHref, discordLabel, className, ...props }: SiteFooterProps): import("react").JSX.Element;
|
|
52
|
+
export declare function SiteFooter({ columns: ownColumns, tools, extra, finePrint, parentLink, parentHref, githubHref, githubLabel, discordHref, discordLabel, className, ...props }: SiteFooterProps): import("react").JSX.Element;
|
|
@@ -4,6 +4,7 @@ import { AutoLink } from "../basics/AutoLink.js";
|
|
|
4
4
|
import { DiscordIcon } from "../icons/DiscordIcon.js";
|
|
5
5
|
import { GitHubIcon } from "../icons/GitHubIcon.js";
|
|
6
6
|
import { HaruhimeWordmarkLink } from "../icons/HaruhimeWordmarkLink.js";
|
|
7
|
+
import { haruhimeToolsColumn } from "./haruhimeTools.js";
|
|
7
8
|
import { LinkNote } from "./LinkNote.js";
|
|
8
9
|
import { linkItemKey } from "./links.js";
|
|
9
10
|
// The GitHub icon link in the bottom row.
|
|
@@ -15,11 +16,16 @@ const DISCORD_LINK = "shrink-0 text-c1 transition-opacity hover:opacity-80";
|
|
|
15
16
|
const GRID_COLUMNS = ["", "", "sm:grid-cols-2", "sm:grid-cols-3", "sm:grid-cols-4"];
|
|
16
17
|
/**
|
|
17
18
|
* @function SiteFooter
|
|
18
|
-
* @param props {SiteFooterProps} columns, extra slot, fine print, parent, GitHub and Discord
|
|
19
|
+
* @param props {SiteFooterProps} columns, the tools column, extra slot, fine print, parent, GitHub and Discord
|
|
19
20
|
* links and their names, and native footer props
|
|
20
21
|
* @returns {JSX.Element} the footer: columns on top, then extra, fine print and the brand row
|
|
21
22
|
*/
|
|
22
|
-
export function SiteFooter({ columns = [], extra, finePrint, parentLink = true, parentHref = "https://www.haruhime.moe", githubHref = "https://github.com/haruhimemoe", githubLabel = "haruhimemoe on GitHub", discordHref, discordLabel = "Discord", className, ...props }) {
|
|
23
|
+
export function SiteFooter({ columns: ownColumns = [], tools, extra, finePrint, parentLink = true, parentHref = "https://www.haruhime.moe", githubHref = "https://github.com/haruhimemoe", githubLabel = "haruhimemoe on GitHub", discordHref, discordLabel = "Discord", className, ...props }) {
|
|
24
|
+
const columns = [...ownColumns];
|
|
25
|
+
if (tools) {
|
|
26
|
+
const at = Math.max(0, Math.min(tools.position ?? 1, columns.length));
|
|
27
|
+
columns.splice(at, 0, haruhimeToolsColumn(tools));
|
|
28
|
+
}
|
|
23
29
|
const fine = finePrint ? _jsx("p", { className: "text-c4 text-xs", children: finePrint }) : null;
|
|
24
30
|
const github = githubHref ? (_jsx("a", { href: githubHref, "aria-label": githubLabel, className: ICON_LINK, children: _jsx(GitHubIcon, {}) })) : null;
|
|
25
31
|
const discord = discordHref ? (_jsx("a", { href: discordHref, "aria-label": discordLabel, className: DISCORD_LINK, children: _jsx(DiscordIcon, {}) })) : null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file src/components/shell/haruhimeTools.ts
|
|
3
|
+
* @desc The haruhime.moe tools as data (HARUHIME_TOOLS) and the footer column that links them
|
|
4
|
+
* from each tool (haruhimeToolsColumn): every other tool plus "All tools" on the parent
|
|
5
|
+
* site. Sibling subdomains are separate sites to search engines, so each tool links the
|
|
6
|
+
* others. Server-safe: no directive, no hooks.
|
|
7
|
+
* @author David @dvhsh (https://dvh.sh)
|
|
8
|
+
* @created Mon Sep 28, 2026
|
|
9
|
+
* @modified Mon Sep 28, 2026
|
|
10
|
+
*/
|
|
11
|
+
import type { SiteLinkItem } from "./links.js";
|
|
12
|
+
/** A live haruhime.moe tool's id: its subdomain. */
|
|
13
|
+
export type HaruhimeToolId = "packs" | "pools" | "bb";
|
|
14
|
+
/** One live haruhime.moe tool: its name, home page and what it is in a few words. */
|
|
15
|
+
export type HaruhimeTool = {
|
|
16
|
+
id: HaruhimeToolId;
|
|
17
|
+
name: string;
|
|
18
|
+
href: string;
|
|
19
|
+
/** A few words after the name in the footer, like "mappool downloads". */
|
|
20
|
+
blurb: string;
|
|
21
|
+
};
|
|
22
|
+
/** The live haruhime.moe tools in launch order. A tool joins this list once it's live. */
|
|
23
|
+
export declare const HARUHIME_TOOLS: readonly HaruhimeTool[];
|
|
24
|
+
/** haruhimeToolsColumn's (and SiteFooter's `tools` prop's) options. */
|
|
25
|
+
export type HaruhimeToolsOptions = {
|
|
26
|
+
/** The tool the footer sits on. It's left out of the list (its own column links it). */
|
|
27
|
+
current?: HaruhimeToolId | undefined;
|
|
28
|
+
/** The column's title (and nav landmark name). Default "haruhime tools". */
|
|
29
|
+
title?: string | undefined;
|
|
30
|
+
/** The last entry, linking the parent site. Default "All tools"; false leaves it out. */
|
|
31
|
+
allLabel?: string | false | undefined;
|
|
32
|
+
/** Where "All tools" links. Default "https://www.haruhime.moe". */
|
|
33
|
+
allHref?: string | undefined;
|
|
34
|
+
/** Where SiteFooter puts the column among `columns` (0 is first). Default 1, after the first. */
|
|
35
|
+
position?: number | undefined;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* @function haruhimeToolsColumn
|
|
39
|
+
* @param options {HaruhimeToolsOptions} the current tool, title and "All tools" link
|
|
40
|
+
* @returns {{ title: string; items: SiteLinkItem[] }} a footer column: each other tool as
|
|
41
|
+
* "name: blurb", then "All tools" on the parent site
|
|
42
|
+
*/
|
|
43
|
+
export declare function haruhimeToolsColumn(options?: HaruhimeToolsOptions): {
|
|
44
|
+
title: string;
|
|
45
|
+
items: SiteLinkItem[];
|
|
46
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file src/components/shell/haruhimeTools.ts
|
|
3
|
+
* @desc The haruhime.moe tools as data (HARUHIME_TOOLS) and the footer column that links them
|
|
4
|
+
* from each tool (haruhimeToolsColumn): every other tool plus "All tools" on the parent
|
|
5
|
+
* site. Sibling subdomains are separate sites to search engines, so each tool links the
|
|
6
|
+
* others. Server-safe: no directive, no hooks.
|
|
7
|
+
* @author David @dvhsh (https://dvh.sh)
|
|
8
|
+
* @created Mon Sep 28, 2026
|
|
9
|
+
* @modified Mon Sep 28, 2026
|
|
10
|
+
*/
|
|
11
|
+
/** The live haruhime.moe tools in launch order. A tool joins this list once it's live. */
|
|
12
|
+
export const HARUHIME_TOOLS = [
|
|
13
|
+
{ id: "packs", name: "packs", href: "https://packs.haruhime.moe", blurb: "mappool downloads" },
|
|
14
|
+
{ id: "pools", name: "pools", href: "https://pools.haruhime.moe", blurb: "mappool builder" },
|
|
15
|
+
{ id: "bb", name: "bb", href: "https://bb.haruhime.moe", blurb: "osu! BBCode editor" },
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* @function haruhimeToolsColumn
|
|
19
|
+
* @param options {HaruhimeToolsOptions} the current tool, title and "All tools" link
|
|
20
|
+
* @returns {{ title: string; items: SiteLinkItem[] }} a footer column: each other tool as
|
|
21
|
+
* "name: blurb", then "All tools" on the parent site
|
|
22
|
+
*/
|
|
23
|
+
export function haruhimeToolsColumn(options = {}) {
|
|
24
|
+
const { current, title = "haruhime tools", allLabel = "All tools" } = options;
|
|
25
|
+
const items = HARUHIME_TOOLS.filter((tool) => tool.id !== current).map((tool) => ({ href: tool.href, label: `${tool.name}: ${tool.blurb}` }));
|
|
26
|
+
if (allLabel !== false) {
|
|
27
|
+
items.push({ href: options.allHref ?? "https://www.haruhime.moe", label: allLabel });
|
|
28
|
+
}
|
|
29
|
+
return { title, items };
|
|
30
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export { type BeatmapStatKey, BeatmapStats, type BeatmapStatsProps, } from "./co
|
|
|
51
51
|
export { ModBadge, type ModBadgeProps } from "./components/osu/ModBadge.js";
|
|
52
52
|
export { StarRating, type StarRatingProps } from "./components/osu/StarRating.js";
|
|
53
53
|
export { HeaderMenu, type HeaderMenuItem, type HeaderMenuProps, } from "./components/shell/HeaderMenu.js";
|
|
54
|
+
export { HARUHIME_TOOLS, type HaruhimeTool, type HaruhimeToolId, type HaruhimeToolsOptions, haruhimeToolsColumn, } from "./components/shell/haruhimeTools.js";
|
|
54
55
|
export { type LinkTabItem, LinkTabs, type LinkTabsProps } from "./components/shell/LinkTabs.js";
|
|
55
56
|
export type { SiteLinkItem } from "./components/shell/links.js";
|
|
56
57
|
export { NavLinks, type NavLinksProps, type SiteNavAlign } from "./components/shell/NavLinks.js";
|
package/dist/index.js
CHANGED
|
@@ -57,6 +57,7 @@ export { ModBadge } from "./components/osu/ModBadge.js";
|
|
|
57
57
|
export { StarRating } from "./components/osu/StarRating.js";
|
|
58
58
|
// Shell
|
|
59
59
|
export { HeaderMenu, } from "./components/shell/HeaderMenu.js";
|
|
60
|
+
export { HARUHIME_TOOLS, haruhimeToolsColumn, } from "./components/shell/haruhimeTools.js";
|
|
60
61
|
export { LinkTabs } from "./components/shell/LinkTabs.js";
|
|
61
62
|
export { NavLinks } from "./components/shell/NavLinks.js";
|
|
62
63
|
export { PageShell } from "./components/shell/PageShell.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haruhimemoe/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "React components for the haruhime.moe osu! tools on Next.js: the osu!-web-style palette as a Tailwind theme, buttons, cards, form fields and confirms, filter controls, tables, osu! beatmap display pieces and the site header and footer.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"osu",
|