style(chart): open chart pages and surface/track tokens

- @hm-design/chart: add --hm-chart-track (radial tracks, horizontal bar
  hover band; warm neutral light) and --hm-chart-surface (slice / segment
  gaps, Dot rings, label halos, radial meter center; white by default)
- --hm-chart-bar-name-halo stays an optional override and falls back to
  --hm-chart-surface; official chart.tsx unchanged
- Storybook Chart pages (Bar / Line / Area / Donut / Pie / Radar / Radial):
  open layout without example cards, 2-4 responsive columns, one sample
  data notice per page, surface token set to the content background
- Same sample data, props, tooltip and interaction as the example cards;
  examples entry and consumer example unchanged
- README: surface / track token usage
This commit is contained in:
shkim4 committed 2026-11-12 17:12:09 +09:00
1 parent a7b56ff23e
commit 7ff852952a
15 files changed
+337 -214

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
import type { ReactNode } from "react"
import { sampleDataNotice } from "@hm-design/chart/examples"
import { StorySection } from "@/components/story-page"
// Storybook presentation only (not part of @hm-design/chart): the open Chart page layout (2026-11-12, user request).
// Charts sit directly on the Storybook content background, without the example card (background, border, padding). Each chart
// is one StorySection: H2 variant name → description (what the example shows) → thin section divider → optional toolbar → chart.
// The charts themselves are the public @hm-design/chart components on the @hm-design/chart/examples sample data, with the same
// props as the matching *Example card, so data, legend, tooltip and interaction are unchanged. No common layout change; the page
// only sets the chart's own surface token (chartPageClass).
/**
* className of every Chart page's StoryPage. The charts sit on the Storybook content background (--hm-sem-bg-content), so the page
* sets the chart's public surface token to it (2026-11-12): slice / segment gaps, Dot rings, label halos and the radial meter's
* center read as background instead of white. Only the token value is set, as a consumer would; no chart internals are overridden.
*/
export const chartPageClass = "[--hm-chart-surface:var(--hm-sem-bg-content)]"
/** One sample-data notice per page, instead of a badge and a notice under every chart. */
export function ChartSampleNotice() {
return (
<p className="m-0 text-[length:var(--hm-label-font-size)] leading-[var(--hm-label-line-height)] text-[color:var(--hm-sem-fg-secondary)]">
{sampleDataNotice}
</p>
)
}
/**
* One chart of a Chart page. `toolbar` keeps the example card's control row (Select height, so the charts of a row start at the
* same height); pass `null` for an empty row of that height next to charts that have one.
*/
export function ChartSpecimen({
title,
description,
toolbar,
children,
}: {
title: string
description?: ReactNode
toolbar?: ReactNode
children: ReactNode
}) {
return (
<StorySection title={title} description={description}>
{toolbar !== undefined ? (
<div
data-slot="chart-story-toolbar"
aria-hidden={toolbar === null ? true : undefined}
className="mb-3 flex min-h-[34px] items-center text-sm text-muted-foreground"
>
{toolbar}
</div>
) : null}
{children}
</StorySection>
)
}
// Grid columns (className of StorySectionGrid). Widths are the preview iframe width, which already excludes the Storybook sidebar.
// A third column only from 1200px, where each column keeps about 340px (Radial needs 320px). Rows align at the top; every
// chart keeps its own height. Source order is the one-column (mobile) order. All breakpoints are px (min-[…]): Tailwind does not
// order a rem breakpoint (lg) against a px one, so `lg:grid-cols-2` would win over `min-[1200px]:grid-cols-3`.
const base = "grid-cols-1 items-start *:min-w-0"
export const chartGrid = {
/** Wide charts (Bar): two per row from 1024px. */
pair: `${base} min-[1024px]:grid-cols-2`,
/** Compact round charts (Donut, Pie, Radial): two per row from 1024px, three from 1200px. */
compact: `${base} min-[1024px]:grid-cols-2 min-[1200px]:grid-cols-3`,
/** Radar (four charts): two per row from 1024px, four in one row from 1600px. */
quad: `${base} min-[1024px]:grid-cols-2 min-[1600px]:grid-cols-4`,
/**
* Plain / labelled pairs (Line, Area): two per row from 1024px (each pair in one row); from 1200px three columns that fill
* top to bottom, so the plain styles form the first row and their Dot + Label versions the second.
*/
pairs: `${base} min-[1024px]:grid-cols-2 min-[1200px]:grid-flow-col min-[1200px]:grid-cols-3 min-[1200px]:grid-rows-2`,
} as const