@awesomephant/reactcake 1.1.2 → 1.2.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 ADDED
@@ -0,0 +1,6 @@
1
+ # [1.2.0](https://github.com/awesomephant/reactcake/compare/v1.1.2...v1.2.0) (2026-11-15)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add zIndex prop ([9d57d3f](https://github.com/awesomephant/reactcake/commit/9d57d3ff786a969f9224a90a527e38993dec7899))
package/Readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A headless chart framework for React inspired by [Layercake](https://layercake.graphics/). See [documentation](https://reactcake.maxkohler.com/) for usage and motivation.
4
4
 
5
- ![NPM Version](https://img.shields.io/npm/v/%40awesomephant%2Freactcake) [![release](https://github.com/awesomephant/reactcake/actions/workflows/release.yml/badge.svg)](https://github.com/awesomephant/reactcake/actions/workflows/release.yml)
5
+ [![NPM Version](https://img.shields.io/npm/v/%40awesomephant%2Freactcake)](https://www.npmjs.com/package/@awesomephant/reactcake) [![release](https://github.com/awesomephant/reactcake/actions/workflows/release.yml/badge.svg)](https://github.com/awesomephant/reactcake/actions/workflows/release.yml)
6
6
 
7
7
  ## Contributing
8
8
 
@@ -6,7 +6,14 @@ interface HtmlProps extends LayoutProps {
6
6
  children?: ReactNode;
7
7
  }
8
8
 
9
- const Html = ({ overflow = "visible", label, labelledBy, describedBy, children }: HtmlProps) => {
9
+ const Html = ({
10
+ overflow = "visible",
11
+ zIndex,
12
+ label,
13
+ labelledBy,
14
+ describedBy,
15
+ children,
16
+ }: HtmlProps) => {
10
17
  const { padding } = useReactCake();
11
18
 
12
19
  return (
@@ -22,6 +29,7 @@ const Html = ({ overflow = "visible", label, labelledBy, describedBy, children }
22
29
  right: `${padding.right}px`,
23
30
  bottom: `${padding.bottom}px`,
24
31
  overflow,
32
+ zIndex,
25
33
  }}
26
34
  >
27
35
  {children}
@@ -29,4 +37,4 @@ const Html = ({ overflow = "visible", label, labelledBy, describedBy, children }
29
37
  );
30
38
  };
31
39
 
32
- export default Html;
40
+ export { Html, type HtmlProps };
File without changes
@@ -2,26 +2,43 @@ import { createContext, useContext, type CSSProperties, type ReactNode } from "r
2
2
  import { extent } from "d3-array";
3
3
 
4
4
  import { useDimensions } from "../hooks/useDimensions";
5
- import type { DatumValue, Padding, ScaleLike, ContextValue } from "../types";
5
+ import type { Padding, ScaleLike, ContextValue, DomainLike, Accessor } from "../types";
6
6
 
7
7
  const ReactCakeContext = createContext<ContextValue>(null);
8
8
 
9
+ type RangeLike = [number, number];
10
+
9
11
  interface ReactCakeProps {
10
- x?: string | ((d: unknown, i: number) => Datum);
11
- x2?: string | ((d: unknown, i: number) => Datum);
12
- y?: string | ((d: unknown, i: number) => Datum);
13
- data?: unknown[];
14
- flatData?: unknown[];
12
+ data: object[];
13
+ /**
14
+ * x accs comment
15
+ */
16
+ x?: Accessor;
17
+ x2?: Accessor;
18
+ y?: Accessor;
19
+ z?: Accessor;
20
+ flatData?: object[];
15
21
  padding?: Padding;
16
22
  xScale?: ScaleLike;
17
- yDomain?: [DatumValue | null, DatumValue | null];
23
+ xRange?: RangeLike;
24
+ xDomain?: DomainLike;
25
+ x2Scale?: ScaleLike;
18
26
  yScale?: ScaleLike;
27
+ yRange?: RangeLike;
28
+ yDomain?: DomainLike;
19
29
  zScale?: ScaleLike;
30
+ zRange?: RangeLike;
31
+ zDomain?: DomainLike;
20
32
  style?: CSSProperties;
21
33
  percentRange?: boolean;
22
34
  children?: ReactNode;
23
35
  }
24
36
 
37
+ /**
38
+ * This is a comment
39
+ * @param param0
40
+ * @returns
41
+ */
25
42
  const ReactCake = ({
26
43
  data = [],
27
44
  flatData,
@@ -50,7 +67,7 @@ const ReactCake = ({
50
67
  const _x = typeof x === "string" ? (d) => d[x] : x;
51
68
  const _x2 = typeof x2 === "string" ? (d) => d[x2] : x2;
52
69
  const _y = typeof y === "string" ? (d) => d[y] : y;
53
- const _z = typeof y === "string" ? (d) => d[z] : z;
70
+ const _z = typeof z === "string" ? (d) => d[z] : z;
54
71
 
55
72
  const xIsBandscale = xScale && typeof xScale.bandwidth === "function";
56
73
  const yIsBandscale = yScale && typeof yScale.bandwidth === "function";
@@ -123,4 +140,4 @@ function useReactCake() {
123
140
  return context;
124
141
  }
125
142
 
126
- export { ReactCake, useReactCake };
143
+ export { ReactCake, useReactCake, type ReactCakeProps };
@@ -2,7 +2,7 @@ import { type ReactNode } from "react";
2
2
  import { useReactCake } from "../ReactCake";
3
3
  import { LayoutProps } from "../types";
4
4
 
5
- interface SvgProps extends LayoutProps {
5
+ interface ScaledSvgProps extends LayoutProps {
6
6
  title?: string;
7
7
  children?: ReactNode;
8
8
  }
@@ -14,7 +14,8 @@ const ScaledSvg = ({
14
14
  describedBy,
15
15
  title,
16
16
  overflow = "visible",
17
- }: SvgProps) => {
17
+ zIndex,
18
+ }: ScaledSvgProps) => {
18
19
  const { padding } = useReactCake();
19
20
  return (
20
21
  <>
@@ -33,6 +34,7 @@ const ScaledSvg = ({
33
34
  top: `${padding.top}px`,
34
35
  left: `${padding.left}px`,
35
36
  overflow: overflow,
37
+ zIndex,
36
38
  }}
37
39
  >
38
40
  {title && <title>{title}</title>}
@@ -42,4 +44,4 @@ const ScaledSvg = ({
42
44
  );
43
45
  };
44
46
 
45
- export default ScaledSvg;
47
+ export { ScaledSvg, type ScaledSvgProps };
package/lib/Svg/index.tsx CHANGED
@@ -7,7 +7,7 @@ interface SvgProps extends LayoutProps {
7
7
  children?: ReactNode;
8
8
  }
9
9
 
10
- const Svg = ({ children, title, overflow = "hidden" }: SvgProps) => {
10
+ const Svg = ({ children, title, overflow = "hidden", zIndex }: SvgProps) => {
11
11
  const { padding } = useReactCake();
12
12
  return (
13
13
  <svg
@@ -23,6 +23,7 @@ const Svg = ({ children, title, overflow = "hidden" }: SvgProps) => {
23
23
  bottom: 0,
24
24
  right: 0,
25
25
  overflow: overflow,
26
+ zIndex,
26
27
  }}
27
28
  >
28
29
  {title && <title>{title}</title>}
@@ -31,4 +32,4 @@ const Svg = ({ children, title, overflow = "hidden" }: SvgProps) => {
31
32
  );
32
33
  };
33
34
 
34
- export default Svg;
35
+ export { Svg, type SvgProps };
package/lib/index.ts CHANGED
@@ -1,6 +1,16 @@
1
- import Html from "./Html/index.tsx";
2
- import Svg from "./Svg";
3
- import ScaledSvg from "./ScaledSvg"
4
- import { ReactCake , useReactCake} from "./ReactCake";
1
+ import { Html, type HtmlProps } from "./Html/index.tsx";
2
+ import { Svg, type SvgProps } from "./Svg";
3
+ import { ScaledSvg, type ScaledSvgProps } from "./ScaledSvg";
4
+ import { ReactCake, useReactCake, type ReactCakeProps } from "./ReactCake/index.tsx";
5
5
 
6
- export {ReactCake, useReactCake, Html, Svg, ScaledSvg};
6
+ export {
7
+ Html,
8
+ ReactCake,
9
+ useReactCake,
10
+ Svg,
11
+ ScaledSvg,
12
+ type HtmlProps,
13
+ type ScaledSvgProps,
14
+ type SvgProps,
15
+ type ReactCakeProps,
16
+ };
package/lib/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactcake",
3
3
  "dependencies": {
4
- "d3-array": "^3.2.4"
4
+ "d3-array": "^3.2.5"
5
5
  },
6
6
  "release": {
7
7
  "branches": [
package/lib/types.ts CHANGED
@@ -1,8 +1,14 @@
1
1
  import { type ReactNode } from "react";
2
2
 
3
- export type DatumValue = number | Date | string;
3
+ export type DatumValue = number | string | Date;
4
4
  export type TickFormatter<TValue = DatumValue> = (value: TValue) => ReactNode;
5
5
 
6
+ export type DomainLike =
7
+ | [min: number | null, max: number | null]
8
+ | Array<string | number | null>
9
+ | ((domain: Array<any>) => Array<any>)
10
+ | undefined;
11
+
6
12
  export type Padding = {
7
13
  top?: number;
8
14
  left?: number;
@@ -12,7 +18,7 @@ export type Padding = {
12
18
 
13
19
  export interface ScaleLike<T = DatumValue> {
14
20
  (value: unknown): number;
15
- domain: () => T[];
21
+ domain: (domain: DomainLike) => ScaleLike<T>;
16
22
  range: (range: [number, number]) => ScaleLike<T>;
17
23
  ticks?: (count?: number) => T[];
18
24
  tickFormat?: (count?: number) => TickFormatter<T>;
@@ -20,7 +26,7 @@ export interface ScaleLike<T = DatumValue> {
20
26
  invert?: (d: number) => ScaleLike;
21
27
  }
22
28
 
23
- type Accessor = (x: DatumValue) => number
29
+ export type Accessor = string | ((d: unknown, i?: number) => unknown);
24
30
 
25
31
  export interface ContextValue {
26
32
  width: number;
@@ -39,8 +45,15 @@ export interface ContextValue {
39
45
  }
40
46
 
41
47
  export interface LayoutProps {
42
- overflow?: "hidden" | "visible",
48
+ /**
49
+ * Sets the CSS overflow property
50
+ */
51
+ overflow?: "hidden" | "visible";
43
52
  label?: string;
53
+ /**
54
+ * Sets the aria-labelledby attribute
55
+ */
44
56
  labelledBy?: string;
45
57
  describedBy?: string;
58
+ zIndex?: number;
46
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomephant/reactcake",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "A headless chart framework for React inspired by Layercake",
5
5
  "keywords": [
6
6
  "react",
@@ -27,21 +27,30 @@
27
27
  "build:ts": "esbuild lib/index.ts --outdir=./dist --bundle",
28
28
  "build:min": "esbuild lib/index.ts --outdir=./dist --entry-names=[dir]/[name].min --bundle --minify",
29
29
  "build:types": "tsc",
30
- "build:lib": "run-p 'build:ts' 'build:min'",
31
- "build:demo": "esbuild src/index.ts src/index.html --loader:.html=copy --outdir=./_site --minify"
30
+ "build:lib": "run-p 'build:ts' 'build:min'"
32
31
  },
33
32
  "devDependencies": {
34
- "esbuild": "^0.28.0",
33
+ "esbuild": "^0.28.2",
35
34
  "npm-run-all": "^4.1.5",
36
- "tsx": "^4.21.0",
37
- "typescript": "^7.0.2"
35
+ "tsx": "^4.23.15",
36
+ "typescript": "^6.0.0"
38
37
  },
39
38
  "workspaces": [
40
- "site",
41
- "lib"
39
+ "lib",
40
+ "site"
42
41
  ],
43
42
  "allowScripts": {
44
43
  "esbuild@0.28.2": true,
45
- "fsevents@2.3.3": true
44
+ "fsevents@2.3.3": true,
45
+ "@parcel/watcher@2.6.0": true
46
+ },
47
+ "release": {
48
+ "plugins": [
49
+ "@semantic-release/commit-analyzer",
50
+ "@semantic-release/release-notes-generator",
51
+ "@semantic-release/changelog",
52
+ "@semantic-release/npm",
53
+ "@semantic-release/github"
54
+ ]
46
55
  }
47
56
  }
@@ -1,5 +1,5 @@
1
1
  // @ts-check
2
- import { defineConfig } from 'astro/config';
2
+ import { defineConfig, fontProviders } from 'astro/config';
3
3
  import {transformerRenderIndentGuides, transformerRenderLineNumber} from "@shikijs/transformers"
4
4
 
5
5
  import mdx from '@astrojs/mdx';
@@ -7,11 +7,22 @@ import mdx from '@astrojs/mdx';
7
7
  import react from '@astrojs/react';
8
8
 
9
9
  export default defineConfig({
10
+ fonts: [{
11
+ provider: fontProviders.local(),
12
+ name: "Areal",
13
+ cssVariable: "--font-areal",
14
+ options: {
15
+ variants: [{
16
+ weight: "100 900",
17
+ style: "normal",
18
+ src:["./src/assets/ABCArealVariable.woff2"]
19
+ }]
20
+ }
21
+ }],
10
22
  markdown: {
11
23
  shikiConfig: {
12
24
  theme: 'css-variables',
13
25
  defaultColor: false,
14
- transformers:[transformerRenderLineNumber(), transformerRenderIndentGuides()]
15
26
  },
16
27
  syntaxHighlight: {
17
28
  type: 'shiki',
package/site/package.json CHANGED
@@ -7,23 +7,29 @@
7
7
  },
8
8
  "scripts": {
9
9
  "start": "astro dev",
10
- "build": "astro build",
10
+ "build:typedoc": "typedoc ../lib/index.ts --tsconfig ../tsconfig.json --json ./src/content/typedoc.json",
11
+ "build:astro": "astro build",
11
12
  "preview": "astro preview",
12
- "astro": "astro"
13
+ "astro": "astro",
14
+ "build": "run-s 'build:*'"
13
15
  },
14
16
  "dependencies": {
15
- "@astrojs/markdown-satteri": "^0.4.6",
16
- "@astrojs/mdx": "^8.1.2",
17
- "@astrojs/react": "^7.1.2",
18
- "astro": "^7.4.4",
19
- "d3-scale": "^4.0.2",
17
+ "@astrojs/markdown-satteri": "^0.4.7",
18
+ "@astrojs/mdx": "^8.1.3",
19
+ "@astrojs/react": "^7.1.4",
20
+ "astro": "^7.4.7",
21
+ "d3-scale": "^4.0.3",
20
22
  "react": "^19.3.1",
21
23
  "react-dom": "^19.3.1"
22
24
  },
23
25
  "devDependencies": {
26
+ "@semantic-release/changelog": "^7.0.0",
24
27
  "@shikijs/transformers": "^4.6.0",
25
28
  "@types/d3-scale": "^4.0.9",
26
29
  "@types/react": "^19.3.0",
27
- "@types/react-dom": "^19.3.0"
30
+ "@types/react-dom": "^19.3.0",
31
+ "npm-run-all": "^4.1.5",
32
+ "sass-embedded": "^1.108.2",
33
+ "typedoc": "^0.28.20"
28
34
  }
29
35
  }
@@ -10,8 +10,7 @@ const {height, width = "100%"} = Astro.props
10
10
 
11
11
  <style>
12
12
  .container {
13
- margin: 1rem 0;
14
13
  border: 1px solid var(--blue-50);
15
- font-family: sans-serif;
14
+ font-size: 13px;
16
15
  }
17
16
  </style>
@@ -0,0 +1,55 @@
1
+ ---
2
+ import { getCollection } from "astro:content";
3
+
4
+ const {data} = Astro.props;
5
+ const typedoc = await getCollection('typedoc');
6
+
7
+ const expandReferenceType = (name: string, data) => {
8
+ const ref = data.find(d => d.data.name === name)
9
+ return ref ? ref.data.children : null;
10
+ }
11
+
12
+ const expanded = data[0].parameters ? data[0].parameters.map(d => {
13
+ return d.type.type === "reference"? expandReferenceType(d.type.name, typedoc): d.type
14
+ }).flat(): []
15
+
16
+ ---
17
+
18
+ <ul>
19
+ {expanded.map(d =>
20
+ <>
21
+ <li><span>{d?.name}{!d?.flags.isOptional && <strong class="required">required</strong>}</span><span><code>{d?.type.type === "union"? `${d.type.types.map(t => `"${t.value}"`).join(" | ")}` : d?.type.type ==="array"?<code>{d.type.elementType.name}[]</code> : d?.type?.name}</code></span>{d.comment && <span>{d.comment.summary[0].text}</span>}</li>
22
+ </>
23
+ )}
24
+ </ul>
25
+
26
+ <style lang="scss">
27
+ ul {
28
+ display: grid;
29
+ grid-template-columns: repeat(2, max-content) 1fr;
30
+ margin: 0;
31
+ column-gap: 2rem;
32
+ margin-bottom: 1rem;
33
+ width: 100%;
34
+ }
35
+
36
+ li {
37
+ display: grid;
38
+ grid-template-columns: subgrid;
39
+ grid-column: 1 / 4;
40
+ border-bottom: 1px dotted currentColor;
41
+ &:last-child {
42
+ border-bottom: 0;
43
+ }
44
+ }
45
+ .required {
46
+ margin-left: .5ch;
47
+ background: #f2d9d9;
48
+ font-family: monospace;
49
+ padding: .1em .3em;
50
+ padding-bottom: 0;
51
+ font-size: .9em;
52
+ font-weight: normal;
53
+ text-transform: uppercase;
54
+ }
55
+ </style>
@@ -0,0 +1,18 @@
1
+ ## Background
2
+
3
+ ReactCake provides useful context for drawing data-driven charts, like a shared coordinate system, data extents and margins. Components that draw actual chart elements, like bars and lines, live in your project or your own component library; ReactCake is completely agnostic to what you render with it.
4
+
5
+ It provides sensible defaults and infers as much information as possible from your data, but also exposes fine-grained props to configure things yourself. Its primary use case are custom news graphics.
6
+
7
+ ReactCake is built on [D3](https://d3js.org/what-is-d3).
8
+
9
+ ### Relationship to Layercake
10
+
11
+ This project is an attempt to carefully translate the overall approach and development ergonomics of the Layercake framework from Svelte to React. It does not aim for feature parity or identical API surfaces.
12
+
13
+
14
+ ### Prior work
15
+
16
+ - Rich Harris (2020): *[A new technique for making responsive, JavaScript-free charts](https://dev.to/richharris/a-new-technique-for-making-responsive-javascript-free-charts-gmp)*
17
+ - Michael Keller + contributors: *[Layercake](https://layercake.graphics/)*
18
+ - Rich Harris (2020): *[pancake](https://github.com/Rich-Harris/pancake)*
@@ -0,0 +1,38 @@
1
+ ### Installation
2
+
3
+ ```bash
4
+ npm install --save @awesomephant/reactcake
5
+ ```
6
+
7
+ ### Usage
8
+
9
+ ```tsx
10
+ import { ReactCake, Html, Svg } from "@awesomephant/reactcake";
11
+ import { scaleLinear, scaleBand } from "d3-scale"
12
+
13
+ // Chart components live in your project
14
+ import { xScale, yScale, Bars } from "./lib";
15
+
16
+ const data = [
17
+ {year: 2024, value: 32},
18
+ {year: 2025, value: 15},
19
+ {year: 2026, value: 52}
20
+ ];
21
+
22
+ // Use any d3 scale
23
+ const xScale = scaleBand();
24
+ const yScale = scaleLinear();
25
+
26
+ // Build charts declaratively
27
+ return (
28
+ <ReactCake data={data} x="year" y="value" xScale={xScale} yScale={yScale}>
29
+ <Html>
30
+ <AxisX />
31
+ <AxisY />
32
+ </Html>
33
+ <Svg>
34
+ <Bars/>
35
+ </Svg>
36
+ </ReactCake>
37
+ );
38
+ ```
@@ -0,0 +1,8 @@
1
+ import { defineCollection } from "astro:content";
2
+ import { file } from "astro/loaders";
3
+
4
+ const typedoc = defineCollection({
5
+ loader: file("./src/content/typedoc.json", { parser: (s) => JSON.parse(s).children }),
6
+ });
7
+
8
+ export const collections = { typedoc };
@@ -9,7 +9,7 @@
9
9
  }
10
10
 
11
11
  .tick__mark {
12
- border-left: 1px solid var(--blue-50);
12
+ border-left: 1px solid currentColor;
13
13
  position: absolute;
14
14
  transform: translateX(-50%);
15
15
  }
@@ -17,20 +17,19 @@
17
17
  .gridline {
18
18
  bottom: 0;
19
19
  position: absolute;
20
- border-left: 1px dotted var(--blue-50);
20
+ border-left: 1px dotted currentColor;
21
21
  }
22
22
 
23
23
 
24
24
  .baseline {
25
25
  position: absolute;
26
- border-bottom: 1px solid var(--blue-50);
26
+ border-bottom: 1px solid currentColor;
27
27
  width: 100%;
28
28
  }
29
29
 
30
30
  .tick__text {
31
31
  display: block;
32
32
  font-size: var(--ms--1);
33
- color: var(--blue-50);
34
33
  position: relative;
35
34
  white-space: nowrap;
36
35
  }
@@ -11,6 +11,7 @@ interface AxisYProps {
11
11
  grid?: boolean;
12
12
  showTicks?: boolean;
13
13
  snapLabels?: boolean;
14
+ tickGutter: number;
14
15
  tickLength?: number;
15
16
  }
16
17
 
@@ -23,7 +24,7 @@ const AxisY = ({
23
24
  tickGutter = 3,
24
25
  format = (d) => String(d),
25
26
  }: AxisYProps) => {
26
- const { yScale, padding } = useReactCake();
27
+ const { yScale } = useReactCake();
27
28
  const isBandwidth = typeof yScale.bandwidth === "function";
28
29
 
29
30
  const tickVals = Array.isArray(ticks)
@@ -6,7 +6,7 @@
6
6
 
7
7
  .tick {
8
8
  position: absolute;
9
- border-top: 1px solid var(--blue-50);
9
+ border-top: 1px solid currentColor;
10
10
  }
11
11
 
12
12
 
@@ -14,20 +14,18 @@
14
14
  left: 0;
15
15
  right: 0;
16
16
  position: absolute;
17
- border-top: 1px dotted var(--blue-50);
17
+ border-top: 1px dotted currentColor;
18
18
  }
19
19
 
20
-
21
20
  .baseline {
22
21
  position: absolute;
23
- border-left: 1px solid var(--blue-50);
22
+ border-left: 1px solid currentColor;
24
23
  height: 100%;
25
24
  }
26
25
 
27
26
  .text {
28
27
  display: block;
29
28
  font-size: var(--ms--1);
30
- color: var(--blue-50);
31
29
  white-space: nowrap;
32
30
  transform: translateY(-50%);
33
31
  }
@@ -7,8 +7,6 @@ import { max } from "d3-array";
7
7
  import DebugPadding from "./DebugPadding";
8
8
 
9
9
  const data = [
10
- { year: 2021, value: 18 },
11
- { year: 2022, value: 12 },
12
10
  { year: 2023, value: 22 },
13
11
  { year: 2024, value: 32 },
14
12
  { year: 2025, value: 15 },
@@ -18,7 +18,7 @@ export default function Columns() {
18
18
  y={100 - valueY}
19
19
  width={colWidth}
20
20
  height={valueY}
21
- stroke="var(--blue-50)"
21
+ stroke="currentColor"
22
22
  fill="none"
23
23
  />
24
24
  );
@@ -2,6 +2,7 @@ import { useReactCake } from "../../../lib";
2
2
 
3
3
  export default function DebugPadding() {
4
4
  const { padding } = useReactCake();
5
+ const fill = "rgba(125,125,105,.1)";
5
6
  return (
6
7
  <div
7
8
  style={{
@@ -10,7 +11,7 @@ export default function DebugPadding() {
10
11
  right: 0,
11
12
  top: 0,
12
13
  bottom: 0,
13
- boxShadow: `${padding.right}px 0 var(--blue-20), 0 ${padding.bottom}px var(--blue-20), 0 ${-padding.top}px var(--blue-20), -${padding.left}px 0 var(--blue-20)`,
14
+ boxShadow: `${padding.right}px 0 ${fill}, 0 ${padding.bottom}px ${fill}, 0 ${-padding.top}px ${fill}, -${padding.left}px 0 ${fill}`,
14
15
  }}
15
16
  ></div>
16
17
  );
@@ -1,5 +1,6 @@
1
1
  ---
2
- import "./code.css"
2
+ import { Font } from "astro:assets";
3
+ import "./code.scss"
3
4
  ---
4
5
 
5
6
  <!doctype html>
@@ -10,11 +11,10 @@ import "./code.css"
10
11
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
11
12
  <meta name="generator" content={Astro.generator} />
12
13
  <title>ReactCake</title>
14
+ <Font cssVariable="--font-areal" />
13
15
  </head>
14
16
  <body>
15
- <main class="content">
16
17
  <slot />
17
- </main>
18
18
  </body>
19
19
  </html>
20
20
 
@@ -23,32 +23,33 @@ import "./code.css"
23
23
  box-sizing: border-box;
24
24
  margin: 0;
25
25
  padding: 0;
26
+ font-size: inherit;
26
27
  }
27
28
 
28
29
  body {
29
30
  margin: 0;
30
31
  width: 100%;
31
32
  padding: .5rem;
32
- font-family: Georgia, 'Times New Roman', Times, serif;
33
- --blue-70: hsl(220, 0%, 20%);
34
- --blue-50: hsl(220, 0%, 36%);
35
- --blue-30: hsl(220, 0%, 76%);
36
- --blue-20: hsl(220, 0%, 92%);
37
- --blue-10: hsl(220, 0%, 97%);
33
+ font-family: var(--font-areal), sans-serif;
34
+ --blue-70: hsl(20, 80%, 20%);
35
+ --blue-50: hsl(20, 80%, 26%);
36
+ --blue-30: hsl(20, 80%, 76%);
37
+ --blue-20: hsl(20, 80%, 92%);
38
+ --blue-10: hsl(20, 80%, 97%);
38
39
  --ms--1: .8rem
40
+ padding: 1rem;
41
+ background: #d8d2f6;
42
+ line-height: 1.25;
43
+ color: var(--blue-50);
39
44
  }
40
45
 
41
46
  a, a:visited {
42
- color: var(--blue-70);
47
+ color: var(--blue-50);
48
+ background: #f0f0f0;
49
+ text-decoration: none;
50
+ border-bottom: 1px dotted currentColor;
43
51
  }
44
52
 
45
- .content {
46
- border: 1px solid var(--blue-70);
47
- max-width: 40rem;
48
- line-height: 1.4;
49
- padding: 1rem;
50
- border-right: 1px solid var(--blue-70);
51
- }
52
53
 
53
54
  p, li {
54
55
  letter-spacing: .002em;
@@ -56,20 +57,35 @@ import "./code.css"
56
57
 
57
58
  h1 {
58
59
  font-weight: 900;
60
+ font-size: 2.75em;
61
+ transform: scaleX(.8);
62
+ transform-origin: left;
59
63
  }
60
64
 
61
65
  h2 {
66
+ transform: scaleX(.8);
67
+ transform-origin: left;
68
+ font-size: 1.75rem;
62
69
  margin-top: 1rem;
63
70
  margin-bottom: .25rem;
71
+ &:first-child {
72
+ margin-top: 0;
73
+ }
64
74
  }
65
75
  h3 {
66
- margin-top: 1.25rem;
67
76
  margin-bottom: 0.1rem;
68
77
  font-weight: 600;
78
+ font-size: 1.2em;
79
+ }
80
+ h4 {
81
+ font-weight: 400;
82
+ font-size: 1rem;
83
+ opacity: .7;
84
+ margin-bottom: 0.1rem;
69
85
  }
70
86
 
71
87
  p, ul, ol {
72
- margin-bottom: 1rem;
88
+ margin-bottom: .75em;
73
89
  &:last-child {
74
90
  margin-bottom: 0;
75
91
  }
@@ -1,12 +1,16 @@
1
1
  .astro-code {
2
- --astro-code-background: hsl(51, 62.5%, 93.7%);
2
+ --astro-code-background: white;
3
3
  --astro-code-token-comment: #666;
4
+ border: 1px solid currentColor;
4
5
  margin: 1em 0;
5
6
  margin-top: .5em;
6
7
  padding: .5em;
7
8
  font-size: 12px;
8
- line-height: 1.25;
9
+ line-height: 1.1;
9
10
  font-family: monospace;
11
+ &:last-child {
12
+ margin-bottom: 0;
13
+ }
10
14
  }
11
15
 
12
16
 
@@ -27,11 +31,10 @@ pre.astro-code .indent::before {
27
31
  opacity: 0.5;
28
32
  width: 1px;
29
33
  height: 100%;
30
- background-color: red;
31
34
  }
32
35
 
33
36
  pre.astro-code .line-number {
34
37
  user-select: none;
35
- color: #666;
36
- margin-right: 2ch;
38
+ color: rgba(black, .5);
39
+ margin-right: 3ch;
37
40
  }
@@ -0,0 +1,108 @@
1
+ ---
2
+ import { getCollection } from 'astro:content';
3
+
4
+ import Base from "../layouts/Base.astro"
5
+ import {Content as Installation} from "../content/installation.md"
6
+ import {Content as Background} from "../content/background.md"
7
+ import Example from "../components/Example.astro"
8
+ import PropList from "../components/PropList.astro"
9
+ import ColumnChart from "../examples/ColumnChart.tsx"
10
+
11
+ const typedoc = await getCollection('typedoc');
12
+
13
+ ---
14
+
15
+ <Base>
16
+
17
+ <article class="home">
18
+
19
+ <header>
20
+ <div>
21
+ <h1>ReactCake</h1>
22
+ <p>A headless chart framework for React inspired by <a href="https://layercake.graphics/">Layercake</a></p>
23
+ <ul>
24
+ <li><a href="https://github.com/awesomephant/reactcake">Github</a></li>
25
+ <li><a href="https://www.npmjs.com/package/@awesomephant/reactcake">npm</a></li>
26
+ </ul>
27
+ </div>
28
+ <Example height="12rem" >
29
+ <ColumnChart/>
30
+ </Example>
31
+ </header>
32
+
33
+ <section class="installation">
34
+ <h2>Quickstart</h2>
35
+ <Installation/>
36
+ </section>
37
+
38
+ <section class="docs">
39
+ <h2>Docs</h2>
40
+ <h3>Components</h3>
41
+ {typedoc.filter(d => d.data.kind === 64 && !d.data.name.startsWith("use")).map(d => {
42
+ return (
43
+ <>
44
+ <h3><code>{`<`}{d.data.name}{`/>`}</code></h3>
45
+ {d.data.signatures[0].comment && <p>{d.data.signatures[0].comment.summary[0].text}</p>}
46
+ <PropList data={d.data.signatures}/>
47
+ </>)
48
+ })}
49
+ <h3>Hooks</h3>
50
+ {typedoc.filter(d => d.data.kind === 64 && d.data.name.startsWith("use")).map(d => {
51
+ return (
52
+ <>
53
+ <h3><code>{d.data.name}{`()`}</code></h3>
54
+ {d.data.signatures[0].comment && <p>{d.data.signatures[0].comment.summary[0].text}</p>}
55
+ <PropList data={d.data.signatures}/>
56
+ </>)
57
+ })}
58
+ <h3>Utils</h3>
59
+
60
+ </section>
61
+
62
+ <section class="background">
63
+ <Background/>
64
+ </section>
65
+ </article>
66
+
67
+ </Base>
68
+
69
+ <style lang="scss">
70
+ .home {
71
+ display: grid;
72
+ grid-template-columns: repeat(12, 1fr);
73
+ hyphens: auto;
74
+ }
75
+
76
+ header, section {
77
+ padding: 1rem;
78
+ border: 1px solid var(--blue-50);
79
+ background-color: white;
80
+ margin-bottom: -1px;
81
+ margin-right: -1px;
82
+
83
+ }
84
+ header {
85
+ border-top: 1px solid var(--blue-50);
86
+ border-left: 1px solid var(--blue-50);
87
+ grid-column: span 2;
88
+ display: flex;
89
+ flex-flow: column;
90
+ justify-content: space-between;
91
+ }
92
+
93
+ .installation {
94
+ border-top: 1px solid var(--blue-50);
95
+ grid-column: 3 / 8;
96
+ }
97
+ .docs {
98
+ border-top: 1px solid var(--blue-50);
99
+ grid-column: 8 / 13;
100
+ grid-row: span 3;
101
+ }
102
+
103
+ .background {
104
+ grid-column: 3 / 8;
105
+ border-left: 1px solid var(--blue-50);
106
+ }
107
+
108
+ </style>
package/tsconfig.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "noUncheckedIndexedAccess": true,
8
8
  "noImplicitOverride": true,
9
9
  "outDir": "dist",
10
- "rootDir": "./lib",
10
+ "rootDir": ".",
11
11
  "declaration": true,
12
12
  "emitDeclarationOnly": true,
13
13
  "allowImportingTsExtensions": true,
@@ -1,73 +0,0 @@
1
- ---
2
- layout: "../layouts/Base.astro"
3
-
4
- ---
5
-
6
- import Example from "../components/Example.astro"
7
- import ColumnChart from "../examples/ColumnChart.tsx"
8
-
9
- # ReactCake
10
-
11
- A headless chart framework for React inspired by [Layercake](https://layercake.graphics/).
12
-
13
- <Example height="12rem" width="20rem">
14
- <ColumnChart></ColumnChart>
15
- </Example>
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install --save @awesomephant/reactcake
21
- ```
22
-
23
- ## Usage
24
-
25
- ```tsx
26
- import { ReactCake, Html, Svg } from "@awesomephant/reactcake";
27
- import { scaleLinear, scaleBand } from "d3-scale"
28
-
29
- // Chart components live in your project
30
- import { xScale, yScale, Bars } from "./lib";
31
-
32
- const data = [
33
- {year: 2024, value: 32},
34
- {year: 2025, value: 15},
35
- {year: 2026, value: 52}
36
- ];
37
-
38
- // Use any d3 scale
39
- const xScale = scaleTime();
40
- const xScale = scaleBand();
41
-
42
- // Build charts declaratively
43
- return (
44
- <ReactCake data={data} x="year" y="value" xScale={xScale} yScale={yScale}>
45
- <Html>
46
- <AxisX />
47
- <AxisY />
48
- </Html>
49
- <Svg>
50
- <Bars/>
51
- </Svg>
52
- </ReactCake>
53
- );
54
- ```
55
-
56
- ## Concepts
57
-
58
- ReactCake provides useful context for drawing data-driven charts, like a coordinate system, data extents and shared margins. Components that draw actual chart elements, like bars and lines, live in your project (or maybe a local component library), ReactCake is completely agnostic to what you render with it.
59
-
60
- It provides sensible defaults and infers as much information as possible from your data, but also exposes fine-grained props to configure things yourself.
61
-
62
- ReactCake is built on [D3](https://d3js.org/what-is-d3).
63
-
64
- ### Relationship to Layercake
65
-
66
- This project is an attempt to carefully translate the overall approach and development ergonomics of the Layercake framework from Svelte to React. It does not aim for feature parity or identical API surfaces.
67
-
68
-
69
- ### Prior work
70
-
71
- - [A new technique for making responsive, JavaScript-free charts](https://dev.to/richharris/a-new-technique-for-making-responsive-javascript-free-charts-gmp)
72
- - [Layercake](https://layercake.graphics/)
73
- - [pancake](https://github.com/Rich-Harris/pancake)