lucentia-ui 1.1.0 → 1.3.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.
Files changed (71) hide show
  1. package/dist/components/Chart/BarChart/Bar.d.ts +11 -0
  2. package/dist/components/Chart/BarChart/Bar.js +4 -0
  3. package/dist/components/Chart/BarChart/Bar.module.css +0 -0
  4. package/dist/components/Chart/BarChart/BarChart.d.ts +2 -0
  5. package/dist/components/Chart/BarChart/BarChart.js +23 -0
  6. package/dist/components/Chart/BarChart/BarSeries.d.ts +10 -0
  7. package/dist/components/Chart/BarChart/BarSeries.js +27 -0
  8. package/dist/components/Chart/BarChart/types.d.ts +10 -0
  9. package/dist/components/Chart/BarChart/types.js +1 -0
  10. package/dist/components/Chart/BarChart/utils.d.ts +3 -0
  11. package/dist/components/Chart/BarChart/utils.js +26 -0
  12. package/dist/components/Chart/ChartAxis.d.ts +6 -0
  13. package/dist/components/Chart/ChartAxis.js +6 -0
  14. package/dist/components/Chart/ChartContainer.d.ts +11 -0
  15. package/dist/components/Chart/ChartContainer.js +22 -0
  16. package/dist/components/Chart/ChartContainer.module.css +51 -0
  17. package/dist/components/Chart/ChartContext.d.ts +7 -0
  18. package/dist/components/Chart/ChartContext.js +9 -0
  19. package/dist/components/Chart/ChartGrid.d.ts +6 -0
  20. package/dist/components/Chart/ChartGrid.js +19 -0
  21. package/dist/components/Chart/ChartLegend.d.ts +9 -0
  22. package/dist/components/Chart/ChartLegend.js +19 -0
  23. package/dist/components/Chart/ChartTooltip.d.ts +8 -0
  24. package/dist/components/Chart/ChartTooltip.js +12 -0
  25. package/dist/components/Chart/ChartXAxis.d.ts +5 -0
  26. package/dist/components/Chart/ChartXAxis.js +16 -0
  27. package/dist/components/Chart/ChartYAxis.d.ts +6 -0
  28. package/dist/components/Chart/ChartYAxis.js +11 -0
  29. package/dist/components/Chart/LineChart/LineChart.d.ts +2 -0
  30. package/dist/components/Chart/LineChart/LineChart.js +27 -0
  31. package/dist/components/Chart/LineChart/LinePath.d.ts +9 -0
  32. package/dist/components/Chart/LineChart/LinePath.js +7 -0
  33. package/dist/components/Chart/LineChart/LinePoint.d.ts +9 -0
  34. package/dist/components/Chart/LineChart/LinePoint.js +4 -0
  35. package/dist/components/Chart/LineChart/LineSeries.d.ts +9 -0
  36. package/dist/components/Chart/LineChart/LineSeries.js +24 -0
  37. package/dist/components/Chart/LineChart/types.d.ts +9 -0
  38. package/dist/components/Chart/LineChart/types.js +1 -0
  39. package/dist/components/Chart/PieChart/PieChart.d.ts +2 -0
  40. package/dist/components/Chart/PieChart/PieChart.js +9 -0
  41. package/dist/components/Chart/PieChart/PieSeries.d.ts +2 -0
  42. package/dist/components/Chart/PieChart/PieSeries.js +40 -0
  43. package/dist/components/Chart/PieChart/PieSlice.d.ts +12 -0
  44. package/dist/components/Chart/PieChart/PieSlice.js +8 -0
  45. package/dist/components/Chart/PieChart/types.d.ts +18 -0
  46. package/dist/components/Chart/PieChart/types.js +1 -0
  47. package/dist/components/Chart/PieChart/utils.d.ts +5 -0
  48. package/dist/components/Chart/PieChart/utils.js +27 -0
  49. package/dist/components/Chart/RadarChart/RadarAxis.d.ts +4 -0
  50. package/dist/components/Chart/RadarChart/RadarAxis.js +16 -0
  51. package/dist/components/Chart/RadarChart/RadarChart.d.ts +2 -0
  52. package/dist/components/Chart/RadarChart/RadarChart.js +11 -0
  53. package/dist/components/Chart/RadarChart/RadarGrid.d.ts +5 -0
  54. package/dist/components/Chart/RadarChart/RadarGrid.js +20 -0
  55. package/dist/components/Chart/RadarChart/RadarSeries.d.ts +2 -0
  56. package/dist/components/Chart/RadarChart/RadarSeries.js +33 -0
  57. package/dist/components/Chart/RadarChart/types.d.ts +22 -0
  58. package/dist/components/Chart/RadarChart/types.js +1 -0
  59. package/dist/components/Chart/RadarChart/utils.d.ts +5 -0
  60. package/dist/components/Chart/RadarChart/utils.js +16 -0
  61. package/dist/components/Chart/index.d.ts +15 -0
  62. package/dist/components/Chart/index.js +18 -0
  63. package/dist/components/Chart/utils/getNiceTicks.d.ts +1 -0
  64. package/dist/components/Chart/utils/getNiceTicks.js +20 -0
  65. package/dist/components/Feedback/Modal/Modal.module.css +1 -1
  66. package/dist/index.d.ts +2 -0
  67. package/dist/index.js +4 -0
  68. package/dist/styles/tokens.css +28 -4
  69. package/dist/utils/date/generateCalendar.d.ts +5 -0
  70. package/dist/utils/date/generateCalendar.js +36 -0
  71. package/package.json +5 -3
@@ -0,0 +1,11 @@
1
+ type Props = {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ fill: string;
7
+ onMouseEnter?: () => void;
8
+ onMouseLeave?: () => void;
9
+ };
10
+ export declare const Bar: ({ x, y, width, height, fill, onMouseEnter, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const Bar = ({ x, y, width, height, fill, onMouseEnter, onMouseLeave, }) => {
3
+ return (_jsx("rect", { x: x, y: y, width: width, height: height, fill: fill, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: "lucentia-bar", rx: 2 }));
4
+ };
File without changes
@@ -0,0 +1,2 @@
1
+ import { BarChartProps } from "./types";
2
+ export declare const BarChart: ({ data, keys, height, barGap }: BarChartProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChartContainer } from "../ChartContainer";
4
+ import { ChartGrid } from "../ChartGrid";
5
+ import { ChartTooltip } from "../ChartTooltip";
6
+ import { ChartXAxis } from "../ChartXAxis";
7
+ import { ChartYAxis } from "../ChartYAxis";
8
+ import { getNiceTicks } from "../utils/getNiceTicks";
9
+ import { BarSeries } from "./BarSeries";
10
+ import { getMaxValue } from "./utils";
11
+ export const BarChart = ({ data, keys, height = 300, barGap = 16 }) => {
12
+ const seriesKeys = keys !== null && keys !== void 0 ? keys : Object.keys(data[0]).filter((k) => k !== "label");
13
+ const max = getMaxValue(data, seriesKeys);
14
+ const labels = data.map((d) => d.label);
15
+ const ticks = getNiceTicks(max);
16
+ const [cursor, setCursor] = useState({
17
+ x: 0,
18
+ y: 0,
19
+ });
20
+ const [tooltip, setTooltip] = useState(null);
21
+ // BarChart.tsx の return 部分を修正
22
+ return (_jsx("div", { style: { width: "100%" }, children: _jsxs(ChartContainer, { height: height, onPointerMove: (x, y) => setCursor({ x, y }), children: [_jsx(ChartGrid, {}), _jsx(ChartXAxis, { labels: labels }), _jsx(ChartYAxis, { ticks: ticks, max: ticks[ticks.length - 1] }), _jsx(BarSeries, { data: data, keys: seriesKeys, max: max, gap: barGap, onHover: (label, key, value) => setTooltip({ label, key, value }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: cursor.x + 8, y: cursor.y + 8, children: [_jsx("div", { children: tooltip.label }), _jsxs("strong", { children: [tooltip.key, ": ", tooltip.value] })] }))] }) }));
23
+ };
@@ -0,0 +1,10 @@
1
+ type Props = {
2
+ data: any[];
3
+ keys: string[];
4
+ max: number;
5
+ gap: number;
6
+ onHover?: (label: string, key: string, value: number) => void;
7
+ onLeave?: () => void;
8
+ };
9
+ export declare const BarSeries: ({ data, keys, max, gap, onHover, onLeave }: Props) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useChart } from "../ChartContext";
3
+ import { Bar } from "./Bar";
4
+ import { scaleValue } from "./utils";
5
+ export const BarSeries = ({ data, keys, max, gap, onHover, onLeave }) => {
6
+ const { width, height, padding } = useChart();
7
+ const innerWidth = width - padding * 2;
8
+ const innerHeight = height - padding * 2;
9
+ // 1グループあたりの幅(端数を切り捨てることで、右端のはみ出しを防止)
10
+ const groupWidth = Math.floor(innerWidth / data.length);
11
+ const contentWidth = groupWidth - gap;
12
+ const barUnitWidth = contentWidth / keys.length;
13
+ const actualBarWidth = barUnitWidth * 0.8;
14
+ return (_jsx("g", { children: data.map((d, i) => {
15
+ // padding + (i * groupWidth) で確実に計算
16
+ const groupX = padding + i * groupWidth;
17
+ return keys.map((key, j) => {
18
+ var _a;
19
+ const value = Number((_a = d[key]) !== null && _a !== void 0 ? _a : 0);
20
+ const barHeight = scaleValue(value, max, innerHeight);
21
+ // X座標:グループ開始位置 + 棒のオフセット
22
+ const x = groupX + (gap / 2) + (j * barUnitWidth) + (barUnitWidth - actualBarWidth) / 2;
23
+ const y = height - padding - barHeight;
24
+ return (_jsx(Bar, { x: x, y: y, width: actualBarWidth, height: barHeight, onMouseEnter: () => onHover === null || onHover === void 0 ? void 0 : onHover(d.label, key, value), onMouseLeave: onLeave, fill: `var(--chart-color-${j + 1})` }, `${i}-${key}`));
25
+ });
26
+ }) }));
27
+ };
@@ -0,0 +1,10 @@
1
+ export type BarChartDatum = {
2
+ label: string;
3
+ [key: string]: string | number;
4
+ };
5
+ export type BarChartProps = {
6
+ data: BarChartDatum[];
7
+ keys?: string[];
8
+ height?: number;
9
+ barGap?: number;
10
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare const getMaxValue: (data: any[], keys: string[]) => number;
2
+ export declare const scaleValue: (value: number, max: number, height: number) => number;
3
+ export declare const getStackMax: (data: any[], keys: string[]) => number;
@@ -0,0 +1,26 @@
1
+ export const getMaxValue = (data, keys) => {
2
+ let max = 0;
3
+ data.forEach((d) => {
4
+ keys.forEach((k) => {
5
+ var _a;
6
+ const v = Number((_a = d[k]) !== null && _a !== void 0 ? _a : 0);
7
+ if (v > max)
8
+ max = v;
9
+ });
10
+ });
11
+ return max;
12
+ };
13
+ export const scaleValue = (value, max, height) => {
14
+ if (max === 0)
15
+ return 0;
16
+ return (value / max) * height;
17
+ };
18
+ export const getStackMax = (data, keys) => {
19
+ let max = 0;
20
+ data.forEach((d) => {
21
+ const sum = keys.reduce((acc, k) => { var _a; return acc + Number((_a = d[k]) !== null && _a !== void 0 ? _a : 0); }, 0);
22
+ if (sum > max)
23
+ max = sum;
24
+ });
25
+ return max;
26
+ };
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ xLabel?: string;
3
+ yLabel?: string;
4
+ };
5
+ export declare const ChartAxis: ({ xLabel, yLabel }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChart } from "./ChartContext";
3
+ export const ChartAxis = ({ xLabel, yLabel }) => {
4
+ const { width, height, padding } = useChart();
5
+ return (_jsxs("g", { stroke: "var(--chart-axis)", children: [_jsx("line", { x1: padding, x2: width - padding, y1: height - padding, y2: height - padding }), _jsx("line", { x1: padding, x2: padding, y1: padding, y2: height - padding }), xLabel && (_jsx("text", { x: width / 2, y: height - 6, textAnchor: "middle", fill: "var(--chart-text)", fontSize: "12", children: xLabel })), yLabel && (_jsx("text", { transform: `translate(12 ${height / 2}) rotate(-90)`, textAnchor: "middle", fill: "var(--chart-text)", fontSize: "12", children: yLabel }))] }));
6
+ };
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from "react";
2
+ type Props = {
3
+ children: ReactNode;
4
+ width?: number;
5
+ height?: number;
6
+ padding?: number;
7
+ className?: string;
8
+ onPointerMove?: (x: number, y: number) => void;
9
+ };
10
+ export declare const ChartContainer: ({ children, width, height, padding, className, onPointerMove, }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useRef } from "react";
3
+ import { ChartContext } from "./ChartContext";
4
+ import styles from "./ChartContainer.module.css";
5
+ export const ChartContainer = ({ children, width = 600, height = 300, padding = 32, className, onPointerMove, }) => {
6
+ const svgRef = useRef(null);
7
+ const handleMove = (e) => {
8
+ if (!svgRef.current || !onPointerMove)
9
+ return;
10
+ const rect = svgRef.current.getBoundingClientRect();
11
+ const scaleX = width / rect.width;
12
+ const scaleY = height / rect.height;
13
+ const x = (e.clientX - rect.left) * scaleX;
14
+ const y = (e.clientY - rect.top) * scaleY;
15
+ onPointerMove(x, y);
16
+ };
17
+ return (_jsx(ChartContext.Provider, { value: {
18
+ width,
19
+ height,
20
+ padding,
21
+ }, children: _jsx("svg", { ref: svgRef, viewBox: `0 0 ${width} ${height}`, width: "100%", height: "100%", className: [styles.container, className].filter(Boolean).join(" "), onPointerMove: handleMove, children: children }) }));
22
+ };
@@ -0,0 +1,51 @@
1
+ .container {
2
+ background-color: var(--color-surface);
3
+ padding: var(--space-lg);
4
+ border-radius: var(--radius-md);
5
+ overflow: visible;
6
+ }
7
+
8
+ :root {
9
+ --chart-color-1: #99cccc; /* 明るすぎないソフトブルー */
10
+ --chart-color-2: #66b2b2;
11
+ --chart-color-3: #4da6a6;
12
+ --chart-color-4: #339999;
13
+ --chart-color-5: #008b8b;
14
+ --chart-color-6: #007a7a; /* base: 以前より落ち着いたトーン */
15
+ --chart-color-7: #006666;
16
+ --chart-color-8: #005252;
17
+ --chart-color-9: #004545;
18
+ --chart-color-10: #003333; /* 締まりのある深い色 */
19
+
20
+ --chart-grid: var(--color-border);
21
+ --chart-axis: var(--color-border);
22
+ }
23
+
24
+
25
+ html[data-theme="dark"] {
26
+ --chart-color-1: #80d5d4; /* Base: ここをスタート地点にして視認性を確保 */
27
+ --chart-color-2: #6bc2c1;
28
+ --chart-color-3: #57afae; /* 1,2,3の間で明確な色の沈み込みを作成 */
29
+ --chart-color-4: #439d9c;
30
+ --chart-color-5: #308b8b;
31
+ --chart-color-6: #1c797a;
32
+ --chart-color-7: #09686a;
33
+ --chart-color-8: #005759;
34
+ --chart-color-9: #004749;
35
+ --chart-color-10: #00383a; /* 最終地点はかなり深く */
36
+ }
37
+
38
+ .lucentia-bar {
39
+ transform-origin: bottom;
40
+ animation: barGrow 0.5s ease;
41
+ }
42
+
43
+ @keyframes barGrow {
44
+ from {
45
+ transform: scaleY(0);
46
+ }
47
+
48
+ to {
49
+ transform: scaleY(1);
50
+ }
51
+ }
@@ -0,0 +1,7 @@
1
+ export type ChartContextValue = {
2
+ width: number;
3
+ height: number;
4
+ padding: number;
5
+ };
6
+ export declare const ChartContext: import("react").Context<ChartContextValue | null>;
7
+ export declare const useChart: () => ChartContextValue;
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from "react";
2
+ export const ChartContext = createContext(null);
3
+ export const useChart = () => {
4
+ const ctx = useContext(ChartContext);
5
+ if (!ctx) {
6
+ throw new Error("Chart components must be used inside ChartContainer");
7
+ }
8
+ return ctx;
9
+ };
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ rows?: number;
3
+ columns?: number;
4
+ };
5
+ export declare const ChartGrid: ({ rows, columns }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useChart } from "./ChartContext";
3
+ export const ChartGrid = ({ rows = 4, columns = 4 }) => {
4
+ const { width, height, padding } = useChart();
5
+ const innerWidth = width - padding * 2;
6
+ const innerHeight = height - padding * 2;
7
+ const rowHeight = innerHeight / rows;
8
+ const colWidth = innerWidth / columns;
9
+ const lines = [];
10
+ for (let i = 0; i <= rows; i++) {
11
+ const y = padding + rowHeight * i;
12
+ lines.push(_jsx("line", { x1: padding, x2: width - padding, y1: y, y2: y, stroke: "var(--chart-grid)" }, `row-${i}`));
13
+ }
14
+ for (let i = 0; i <= columns; i++) {
15
+ const x = padding + colWidth * i;
16
+ lines.push(_jsx("line", { y1: padding, y2: height - padding, x1: x, x2: x, stroke: "var(--chart-grid)" }, `col-${i}`));
17
+ }
18
+ return _jsx("g", { children: lines });
19
+ };
@@ -0,0 +1,9 @@
1
+ type Item = {
2
+ label: string;
3
+ color: string;
4
+ };
5
+ type Props = {
6
+ items: Item[];
7
+ };
8
+ export declare const ChartLegend: ({ items }: Props) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const ChartLegend = ({ items }) => {
3
+ return (_jsx("div", { style: {
4
+ display: "flex",
5
+ gap: "12px",
6
+ flexWrap: "wrap",
7
+ marginTop: "8px",
8
+ }, children: items.map((item) => (_jsxs("div", { style: {
9
+ display: "flex",
10
+ alignItems: "center",
11
+ gap: "6px",
12
+ fontSize: "12px",
13
+ }, children: [_jsx("span", { style: {
14
+ width: 12,
15
+ height: 12,
16
+ background: item.color,
17
+ display: "inline-block",
18
+ } }), item.label] }, item.label))) }));
19
+ };
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from "react";
2
+ type Props = {
3
+ x: number;
4
+ y: number;
5
+ children: ReactNode;
6
+ };
7
+ export declare const ChartTooltip: ({ x, y, children }: Props) => import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const ChartTooltip = ({ x, y, children }) => {
3
+ return (_jsx("foreignObject", { x: x, y: y, width: 120, height: 64, style: { borderRadius: "var(--radius-sm)", overflow: "visible" }, children: _jsx("div", { style: {
4
+ background: "var(--color-surface)",
5
+ backdropFilter: "var(--blur)",
6
+ border: "1px solid var(--color-border)",
7
+ borderRadius: "var(--radius-sm)",
8
+ padding: "var(--space-md)",
9
+ fontSize: "var(--font-size-14)",
10
+ color: "var(--color-on-surface)",
11
+ }, children: children }) }));
12
+ };
@@ -0,0 +1,5 @@
1
+ type Props = {
2
+ labels: string[];
3
+ };
4
+ export declare const ChartXAxis: ({ labels }: Props) => import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useChart } from "./ChartContext";
3
+ export const ChartXAxis = ({ labels }) => {
4
+ const { width, height, padding } = useChart();
5
+ // 描画可能領域の計算
6
+ const innerWidth = width - padding * 2;
7
+ // 1ラベルあたりの幅
8
+ const step = innerWidth / (labels.length > 1 ? labels.length - 1 : 1);
9
+ return (_jsx("g", { fill: "var(--color-on-surface)", children: labels.map((label, i) => {
10
+ const x = padding + (innerWidth / labels.length) * (i + 0.5);
11
+ const y = height - padding + 20;
12
+ return (_jsx("text", { x: x, y: y, textAnchor: "middle" // 水平方向の中央揃え
13
+ , dominantBaseline: "hanging" // テキストの上端をy座標に合わせる(より制御しやすくなります)
14
+ , fontSize: "var(--font-size-14)", children: label }, i));
15
+ }) }));
16
+ };
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ ticks: number[];
3
+ max: number;
4
+ };
5
+ export declare const ChartYAxis: ({ ticks, max }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChart } from "./ChartContext";
3
+ export const ChartYAxis = ({ ticks, max }) => {
4
+ const { width, height, padding } = useChart();
5
+ const innerHeight = height - padding * 2;
6
+ return (_jsx("g", { fill: "var(--color-on-surface)", children: ticks.map((tick, i) => {
7
+ const ratio = tick / max;
8
+ const y = height - padding - ratio * innerHeight;
9
+ return (_jsxs("g", { children: [_jsx("text", { x: padding - 8, y: y, textAnchor: "end", dominantBaseline: "middle", fontSize: "var(--font-size-14)", children: tick }), _jsx("line", { x1: padding, x2: width - padding, y1: y, y2: y, stroke: "var(--chart-grid)", strokeDasharray: "2" })] }, i));
10
+ }) }));
11
+ };
@@ -0,0 +1,2 @@
1
+ import { LineChartProps } from "./types";
2
+ export declare const LineChart: ({ data, keys, height }: LineChartProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChartContainer } from "../ChartContainer";
4
+ import { ChartGrid } from "../ChartGrid";
5
+ import { ChartAxis } from "../ChartAxis";
6
+ import { ChartXAxis } from "../ChartXAxis";
7
+ import { ChartYAxis } from "../ChartYAxis";
8
+ import { ChartTooltip } from "../ChartTooltip";
9
+ import { LineSeries } from "./LineSeries";
10
+ import { getMaxValue } from "../BarChart/utils";
11
+ import { getNiceTicks } from "../utils/getNiceTicks";
12
+ export const LineChart = ({ data, keys, height = 300 }) => {
13
+ const seriesKeys = keys !== null && keys !== void 0 ? keys : Object.keys(data[0]).filter((k) => k !== "label");
14
+ const max = getMaxValue(data, seriesKeys);
15
+ const ticks = getNiceTicks(max);
16
+ const labels = data.map((d) => d.label);
17
+ const [cursor, setCursor] = useState({
18
+ x: 0,
19
+ y: 0,
20
+ });
21
+ const [tooltip, setTooltip] = useState(null);
22
+ return (_jsx("div", { style: { width: "100%" }, children: _jsxs(ChartContainer, { height: height, onPointerMove: (x, y) => setCursor({ x, y }), children: [_jsx(ChartGrid, {}), _jsx(ChartAxis, {}), _jsx(ChartYAxis, { ticks: ticks, max: ticks[ticks.length - 1] }), _jsx(ChartXAxis, { labels: labels }), _jsx(LineSeries, { data: data, keys: seriesKeys, max: ticks[ticks.length - 1], onHover: (label, key, value) => setTooltip({
23
+ label,
24
+ key,
25
+ value,
26
+ }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: cursor.x + 12, y: cursor.y + 12, children: [_jsx("div", { children: tooltip.label }), _jsxs("strong", { children: [tooltip.key, ": ", tooltip.value] })] }))] }) }));
27
+ };
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ points: {
3
+ x: number;
4
+ y: number;
5
+ }[];
6
+ color: string;
7
+ };
8
+ export declare const LinePath: ({ points, color }: Props) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const LinePath = ({ points, color }) => {
3
+ const d = points
4
+ .map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`)
5
+ .join(" ");
6
+ return _jsx("path", { d: d, fill: "none", stroke: color, strokeWidth: 3 });
7
+ };
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ cx: number;
3
+ cy: number;
4
+ color: string;
5
+ onMouseEnter?: () => void;
6
+ onMouseLeave?: () => void;
7
+ };
8
+ export declare const LinePoint: ({ cx, cy, color, onMouseEnter, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const LinePoint = ({ cx, cy, color, onMouseEnter, onMouseLeave, }) => {
3
+ return (_jsx("circle", { cx: cx, cy: cy, r: 5, fill: color, stroke: "var(--color-surface)", strokeWidth: 2, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }));
4
+ };
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ data: any[];
3
+ keys: string[];
4
+ max: number;
5
+ onHover?: (label: string, key: string, value: number) => void;
6
+ onLeave?: () => void;
7
+ };
8
+ export declare const LineSeries: ({ data, keys, max, onHover, onLeave }: Props) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChart } from "../ChartContext";
3
+ import { scaleValue } from "../BarChart/utils";
4
+ import { LinePath } from "./LinePath";
5
+ import { LinePoint } from "./LinePoint";
6
+ export const LineSeries = ({ data, keys, max, onHover, onLeave }) => {
7
+ const { width, height, padding } = useChart();
8
+ const innerWidth = width - padding * 2;
9
+ const innerHeight = height - padding * 2;
10
+ // XAxisと同じ中央配置ロジック
11
+ const groupWidth = innerWidth / data.length;
12
+ return (_jsx("g", { children: keys.map((key, kIndex) => {
13
+ const points = data.map((d, i) => {
14
+ var _a;
15
+ const value = Number((_a = d[key]) !== null && _a !== void 0 ? _a : 0);
16
+ const x = padding + groupWidth * (i + 0.5);
17
+ const y = height -
18
+ padding -
19
+ scaleValue(value, max, innerHeight);
20
+ return { x, y, value, label: d.label };
21
+ });
22
+ return (_jsxs("g", { children: [_jsx(LinePath, { points: points, color: `var(--color-primary)` }), points.map((p, i) => (_jsx(LinePoint, { cx: p.x, cy: p.y, color: `var(--color-primary)`, onMouseEnter: () => onHover === null || onHover === void 0 ? void 0 : onHover(p.label, key, p.value), onMouseLeave: onLeave }, i)))] }, key));
23
+ }) }));
24
+ };
@@ -0,0 +1,9 @@
1
+ export type LineChartDatum = {
2
+ label: string;
3
+ [key: string]: string | number;
4
+ };
5
+ export type LineChartProps = {
6
+ data: LineChartDatum[];
7
+ keys?: string[];
8
+ height?: number;
9
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { PieChartProps } from "./types";
2
+ export declare const PieChart: ({ data, width, height, radius, innerRadius, }: PieChartProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChartContainer } from "../ChartContainer";
4
+ import { ChartTooltip } from "../ChartTooltip";
5
+ import { PieSeries } from "./PieSeries";
6
+ export const PieChart = ({ data, width = 300, height = 300, radius, innerRadius = 0, }) => {
7
+ const [tooltip, setTooltip] = useState(null);
8
+ return (_jsxs(ChartContainer, { width: width, height: height, children: [_jsx(PieSeries, { data: data, radius: radius, innerRadius: innerRadius, onHover: (label, value, x, y) => setTooltip({ label, value, x, y }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: tooltip.x + 10, y: tooltip.y - 10, children: [_jsx("div", { children: tooltip.label }), _jsx("div", { style: { fontWeight: "var(--font-weight-bold)" }, children: tooltip.value })] }))] }));
9
+ };
@@ -0,0 +1,2 @@
1
+ import { PieSeriesProps } from "./types";
2
+ export declare const PieSeries: ({ data, radius, innerRadius, onHover, onLeave, }: PieSeriesProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useChart } from "../ChartContext";
4
+ import { PieSlice } from "./PieSlice";
5
+ import { describeArc } from "./utils";
6
+ export const PieSeries = ({ data, radius, innerRadius = 0, onHover, onLeave, }) => {
7
+ const { width, height } = useChart();
8
+ const [hoverIndex, setHoverIndex] = useState(null);
9
+ const cx = width / 2;
10
+ const cy = height / 2;
11
+ const r = radius !== null && radius !== void 0 ? radius : Math.min(width, height) / 2;
12
+ const total = data.reduce((sum, d) => sum + d.value, 0);
13
+ let startAngle = 0;
14
+ const getSVGPoint = (e) => {
15
+ var _a;
16
+ const svg = e.currentTarget.ownerSVGElement;
17
+ if (!svg)
18
+ return { x: 0, y: 0 };
19
+ const pt = svg.createSVGPoint();
20
+ pt.x = e.clientX;
21
+ pt.y = e.clientY;
22
+ const cursorpt = pt.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
23
+ return { x: cursorpt.x, y: cursorpt.y };
24
+ };
25
+ return (_jsx("g", { children: data.map((d, i) => {
26
+ const angle = (d.value / total) * 360;
27
+ const endAngle = startAngle + angle;
28
+ const path = describeArc(cx, cy, r, startAngle, endAngle, innerRadius);
29
+ startAngle = endAngle;
30
+ const scale = hoverIndex === i ? 1.04 : 1;
31
+ return (_jsx(PieSlice, { d: path, color: `var(--chart-color-${i + 1})`, cx: cx, cy: cy, scale: scale, onMouseMove: (e) => {
32
+ setHoverIndex(i);
33
+ const { x, y } = getSVGPoint(e);
34
+ onHover === null || onHover === void 0 ? void 0 : onHover(d.label, d.value, x, y);
35
+ }, onMouseLeave: () => {
36
+ setHoverIndex(null);
37
+ onLeave === null || onLeave === void 0 ? void 0 : onLeave();
38
+ } }, i));
39
+ }) }));
40
+ };
@@ -0,0 +1,12 @@
1
+ import { MouseEvent } from "react";
2
+ type Props = {
3
+ d: string;
4
+ color: string;
5
+ cx: number;
6
+ cy: number;
7
+ scale?: number;
8
+ onMouseMove?: (e: MouseEvent<SVGPathElement>) => void;
9
+ onMouseLeave?: () => void;
10
+ };
11
+ export declare const PieSlice: ({ d, color, cx, cy, scale, onMouseMove, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const PieSlice = ({ d, color, cx, cy, scale = 1, onMouseMove, onMouseLeave, }) => {
3
+ return (_jsx("path", { d: d, fill: color, transform: `scale(${scale})`, style: {
4
+ cursor: "default",
5
+ transformOrigin: `${cx}px ${cy}px`,
6
+ transition: "transform 120ms ease",
7
+ }, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave }));
8
+ };
@@ -0,0 +1,18 @@
1
+ export type PieDatum = {
2
+ label: string;
3
+ value: number;
4
+ };
5
+ export type PieChartProps = {
6
+ data: PieDatum[];
7
+ width?: number;
8
+ height?: number;
9
+ radius?: number;
10
+ innerRadius?: number;
11
+ };
12
+ export type PieSeriesProps = {
13
+ data: PieDatum[];
14
+ radius?: number;
15
+ innerRadius?: number;
16
+ onHover?: (label: string, value: number, x: number, y: number) => void;
17
+ onLeave?: () => void;
18
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare const polarToCartesian: (cx: number, cy: number, r: number, angle: number) => {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export declare const describeArc: (cx: number, cy: number, r: number, startAngle: number, endAngle: number, innerRadius?: number) => string;
@@ -0,0 +1,27 @@
1
+ export const polarToCartesian = (cx, cy, r, angle) => {
2
+ const rad = (angle - 90) * (Math.PI / 180);
3
+ return {
4
+ x: cx + r * Math.cos(rad),
5
+ y: cy + r * Math.sin(rad),
6
+ };
7
+ };
8
+ export const describeArc = (cx, cy, r, startAngle, endAngle, innerRadius = 0) => {
9
+ const outerStart = polarToCartesian(cx, cy, r, endAngle);
10
+ const outerEnd = polarToCartesian(cx, cy, r, startAngle);
11
+ const largeArcFlag = endAngle - startAngle > 180 ? 1 : 0;
12
+ if (innerRadius === 0) {
13
+ return ` M ${outerStart.x} ${outerStart.y}
14
+ A ${r} ${r} 0 ${largeArcFlag} 0 ${outerEnd.x} ${outerEnd.y}
15
+ L ${cx} ${cy}
16
+ Z
17
+ `;
18
+ }
19
+ const innerStart = polarToCartesian(cx, cy, innerRadius, endAngle);
20
+ const innerEnd = polarToCartesian(cx, cy, innerRadius, startAngle);
21
+ return ` M ${outerStart.x} ${outerStart.y}
22
+ A ${r} ${r} 0 ${largeArcFlag} 0 ${outerEnd.x} ${outerEnd.y}
23
+ L ${innerEnd.x} ${innerEnd.y}
24
+ A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 1 ${innerStart.x} ${innerStart.y}
25
+ Z
26
+ `;
27
+ };
@@ -0,0 +1,4 @@
1
+ import { RadarDatum } from "./types";
2
+ export declare const RadarAxis: ({ data, }: {
3
+ data: RadarDatum[];
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChart } from "../ChartContext";
3
+ import { polarToCartesian } from "./utils";
4
+ export const RadarAxis = ({ data, }) => {
5
+ const { width, height } = useChart();
6
+ const cx = width / 2;
7
+ const cy = height / 2;
8
+ const radius = Math.min(width, height) / 2 - 24;
9
+ const step = (Math.PI * 2) / data.length;
10
+ return (_jsx("g", { fontSize: 14, textAnchor: "middle", fill: "var(--color-on-surface)", children: data.map((d, i) => {
11
+ const angle = i * step - Math.PI / 2;
12
+ const lineEnd = polarToCartesian(cx, cy, radius, angle);
13
+ const labelPos = polarToCartesian(cx, cy, radius + 16, angle);
14
+ return (_jsxs("g", { children: [_jsx("line", { x1: cx, y1: cy, x2: lineEnd.x, y2: lineEnd.y, stroke: "var(--chart-grid)" }), _jsx("text", { x: labelPos.x, y: labelPos.y, children: d.label })] }, i));
15
+ }) }));
16
+ };
@@ -0,0 +1,2 @@
1
+ import { RadarChartProps } from "./types";
2
+ export declare const RadarChart: ({ data, width, height, levels, }: RadarChartProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChartContainer } from "../ChartContainer";
4
+ import { ChartTooltip } from "../ChartTooltip";
5
+ import { RadarGrid } from "./RadarGrid";
6
+ import { RadarAxis } from "./RadarAxis";
7
+ import { RadarSeries } from "./RadarSeries";
8
+ export const RadarChart = ({ data, width = 320, height = 320, levels = 5, }) => {
9
+ const [tooltip, setTooltip] = useState(null);
10
+ return (_jsxs(ChartContainer, { width: width, height: height, children: [" ", _jsx(RadarGrid, { data: data, levels: levels }), _jsx(RadarAxis, { data: data }), _jsx(RadarSeries, { data: data, onHover: (label, value, x, y) => setTooltip({ label, value, x, y }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: tooltip.x + 10, y: tooltip.y - 10, children: [_jsx("div", { children: tooltip.label }), _jsx("div", { children: tooltip.value })] }))] }));
11
+ };
@@ -0,0 +1,5 @@
1
+ import { RadarDatum } from "./types";
2
+ export declare const RadarGrid: ({ data, levels, }: {
3
+ data: RadarDatum[];
4
+ levels?: number;
5
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useChart } from "../ChartContext";
3
+ import { polarToCartesian } from "./utils";
4
+ export const RadarGrid = ({ data, levels = 5, }) => {
5
+ const { width, height } = useChart();
6
+ const axes = data.length;
7
+ const cx = width / 2;
8
+ const cy = height / 2;
9
+ const radius = Math.min(width, height) / 2 - 24;
10
+ const step = (Math.PI * 2) / axes;
11
+ return (_jsx("g", { stroke: "var(--chart-grid)", fill: "none", children: [...Array(levels)].map((_, level) => {
12
+ const r = (radius / levels) * (level + 1);
13
+ const points = [...Array(axes)].map((_, i) => {
14
+ const angle = i * step - Math.PI / 2;
15
+ const p = polarToCartesian(cx, cy, r, angle);
16
+ return `${p.x},${p.y}`;
17
+ });
18
+ return (_jsx("polygon", { points: points.join(" ") }, level));
19
+ }) }));
20
+ };
@@ -0,0 +1,2 @@
1
+ import { RadarSeriesProps } from "./types";
2
+ export declare const RadarSeries: ({ data, onHover, onLeave, }: RadarSeriesProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChart } from "../ChartContext";
3
+ import { createRadarPath, polarToCartesian, } from "./utils";
4
+ export const RadarSeries = ({ data, onHover, onLeave, }) => {
5
+ const { width, height } = useChart();
6
+ const cx = width / 2;
7
+ const cy = height / 2;
8
+ const radius = Math.min(width, height) / 2 - 24;
9
+ const values = data.map((d) => d.value);
10
+ const max = Math.max(...values);
11
+ const path = createRadarPath(cx, cy, radius, values, max);
12
+ const step = (Math.PI * 2) / data.length;
13
+ const getSVGPoint = (e) => {
14
+ var _a;
15
+ const svg = e.currentTarget.ownerSVGElement;
16
+ if (!svg)
17
+ return { x: 0, y: 0 };
18
+ const pt = svg.createSVGPoint();
19
+ pt.x = e.clientX;
20
+ pt.y = e.clientY;
21
+ const cursorpt = pt.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
22
+ return { x: cursorpt.x, y: cursorpt.y };
23
+ };
24
+ return (_jsxs("g", { children: [" ", _jsx("path", { d: path, fill: "var(--chart-color-1)", fillOpacity: 0.25, stroke: "var(--chart-color-1)", strokeWidth: 2 }), data.map((d, i) => {
25
+ const r = (d.value / max) * radius;
26
+ const angle = i * step - Math.PI / 2;
27
+ const p = polarToCartesian(cx, cy, r, angle);
28
+ return (_jsx("circle", { cx: p.x, cy: p.y, r: 12, fillOpacity: 0, style: { cursor: "default" }, onMouseMove: (e) => {
29
+ const { x, y } = getSVGPoint(e);
30
+ onHover === null || onHover === void 0 ? void 0 : onHover(d.label, d.value, x, y);
31
+ }, onMouseLeave: onLeave }, i));
32
+ })] }));
33
+ };
@@ -0,0 +1,22 @@
1
+ export type RadarDatum = {
2
+ label: string;
3
+ value: number;
4
+ };
5
+ export type RadarChartProps = {
6
+ data: RadarDatum[];
7
+ width?: number;
8
+ height?: number;
9
+ levels?: number;
10
+ };
11
+ export type RadarSeriesProps = {
12
+ data: RadarDatum[];
13
+ onHover?: (label: string, value: number, x: number, y: number) => void;
14
+ onLeave?: () => void;
15
+ };
16
+ export type RadarGridProps = {
17
+ data: RadarDatum[];
18
+ levels?: number;
19
+ };
20
+ export type RadarAxisProps = {
21
+ data: RadarDatum[];
22
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare const polarToCartesian: (cx: number, cy: number, r: number, angle: number) => {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export declare const createRadarPath: (cx: number, cy: number, radius: number, values: number[], max: number) => string;
@@ -0,0 +1,16 @@
1
+ export const polarToCartesian = (cx, cy, r, angle) => {
2
+ return {
3
+ x: cx + r * Math.cos(angle),
4
+ y: cy + r * Math.sin(angle),
5
+ };
6
+ };
7
+ export const createRadarPath = (cx, cy, radius, values, max) => {
8
+ const step = (Math.PI * 2) / values.length;
9
+ const points = values.map((v, i) => {
10
+ const r = (v / max) * radius;
11
+ const angle = i * step - Math.PI / 2;
12
+ const p = polarToCartesian(cx, cy, r, angle);
13
+ return `${p.x} ${p.y}`;
14
+ });
15
+ return `M ${points.join(" L ")} Z`;
16
+ };
@@ -0,0 +1,15 @@
1
+ export { ChartContainer } from "./ChartContainer";
2
+ export { ChartTooltip } from "./ChartTooltip";
3
+ export { ChartLegend } from "./ChartLegend";
4
+ export { ChartAxis } from "./ChartAxis";
5
+ export { ChartXAxis } from "./ChartXAxis";
6
+ export { ChartYAxis } from "./ChartYAxis";
7
+ export { ChartGrid } from "./ChartGrid";
8
+ export { BarChart } from "./BarChart/BarChart";
9
+ export type { BarChartProps } from "./BarChart/types";
10
+ export { LineChart } from "./LineChart/LineChart";
11
+ export type { LineChartProps } from "./LineChart/types";
12
+ export { PieChart } from "./PieChart/PieChart";
13
+ export type { PieChartProps, PieDatum } from "./PieChart/types";
14
+ export { RadarChart } from "./RadarChart/RadarChart";
15
+ export type { RadarChartProps, RadarDatum } from "./RadarChart/types";
@@ -0,0 +1,18 @@
1
+ // =========================
2
+ // Core
3
+ // =========================
4
+ export { ChartContainer } from "./ChartContainer";
5
+ export { ChartTooltip } from "./ChartTooltip";
6
+ export { ChartLegend } from "./ChartLegend";
7
+ // Axis / Grid
8
+ export { ChartAxis } from "./ChartAxis";
9
+ export { ChartXAxis } from "./ChartXAxis";
10
+ export { ChartYAxis } from "./ChartYAxis";
11
+ export { ChartGrid } from "./ChartGrid";
12
+ // =========================
13
+ // Charts
14
+ // =========================
15
+ export { BarChart } from "./BarChart/BarChart";
16
+ export { LineChart } from "./LineChart/LineChart";
17
+ export { PieChart } from "./PieChart/PieChart";
18
+ export { RadarChart } from "./RadarChart/RadarChart";
@@ -0,0 +1 @@
1
+ export declare const getNiceTicks: (max: number, tickCount?: number) => number[];
@@ -0,0 +1,20 @@
1
+ export const getNiceTicks = (max, tickCount = 5) => {
2
+ if (max === 0)
3
+ return [0];
4
+ const roughStep = max / (tickCount - 1);
5
+ const magnitude = Math.pow(10, Math.floor(Math.log10(roughStep)));
6
+ const residual = roughStep / magnitude;
7
+ let niceStep = magnitude;
8
+ if (residual > 5)
9
+ niceStep = 10 * magnitude;
10
+ else if (residual > 2)
11
+ niceStep = 5 * magnitude;
12
+ else if (residual > 1)
13
+ niceStep = 2 * magnitude;
14
+ const niceMax = Math.ceil(max / niceStep) * niceStep;
15
+ const ticks = [];
16
+ for (let v = 0; v <= niceMax; v += niceStep) {
17
+ ticks.push(v);
18
+ }
19
+ return ticks;
20
+ };
@@ -13,7 +13,7 @@
13
13
  background: var(--color-background);
14
14
  color: var(--color-on-surface);
15
15
  border-radius: var(--radius-md);
16
- box-shadow: var(--shadow-modal);
16
+ box-shadow: var(--shadow-overlay-lg);
17
17
  padding: var(--space-2xl);
18
18
  min-width: 320px;
19
19
  }
package/dist/index.d.ts CHANGED
@@ -12,3 +12,5 @@ export * from "./components/Typography";
12
12
  export * from "./components/Select";
13
13
  export * from "./components/Switch";
14
14
  export * from "./components/Feedback/Modal";
15
+ export * from "./components/Chart";
16
+ export * from "./components/Extra/Clock";
package/dist/index.js CHANGED
@@ -13,3 +13,7 @@ export * from "./components/Typography";
13
13
  export * from "./components/Select";
14
14
  export * from "./components/Switch";
15
15
  export * from "./components/Feedback/Modal";
16
+ /* ===== Chart ===== */
17
+ export * from "./components/Chart";
18
+ /* ===== Extra ===== */
19
+ export * from "./components/Extra/Clock";
@@ -13,6 +13,7 @@
13
13
 
14
14
  --line-tight: 1.2;
15
15
  --line-snug: 1.35;
16
+ --line-normal: 1.5;
16
17
  --line-comfort: 1.7;
17
18
 
18
19
  --font-weight-regular: 400;
@@ -63,8 +64,19 @@
63
64
  --color-surface-container: #e9efeebf;
64
65
 
65
66
  --color-border: #bbcccc;
66
- --color-scrim: rgba(129, 129, 129, 0.25);
67
67
 
68
+ --chart-color-1: #99cccc;
69
+ --chart-color-2: #66b2b2;
70
+ --chart-color-3: #4da6a6;
71
+ --chart-color-4: #339999;
72
+ --chart-color-5: #008b8b;
73
+ --chart-color-6: #007a7a;
74
+ --chart-color-7: #006666;
75
+ --chart-color-8: #005252;
76
+ --chart-color-9: #004545;
77
+ --chart-color-10: #003333;
78
+
79
+ --color-scrim: rgba(129, 129, 129, 0.25);
68
80
  --color-shadow-l: rgba(255, 255, 255, 1);
69
81
  --color-shadow-d: rgba(0, 0, 0, 0.2);
70
82
 
@@ -91,7 +103,8 @@
91
103
  -4px -4px 16px 8px var(--color-shadow-l),
92
104
  4px 4px 16px 8px var(--color-shadow-d);
93
105
 
94
- --shadow-modal: 0px 4px 16px 8px var(--color-shadow-d);
106
+ --shadow-overlay-md: 0px 2px 8px 2px var(--color-shadow-d);
107
+ --shadow-overlay-lg: 0px 4px 16px 8px var(--color-shadow-d);
95
108
  }
96
109
 
97
110
  html[data-theme="dark"] {
@@ -116,11 +129,22 @@ html[data-theme="dark"] {
116
129
  --color-surface: #1e2927bf;
117
130
  --color-on-surface: #c3cbca;
118
131
  --color-on-surface-variant: #dde4e380;
119
- --color-surface-container: #262d2d;
132
+ --color-surface-container: #262d2dbf;
120
133
 
121
134
  --color-border: #889392;
122
- --color-scrim: rgba(0, 0, 0, 0.25);
123
135
 
136
+ --chart-color-1: #80d5d4;
137
+ --chart-color-2: #6bc2c1;
138
+ --chart-color-3: #57afae;
139
+ --chart-color-4: #439d9c;
140
+ --chart-color-5: #308b8b;
141
+ --chart-color-6: #1c797a;
142
+ --chart-color-7: #09686a;
143
+ --chart-color-8: #005759;
144
+ --chart-color-9: #004749;
145
+ --chart-color-10: #00383a;
146
+
147
+ --color-scrim: rgba(0, 0, 0, 0.25);
124
148
  --color-shadow-l: rgba(255, 255, 255, 0.25);
125
149
  --color-shadow-d: rgba(0, 0, 0, 1);
126
150
  }
@@ -0,0 +1,5 @@
1
+ export type CalendarDay = {
2
+ date: Date;
3
+ isCurrentMonth: boolean;
4
+ };
5
+ export declare const generateCalendar: (baseDate: Date) => CalendarDay[];
@@ -0,0 +1,36 @@
1
+ export const generateCalendar = (baseDate) => {
2
+ const year = baseDate.getFullYear();
3
+ const month = baseDate.getMonth();
4
+ // 月初
5
+ const firstDayOfMonth = new Date(year, month, 1);
6
+ // 月初の曜日(0=日)
7
+ const startDay = firstDayOfMonth.getDay();
8
+ // 今月の日数
9
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
10
+ // 先月の日数
11
+ const daysInPrevMonth = new Date(year, month, 0).getDate();
12
+ const days = [];
13
+ // ① 前月
14
+ for (let i = startDay - 1; i >= 0; i--) {
15
+ days.push({
16
+ date: new Date(year, month - 1, daysInPrevMonth - i),
17
+ isCurrentMonth: false,
18
+ });
19
+ }
20
+ // ② 当月
21
+ for (let i = 1; i <= daysInMonth; i++) {
22
+ days.push({
23
+ date: new Date(year, month, i),
24
+ isCurrentMonth: true,
25
+ });
26
+ }
27
+ // ③ 次月
28
+ const remaining = 42 - days.length;
29
+ for (let i = 1; i <= remaining; i++) {
30
+ days.push({
31
+ date: new Date(year, month + 1, i),
32
+ isCurrentMonth: false,
33
+ });
34
+ }
35
+ return days;
36
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucentia-ui",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "React UI design token and component system based on neumorphism, featuring two color themes: light and dark.",
5
5
  "homepage": "https://lucentia.rikiyamatsuda.com/en",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,8 @@
23
23
  "**/*.css"
24
24
  ],
25
25
  "peerDependencies": {
26
- "react": ">=18"
26
+ "react": ">=18",
27
+ "react-dom": ">=18"
27
28
  },
28
29
  "scripts": {
29
30
  "build": "tsc -p tsconfig.json && npm run copy:assets",
@@ -32,9 +33,10 @@
32
33
  },
33
34
  "license": "MIT",
34
35
  "dependencies": {
36
+ "@floating-ui/react": "^0.27.0",
35
37
  "clsx": "^2.1.1"
36
38
  },
37
39
  "devDependencies": {
38
40
  "cpy-cli": "^6.0.0"
39
41
  }
40
- }
42
+ }