From ac06db97b0b47fbbe88bb6e529e89bff114cc4ee Mon Sep 17 00:00:00 2001 From: plouc Date: Thu, 11 May 2023 19:04:27 +0900 Subject: [PATCH] feat(theming): move theming to its own package --- Makefile | 3 +- packages/annotations/package.json | 1 + packages/annotations/src/AnnotationLink.tsx | 3 +- packages/annotations/src/AnnotationNote.tsx | 3 +- .../src/CircleAnnotationOutline.tsx | 3 +- .../annotations/src/DotAnnotationOutline.tsx | 3 +- .../annotations/src/RectAnnotationOutline.tsx | 3 +- packages/annotations/src/canvas.ts | 4 +- packages/annotations/src/types.ts | 4 +- packages/arcs/package.json | 1 + packages/arcs/src/ArcsLayer.tsx | 2 +- packages/arcs/src/arc_labels/ArcLabel.tsx | 2 +- .../arcs/src/arc_labels/ArcLabelsLayer.tsx | 3 +- packages/arcs/src/arc_labels/canvas.ts | 4 +- packages/arcs/src/arc_labels/useArcLabels.ts | 3 +- .../arcs/src/arc_link_labels/ArcLinkLabel.tsx | 2 +- packages/arcs/src/arc_link_labels/canvas.ts | 10 +- .../src/arc_link_labels/useArcLinkLabels.ts | 3 +- .../useArcLinkLabelsTransition.ts | 3 +- packages/axes/package.json | 1 + packages/axes/src/canvas.ts | 7 +- packages/axes/src/components/Axis.tsx | 3 +- packages/axes/src/components/AxisTick.tsx | 2 +- packages/axes/src/components/GridLine.tsx | 2 +- packages/bar/package.json | 1 + packages/bar/src/BarCanvas.tsx | 10 +- packages/bar/src/BarItem.tsx | 2 +- packages/bar/src/hooks.ts | 3 +- packages/bar/src/types.ts | 4 +- packages/boxplot/package.json | 1 + packages/boxplot/src/BoxPlotTooltip.tsx | 6 +- packages/boxplot/src/hooks.ts | 3 +- packages/boxplot/src/types.ts | 4 +- packages/bullet/package.json | 1 + packages/bullet/src/BulletItem.tsx | 8 +- packages/bullet/src/BulletRects.tsx | 3 +- packages/bullet/src/types.ts | 5 +- packages/bump/package.json | 1 + packages/bump/src/area-bump/AreasLabels.tsx | 3 +- packages/bump/src/area-bump/hooks.ts | 2 +- packages/bump/src/area-bump/types.ts | 5 +- packages/bump/src/bump/LinesLabels.tsx | 3 +- packages/bump/src/bump/hooks.ts | 2 +- packages/bump/src/bump/types.ts | 5 +- packages/calendar/package.json | 1 + packages/calendar/src/Calendar.tsx | 3 +- packages/calendar/src/CalendarCanvas.tsx | 2 +- packages/calendar/src/TimeRange.tsx | 3 +- packages/calendar/src/types.ts | 10 +- packages/chord/package.json | 1 + packages/chord/src/ChordArcs.tsx | 3 +- packages/chord/src/ChordCanvas.tsx | 2 +- packages/chord/src/ChordLabels.tsx | 2 +- packages/chord/src/ChordRibbons.tsx | 2 +- packages/chord/src/types.ts | 4 +- packages/circle-packing/package.json | 1 + .../src/CirclePackingCanvas.tsx | 3 +- packages/circle-packing/src/Circles.tsx | 3 +- packages/circle-packing/src/LabelHtml.tsx | 2 +- packages/circle-packing/src/LabelSvg.tsx | 2 +- packages/circle-packing/src/hooks.ts | 9 +- packages/circle-packing/src/types.ts | 5 +- packages/colors/package.json | 2 +- packages/colors/src/inheritedColor.ts | 2 +- packages/core/package.json | 1 + packages/core/src/components/Container.js | 2 +- packages/funnel/package.json | 1 + packages/funnel/src/PartLabel.tsx | 3 +- packages/funnel/src/Separator.tsx | 3 +- packages/funnel/src/hooks.ts | 3 +- packages/funnel/src/types.ts | 5 +- packages/geo/index.d.ts | 5 +- packages/geo/package.json | 1 + packages/geo/src/Choropleth.js | 3 +- packages/geo/src/ChoroplethCanvas.js | 3 +- packages/geo/src/GeoMap.js | 3 +- packages/geo/src/GeoMapCanvas.js | 3 +- packages/geo/src/hooks.js | 3 +- packages/heatmap/package.json | 1 + packages/heatmap/src/HeatMapCanvas.tsx | 3 +- packages/heatmap/src/HeatMapCellCircle.tsx | 2 +- packages/heatmap/src/HeatMapCellRect.tsx | 2 +- packages/heatmap/src/hooks.ts | 3 +- packages/heatmap/src/types.ts | 7 +- packages/legends/package.json | 1 + packages/legends/src/canvas.ts | 5 +- .../src/svg/ContinuousColorsLegendSvg.tsx | 2 +- packages/legends/src/svg/LegendSvgItem.tsx | 2 +- packages/legends/src/types.ts | 5 +- packages/line/package.json | 1 + packages/theming/LICENSE.md | 19 ++ packages/theming/README.md | 6 + packages/theming/package.json | 30 +++ packages/theming/src/context.tsx | 30 +++ packages/theming/src/defaults.ts | 137 +++++++++++ packages/theming/src/extend.ts | 38 +++ packages/theming/src/hooks.ts | 8 + packages/theming/src/index.ts | 5 + packages/theming/src/types.ts | 219 ++++++++++++++++++ packages/theming/tsconfig.json | 9 + pnpm-lock.yaml | 76 +++++- tsconfig.monorepo.json | 1 + 102 files changed, 732 insertions(+), 128 deletions(-) create mode 100644 packages/theming/LICENSE.md create mode 100644 packages/theming/README.md create mode 100644 packages/theming/package.json create mode 100644 packages/theming/src/context.tsx create mode 100644 packages/theming/src/defaults.ts create mode 100644 packages/theming/src/extend.ts create mode 100644 packages/theming/src/hooks.ts create mode 100644 packages/theming/src/index.ts create mode 100644 packages/theming/src/types.ts create mode 100644 packages/theming/tsconfig.json diff --git a/Makefile b/Makefile index dc3b63752..2fb555402 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,8 @@ pkgs-test-cover: ##@1 packages run tests for all packages with code coverage pkgs-build: pkgs-types ##@1 packages build all packages @# Using exit code 255 in case of error as it'll make xargs stop immediately. - @export SKIP_TYPES=TRUE;find ./packages -type d -maxdepth 1 ! -path ./packages \ + @# Skipping type generation as it's already done via `pkgs-types` in one go. + @export SKIP_TYPES=TRUE; find ./packages -type d -maxdepth 1 ! -path ./packages \ | sed 's|^./packages/||' \ | xargs -P 8 -I '{}' sh -c '$(MAKE) pkg-build-{} || exit 255' diff --git a/packages/annotations/package.json b/packages/annotations/package.json index a479a9640..a23f86aba 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -30,6 +30,7 @@ "dependencies": { "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/prop-types": "^15.7.2", "lodash": "^4.17.21", diff --git a/packages/annotations/src/AnnotationLink.tsx b/packages/annotations/src/AnnotationLink.tsx index 75601e043..0fa0049f2 100644 --- a/packages/annotations/src/AnnotationLink.tsx +++ b/packages/annotations/src/AnnotationLink.tsx @@ -1,6 +1,7 @@ import { useMemo } from 'react' import { animated } from '@react-spring/web' -import { useAnimatedPath, useTheme } from '@nivo/core' +import { useAnimatedPath } from '@nivo/core' +import { useTheme } from '@nivo/theming' export const AnnotationLink = ({ points, diff --git a/packages/annotations/src/AnnotationNote.tsx b/packages/annotations/src/AnnotationNote.tsx index 07cb942df..e3562f106 100644 --- a/packages/annotations/src/AnnotationNote.tsx +++ b/packages/annotations/src/AnnotationNote.tsx @@ -1,7 +1,8 @@ import { createElement } from 'react' import omit from 'lodash/omit' import { useSpring, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { NoteSvg } from './types' export const AnnotationNote = ({ diff --git a/packages/annotations/src/CircleAnnotationOutline.tsx b/packages/annotations/src/CircleAnnotationOutline.tsx index e045375bf..68dab40f7 100644 --- a/packages/annotations/src/CircleAnnotationOutline.tsx +++ b/packages/annotations/src/CircleAnnotationOutline.tsx @@ -1,5 +1,6 @@ import { useSpring, animated } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' export const CircleAnnotationOutline = ({ x, y, size }: { x: number; y: number; size: number }) => { const theme = useTheme() diff --git a/packages/annotations/src/DotAnnotationOutline.tsx b/packages/annotations/src/DotAnnotationOutline.tsx index 9abfe8520..91223cb1e 100644 --- a/packages/annotations/src/DotAnnotationOutline.tsx +++ b/packages/annotations/src/DotAnnotationOutline.tsx @@ -1,5 +1,6 @@ import { useSpring, animated } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { defaultProps } from './props' export const DotAnnotationOutline = ({ diff --git a/packages/annotations/src/RectAnnotationOutline.tsx b/packages/annotations/src/RectAnnotationOutline.tsx index 0f742ec8d..9bbd3ec2f 100644 --- a/packages/annotations/src/RectAnnotationOutline.tsx +++ b/packages/annotations/src/RectAnnotationOutline.tsx @@ -1,5 +1,6 @@ import { useSpring, animated } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' export const RectAnnotationOutline = ({ x, diff --git a/packages/annotations/src/canvas.ts b/packages/annotations/src/canvas.ts index 96c0d2345..9df0f5fab 100644 --- a/packages/annotations/src/canvas.ts +++ b/packages/annotations/src/canvas.ts @@ -1,4 +1,4 @@ -import { CompleteTheme } from '@nivo/core' +import { Theme } from '@nivo/theming' import { ComputedAnnotation } from './types' import { isCanvasNote, isCircleAnnotation, isDotAnnotation, isRectAnnotation } from './utils' @@ -19,7 +19,7 @@ export const renderAnnotationsToCanvas = ( theme, }: { annotations: ComputedAnnotation[] - theme: CompleteTheme + theme: Theme } ) => { if (annotations.length === 0) return diff --git a/packages/annotations/src/types.ts b/packages/annotations/src/types.ts index 07fbc2ff4..21f3a302c 100644 --- a/packages/annotations/src/types.ts +++ b/packages/annotations/src/types.ts @@ -1,4 +1,4 @@ -import { CompleteTheme } from '@nivo/core' +import { Theme } from '@nivo/theming' import { ReactElement } from 'react' // The types below are from lodash but the babel plugin won't let us import it @@ -38,7 +38,7 @@ export type NoteCanvasRenderer = ( datum: Datum x: number y: number - theme: CompleteTheme + theme: Theme } ) => void diff --git a/packages/arcs/package.json b/packages/arcs/package.json index 9b53b7f4f..acb3b5015 100644 --- a/packages/arcs/package.json +++ b/packages/arcs/package.json @@ -30,6 +30,7 @@ "dependencies": { "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-shape": "^2.0.0", "d3-shape": "^1.3.5" diff --git a/packages/arcs/src/ArcsLayer.tsx b/packages/arcs/src/ArcsLayer.tsx index 483030d1a..29a4795bf 100644 --- a/packages/arcs/src/ArcsLayer.tsx +++ b/packages/arcs/src/ArcsLayer.tsx @@ -1,5 +1,5 @@ import { createElement } from 'react' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig, useInheritedColor } from '@nivo/colors' import { DatumWithArcAndColor, ArcGenerator } from './types' import { useArcsTransition } from './useArcsTransition' diff --git a/packages/arcs/src/arc_labels/ArcLabel.tsx b/packages/arcs/src/arc_labels/ArcLabel.tsx index 5ce3e8ae1..2261f8b03 100644 --- a/packages/arcs/src/arc_labels/ArcLabel.tsx +++ b/packages/arcs/src/arc_labels/ArcLabel.tsx @@ -1,6 +1,6 @@ import { CSSProperties } from 'react' import { SpringValue, Interpolation, animated } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { DatumWithArcAndColor } from '../types' const staticStyle: CSSProperties = { diff --git a/packages/arcs/src/arc_labels/ArcLabelsLayer.tsx b/packages/arcs/src/arc_labels/ArcLabelsLayer.tsx index 66b46970d..6457a734e 100644 --- a/packages/arcs/src/arc_labels/ArcLabelsLayer.tsx +++ b/packages/arcs/src/arc_labels/ArcLabelsLayer.tsx @@ -1,5 +1,6 @@ import { createElement, useMemo } from 'react' -import { PropertyAccessor, usePropertyAccessor, radiansToDegrees, useTheme } from '@nivo/core' +import { PropertyAccessor, usePropertyAccessor, radiansToDegrees } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor } from '@nivo/colors' import { useArcCentersTransition } from '../centers' import { ArcTransitionMode } from '../arcTransitionMode' diff --git a/packages/arcs/src/arc_labels/canvas.ts b/packages/arcs/src/arc_labels/canvas.ts index 7551e1d76..7671abe38 100644 --- a/packages/arcs/src/arc_labels/canvas.ts +++ b/packages/arcs/src/arc_labels/canvas.ts @@ -1,11 +1,11 @@ -import { CompleteTheme } from '@nivo/core' +import { Theme } from '@nivo/theming' import { DatumWithArcAndColor } from '../types' import { ArcLabel } from './useArcLabels' export const drawCanvasArcLabels = ( ctx: CanvasRenderingContext2D, labels: ArcLabel[], - theme: CompleteTheme + theme: Theme ) => { ctx.textAlign = 'center' ctx.textBaseline = 'middle' diff --git a/packages/arcs/src/arc_labels/useArcLabels.ts b/packages/arcs/src/arc_labels/useArcLabels.ts index c0bb23468..19dedf4ff 100644 --- a/packages/arcs/src/arc_labels/useArcLabels.ts +++ b/packages/arcs/src/arc_labels/useArcLabels.ts @@ -1,5 +1,6 @@ import { useCallback } from 'react' -import { PropertyAccessor, usePropertyAccessor, useTheme } from '@nivo/core' +import { PropertyAccessor, usePropertyAccessor } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig, useInheritedColor } from '@nivo/colors' import { DatumWithArcAndColor } from '../types' import { useArcCenters, ArcCenter } from '../centers' diff --git a/packages/arcs/src/arc_link_labels/ArcLinkLabel.tsx b/packages/arcs/src/arc_link_labels/ArcLinkLabel.tsx index c69aa7b68..0bdc630aa 100644 --- a/packages/arcs/src/arc_link_labels/ArcLinkLabel.tsx +++ b/packages/arcs/src/arc_link_labels/ArcLinkLabel.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { SpringValue, Interpolation, animated } from '@react-spring/web' import { DatumWithArcAndColor } from '../types' diff --git a/packages/arcs/src/arc_link_labels/canvas.ts b/packages/arcs/src/arc_link_labels/canvas.ts index 5319b2ed1..9ffeea8db 100644 --- a/packages/arcs/src/arc_link_labels/canvas.ts +++ b/packages/arcs/src/arc_link_labels/canvas.ts @@ -1,15 +1,13 @@ -import { - // @ts-ignore - textPropsByEngine, - CompleteTheme, -} from '@nivo/core' +// @ts-ignore +import { textPropsByEngine } from '@nivo/core' +import { Theme } from '@nivo/theming' import { DatumWithArcAndColor } from '../types' import { ArcLinkLabel } from './types' export const drawCanvasArcLinkLabels = ( ctx: CanvasRenderingContext2D, labels: ArcLinkLabel[], - theme: CompleteTheme, + theme: Theme, strokeWidth: number ) => { ctx.textBaseline = 'middle' diff --git a/packages/arcs/src/arc_link_labels/useArcLinkLabels.ts b/packages/arcs/src/arc_link_labels/useArcLinkLabels.ts index 0b6872a1c..19f48cdd0 100644 --- a/packages/arcs/src/arc_link_labels/useArcLinkLabels.ts +++ b/packages/arcs/src/arc_link_labels/useArcLinkLabels.ts @@ -1,5 +1,6 @@ import { useCallback } from 'react' -import { PropertyAccessor, usePropertyAccessor, useTheme } from '@nivo/core' +import { PropertyAccessor, usePropertyAccessor } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig, useInheritedColor } from '@nivo/colors' import { DatumWithArcAndColor } from '../types' import { ArcLinkWithDatum, ArcLinkLabel } from './types' diff --git a/packages/arcs/src/arc_link_labels/useArcLinkLabelsTransition.ts b/packages/arcs/src/arc_link_labels/useArcLinkLabelsTransition.ts index b652e2074..a6aa20e36 100644 --- a/packages/arcs/src/arc_link_labels/useArcLinkLabelsTransition.ts +++ b/packages/arcs/src/arc_link_labels/useArcLinkLabelsTransition.ts @@ -1,7 +1,8 @@ import { useMemo } from 'react' import { SpringValue, useTransition, to } from '@react-spring/web' import { line } from 'd3-shape' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig, useInheritedColor } from '@nivo/colors' import { DatumWithArcAndColor, Point } from '../types' import { useFilteredDataBySkipAngle } from '../utils' diff --git a/packages/axes/package.json b/packages/axes/package.json index 8a9b82217..e028b9653 100644 --- a/packages/axes/package.json +++ b/packages/axes/package.json @@ -29,6 +29,7 @@ "dependencies": { "@nivo/core": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-format": "^1.4.1", "@types/d3-time-format": "^2.3.1", diff --git a/packages/axes/src/canvas.ts b/packages/axes/src/canvas.ts index 8834e3000..841dce156 100644 --- a/packages/axes/src/canvas.ts +++ b/packages/axes/src/canvas.ts @@ -1,4 +1,5 @@ -import { degreesToRadians, CompleteTheme } from '@nivo/core' +import { degreesToRadians } from '@nivo/core' +import { Theme } from '@nivo/theming' import { ScaleValue, AnyScale, TicksSpec } from '@nivo/scales' import { computeCartesianTicks, getFormatter, computeGridLines } from './compute' import { positions } from './props' @@ -40,7 +41,7 @@ export const renderAxisToCanvas = ( legend?: string legendPosition?: AxisLegendPosition legendOffset?: number - theme: CompleteTheme + theme: Theme } ) => { const { ticks, textAlign, textBaseline } = computeCartesianTicks({ @@ -189,7 +190,7 @@ export const renderAxesToCanvas = ( right?: CanvasAxisProps | null bottom?: CanvasAxisProps | null left?: CanvasAxisProps | null - theme: CompleteTheme + theme: Theme } ) => { const axes = { top, right, bottom, left } diff --git a/packages/axes/src/components/Axis.tsx b/packages/axes/src/components/Axis.tsx index 6da3ea5bf..abc70c6f8 100644 --- a/packages/axes/src/components/Axis.tsx +++ b/packages/axes/src/components/Axis.tsx @@ -1,7 +1,8 @@ import { useMemo, memo, useCallback } from 'react' import * as React from 'react' import { useSpring, useTransition, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { ScaleValue, AnyScale } from '@nivo/scales' import { computeCartesianTicks, getFormatter } from '../compute' import { AxisTick } from './AxisTick' diff --git a/packages/axes/src/components/AxisTick.tsx b/packages/axes/src/components/AxisTick.tsx index bbd887d24..de3e46315 100644 --- a/packages/axes/src/components/AxisTick.tsx +++ b/packages/axes/src/components/AxisTick.tsx @@ -1,7 +1,7 @@ import { useMemo, memo } from 'react' import * as React from 'react' import { animated } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { ScaleValue } from '@nivo/scales' import { AxisTickProps } from '../types' diff --git a/packages/axes/src/components/GridLine.tsx b/packages/axes/src/components/GridLine.tsx index 191bbebe0..2f9b6822e 100644 --- a/packages/axes/src/components/GridLine.tsx +++ b/packages/axes/src/components/GridLine.tsx @@ -1,6 +1,6 @@ import { memo, SVGAttributes } from 'react' import { SpringValues, animated } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' export const GridLine = memo( ({ diff --git a/packages/bar/package.json b/packages/bar/package.json index fa5386036..39ae9d12c 100644 --- a/packages/bar/package.json +++ b/packages/bar/package.json @@ -35,6 +35,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-scale": "^3.2.3", diff --git a/packages/bar/src/BarCanvas.tsx b/packages/bar/src/BarCanvas.tsx index 7f69196a6..94d2f7ba6 100644 --- a/packages/bar/src/BarCanvas.tsx +++ b/packages/bar/src/BarCanvas.tsx @@ -5,14 +5,8 @@ import { BarDatum, ComputedBarDatum, } from './types' -import { - Container, - Margin, - getRelativeCursor, - isCursorInRect, - useDimensions, - useTheme, -} from '@nivo/core' +import { Container, Margin, getRelativeCursor, isCursorInRect, useDimensions } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { ForwardedRef, createElement, diff --git a/packages/bar/src/BarItem.tsx b/packages/bar/src/BarItem.tsx index 7ac2cf789..1a56c06cb 100644 --- a/packages/bar/src/BarItem.tsx +++ b/packages/bar/src/BarItem.tsx @@ -1,6 +1,6 @@ import { createElement, MouseEvent, useCallback, useMemo } from 'react' import { animated, to } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useTooltip } from '@nivo/tooltip' import { BarDatum, BarItemProps } from './types' diff --git a/packages/bar/src/hooks.ts b/packages/bar/src/hooks.ts index 880b5983b..fa2b38515 100644 --- a/packages/bar/src/hooks.ts +++ b/packages/bar/src/hooks.ts @@ -1,6 +1,7 @@ import { useCallback, useMemo, useState } from 'react' import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors' -import { usePropertyAccessor, useTheme, useValueFormatter, Margin } from '@nivo/core' +import { usePropertyAccessor, useValueFormatter, Margin } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { DataProps, BarCommonProps, diff --git a/packages/bar/src/types.ts b/packages/bar/src/types.ts index 8644bff6c..85a289efd 100644 --- a/packages/bar/src/types.ts +++ b/packages/bar/src/types.ts @@ -9,9 +9,9 @@ import { MotionProps, PropertyAccessor, SvgDefsAndFill, - Theme, ValueFormat, } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { LegendProps } from '@nivo/legends' import { AnyScale, ScaleSpec, ScaleBandSpec } from '@nivo/scales' @@ -251,7 +251,7 @@ export type BarCommonProps = { colorBy: 'id' | 'indexValue' colors: OrdinalColorScaleConfig> - theme: Theme + theme: PartialTheme annotations: AnnotationMatcher>[] legends: BarLegendProps[] diff --git a/packages/boxplot/package.json b/packages/boxplot/package.json index 3885d06be..9b873d603 100644 --- a/packages/boxplot/package.json +++ b/packages/boxplot/package.json @@ -40,6 +40,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-scale": "^3.2.3", diff --git a/packages/boxplot/src/BoxPlotTooltip.tsx b/packages/boxplot/src/BoxPlotTooltip.tsx index e294a2875..989677a9d 100644 --- a/packages/boxplot/src/BoxPlotTooltip.tsx +++ b/packages/boxplot/src/BoxPlotTooltip.tsx @@ -1,7 +1,7 @@ import { BoxPlotSummaryFormatted, BoxPlotTooltipProps, BoxPlotSummary } from './types' import { Chip } from '@nivo/tooltip' import { memo } from 'react' -import { useTheme, CompleteTheme } from '@nivo/core' +import { useTheme, Theme } from '@nivo/theming' interface BoxPlotSummaryTooltipProps { label: string @@ -23,11 +23,11 @@ export const defaultTranslation = { Quantiles: 'Quantiles', } -type ExtendedTheme = CompleteTheme & { +type ExtendedTheme = Theme & { translation: Translation } -const hasTranslation = (theme: CompleteTheme | ExtendedTheme): theme is ExtendedTheme => { +const hasTranslation = (theme: Theme | ExtendedTheme): theme is ExtendedTheme => { return 'translation' in theme } diff --git a/packages/boxplot/src/hooks.ts b/packages/boxplot/src/hooks.ts index 5d93fe300..882fc3e60 100644 --- a/packages/boxplot/src/hooks.ts +++ b/packages/boxplot/src/hooks.ts @@ -1,7 +1,8 @@ import { useMemo, useState } from 'react' import { SpringConfig, useTransition } from '@react-spring/web' import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors' -import { PropertyAccessor, usePropertyAccessor, useTheme, useValueFormatter } from '@nivo/core' +import { PropertyAccessor, usePropertyAccessor, useValueFormatter } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { BoxPlotCommonProps, BoxPlotDatum, diff --git a/packages/boxplot/src/types.ts b/packages/boxplot/src/types.ts index 0961bf483..c876244c2 100644 --- a/packages/boxplot/src/types.ts +++ b/packages/boxplot/src/types.ts @@ -9,9 +9,9 @@ import { MotionProps, PropertyAccessor, SvgDefsAndFill, - Theme, ValueFormat, } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { LegendProps } from '@nivo/legends' import { @@ -231,7 +231,7 @@ export type BoxPlotCommonProps = { colorBy: 'group' | 'subGroup' colors: OrdinalColorScaleConfig - theme: Theme & { translation: BoxPlotDatum } + theme: PartialTheme & { translation: BoxPlotDatum } annotations: AnnotationMatcher[] legends: LegendProps[] diff --git a/packages/bullet/package.json b/packages/bullet/package.json index 5dbbe7105..085cce6ea 100644 --- a/packages/bullet/package.json +++ b/packages/bullet/package.json @@ -34,6 +34,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2" }, diff --git a/packages/bullet/src/BulletItem.tsx b/packages/bullet/src/BulletItem.tsx index c0a4abcc4..5e64eda4a 100644 --- a/packages/bullet/src/BulletItem.tsx +++ b/packages/bullet/src/BulletItem.tsx @@ -1,8 +1,12 @@ import { useMemo } from 'react' import { useSpring, animated } from '@react-spring/web' import { Axis } from '@nivo/axes' -// @ts-ignore -import { getColorScale, useMotionConfig, useTheme } from '@nivo/core' +import { + // @ts-ignore + getColorScale, + useMotionConfig, +} from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useTooltip } from '@nivo/tooltip' import { stackValues } from './compute' import { BulletMarkers } from './BulletMarkers' diff --git a/packages/bullet/src/BulletRects.tsx b/packages/bullet/src/BulletRects.tsx index 790501f31..8f90492dd 100644 --- a/packages/bullet/src/BulletRects.tsx +++ b/packages/bullet/src/BulletRects.tsx @@ -1,6 +1,7 @@ import { createElement, useMemo } from 'react' import { useTransition, animated, to } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { computeRects } from './compute' import { BulletRectsProps, BulletRectComputedRect, BulletRectAnimatedProps } from './types' import { useInheritedColor } from '@nivo/colors' diff --git a/packages/bullet/src/types.ts b/packages/bullet/src/types.ts index f3493298b..d3f2fea57 100644 --- a/packages/bullet/src/types.ts +++ b/packages/bullet/src/types.ts @@ -1,5 +1,6 @@ import * as React from 'react' -import { Box, Dimensions, Theme, Colors, MotionProps } from '@nivo/core' +import { Box, Dimensions, Colors, MotionProps } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig } from '@nivo/colors' import { ScaleLinear } from '@nivo/scales' import { SpringValues } from '@react-spring/web' @@ -75,7 +76,7 @@ export type CommonBulletProps = Dimensions & { axisPosition: 'before' | 'after' - theme: Theme + theme: PartialTheme isInteractive: boolean diff --git a/packages/bump/package.json b/packages/bump/package.json index 74500186a..c1f74e1a9 100644 --- a/packages/bump/package.json +++ b/packages/bump/package.json @@ -35,6 +35,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-scale": "^3.2.3", diff --git a/packages/bump/src/area-bump/AreasLabels.tsx b/packages/bump/src/area-bump/AreasLabels.tsx index dbc1041fa..9382e719e 100644 --- a/packages/bump/src/area-bump/AreasLabels.tsx +++ b/packages/bump/src/area-bump/AreasLabels.tsx @@ -1,5 +1,6 @@ import { useSprings, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig } from '@nivo/colors' import { AreaBumpComputedSerie, diff --git a/packages/bump/src/area-bump/hooks.ts b/packages/bump/src/area-bump/hooks.ts index 2cde76494..60a90182e 100644 --- a/packages/bump/src/area-bump/hooks.ts +++ b/packages/bump/src/area-bump/hooks.ts @@ -1,6 +1,6 @@ import { createElement, useMemo, useCallback, useState, MouseEvent } from 'react' import { area as d3Area, curveBasis, curveLinear } from 'd3-shape' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useOrdinalColorScale, useInheritedColor, InheritedColorConfig } from '@nivo/colors' import { useTooltip } from '@nivo/tooltip' import { computeSeries } from './compute' diff --git a/packages/bump/src/area-bump/types.ts b/packages/bump/src/area-bump/types.ts index 94e0413d6..b663a8c98 100644 --- a/packages/bump/src/area-bump/types.ts +++ b/packages/bump/src/area-bump/types.ts @@ -1,6 +1,7 @@ import { FunctionComponent, MouseEvent } from 'react' import { Area } from 'd3-shape' -import { Box, Theme, Dimensions, MotionProps, CssMixBlendMode, SvgDefsAndFill } from '@nivo/core' +import { Box, Dimensions, MotionProps, CssMixBlendMode, SvgDefsAndFill } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { AxisProps } from '@nivo/axes' import { ScalePoint } from '@nivo/scales' @@ -130,7 +131,7 @@ export type AreaBumpCommonProps< spacing: number xPadding: number - theme: Theme + theme: PartialTheme colors: OrdinalColorScaleConfig> blendMode: CssMixBlendMode fillOpacity: number diff --git a/packages/bump/src/bump/LinesLabels.tsx b/packages/bump/src/bump/LinesLabels.tsx index 7d0c68064..6c94450ab 100644 --- a/packages/bump/src/bump/LinesLabels.tsx +++ b/packages/bump/src/bump/LinesLabels.tsx @@ -1,5 +1,6 @@ import { useSprings, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig } from '@nivo/colors' import { BumpComputedSerie, BumpDatum, BumpLabel, BumpSerieExtraProps } from './types' import { useBumpSeriesLabels } from './hooks' diff --git a/packages/bump/src/bump/hooks.ts b/packages/bump/src/bump/hooks.ts index e89f29498..b1983d8a8 100644 --- a/packages/bump/src/bump/hooks.ts +++ b/packages/bump/src/bump/hooks.ts @@ -1,6 +1,6 @@ import { createElement, useMemo, useCallback, useState, MouseEvent } from 'react' import { line as d3Line, curveBasis, curveLinear } from 'd3-shape' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useOrdinalColorScale, useInheritedColor, InheritedColorConfig } from '@nivo/colors' import { useTooltip } from '@nivo/tooltip' import { diff --git a/packages/bump/src/bump/types.ts b/packages/bump/src/bump/types.ts index b9f86443a..5cad17bf9 100644 --- a/packages/bump/src/bump/types.ts +++ b/packages/bump/src/bump/types.ts @@ -1,6 +1,7 @@ import { FunctionComponent, MouseEvent } from 'react' import { Line as D3Line } from 'd3-shape' -import { Theme, Box, Dimensions, MotionProps } from '@nivo/core' +import { Box, Dimensions, MotionProps } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { OrdinalColorScaleConfig, InheritedColorConfig } from '@nivo/colors' import { AxisProps } from '@nivo/axes' import { ScalePoint } from '@nivo/scales' @@ -129,7 +130,7 @@ export type BumpCommonProps> lineWidth: number activeLineWidth: number diff --git a/packages/calendar/package.json b/packages/calendar/package.json index 9c28cf85b..a770c24ed 100644 --- a/packages/calendar/package.json +++ b/packages/calendar/package.json @@ -31,6 +31,7 @@ "dependencies": { "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@types/d3-scale": "^3.2.3", "@types/d3-time": "^1.0.10", diff --git a/packages/calendar/src/Calendar.tsx b/packages/calendar/src/Calendar.tsx index 70d13dea2..2e5a35884 100644 --- a/packages/calendar/src/Calendar.tsx +++ b/packages/calendar/src/Calendar.tsx @@ -1,5 +1,6 @@ import { CalendarSvgProps } from './types' -import { Container, SvgWrapper, useTheme, useDimensions, useValueFormatter } from '@nivo/core' +import { Container, SvgWrapper, useDimensions, useValueFormatter } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { BoxLegendSvg } from '@nivo/legends' import { CalendarYearLegends } from './CalendarYearLegends' import { CalendarMonthPath } from './CalendarMonthPath' diff --git a/packages/calendar/src/CalendarCanvas.tsx b/packages/calendar/src/CalendarCanvas.tsx index 9256d9a03..e1e8571c5 100644 --- a/packages/calendar/src/CalendarCanvas.tsx +++ b/packages/calendar/src/CalendarCanvas.tsx @@ -7,9 +7,9 @@ import { getRelativeCursor, degreesToRadians, useDimensions, - useTheme, useValueFormatter, } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { renderLegendToCanvas } from '@nivo/legends' import { calendarCanvasDefaultProps } from './props' import { useCalendarLayout, useColorScale, useMonthLegends, useYearLegends, useDays } from './hooks' diff --git a/packages/calendar/src/TimeRange.tsx b/packages/calendar/src/TimeRange.tsx index 467208d11..40417213c 100644 --- a/packages/calendar/src/TimeRange.tsx +++ b/packages/calendar/src/TimeRange.tsx @@ -1,5 +1,6 @@ import { useMemo } from 'react' -import { Container, SvgWrapper, useValueFormatter, useTheme, useDimensions } from '@nivo/core' +import { Container, SvgWrapper, useValueFormatter, useDimensions } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { BoxLegendSvg } from '@nivo/legends' import { computeWeekdays, diff --git a/packages/calendar/src/types.ts b/packages/calendar/src/types.ts index 284334727..05338e5b4 100644 --- a/packages/calendar/src/types.ts +++ b/packages/calendar/src/types.ts @@ -1,4 +1,6 @@ -import { Box, BoxAlign, CompleteTheme, Dimensions, Theme, ValueFormat } from '@nivo/core' +import { Box, BoxAlign, Dimensions, ValueFormat } from '@nivo/core' +import { Theme } from '@nivo/theming' +import { PartialTheme } from '@nivo/theming' import { LegendProps } from '@nivo/legends' export type BBox = Record<'x' | 'y' | 'height' | 'width', number> @@ -56,14 +58,14 @@ export interface ColorScale { export type CalendarYearLegendsProps = { legend: (year: number) => string | number - theme: CompleteTheme + theme: Theme years: YearLegend[] } export type CalendarMonthLegendsProps = { legend: (year: number, month: number, date: Date) => string | number months: MonthLegend[] - theme: CompleteTheme + theme: Theme } export type CalendarTooltipProps = { @@ -145,7 +147,7 @@ export type CommonCalendarProps = { valueFormat: ValueFormat legendFormat: ValueFormat - theme: Theme + theme: PartialTheme // interactivity isInteractive: boolean diff --git a/packages/chord/package.json b/packages/chord/package.json index 73de500d5..e5ed9eac7 100644 --- a/packages/chord/package.json +++ b/packages/chord/package.json @@ -33,6 +33,7 @@ "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-chord": "^3.0.1", diff --git a/packages/chord/src/ChordArcs.tsx b/packages/chord/src/ChordArcs.tsx index 34c2ac6a3..0a70ee878 100644 --- a/packages/chord/src/ChordArcs.tsx +++ b/packages/chord/src/ChordArcs.tsx @@ -1,6 +1,7 @@ import { memo } from 'react' import { useTransition } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor } from '@nivo/colors' import { ChordArc } from './ChordArc' import { ArcDatum, ArcGenerator, ChordCommonProps, ArcAnimatedProps } from './types' diff --git a/packages/chord/src/ChordCanvas.tsx b/packages/chord/src/ChordCanvas.tsx index e572fa32f..df74392d3 100644 --- a/packages/chord/src/ChordCanvas.tsx +++ b/packages/chord/src/ChordCanvas.tsx @@ -1,7 +1,6 @@ import { createElement, useRef, useEffect, useCallback, MouseEvent } from 'react' import { useDimensions, - useTheme, // @ts-ignore midAngle, // @ts-ignore @@ -11,6 +10,7 @@ import { Margin, Container, } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { findArcUnderCursor } from '@nivo/arcs' import { useInheritedColor } from '@nivo/colors' import { renderLegendToCanvas } from '@nivo/legends' diff --git a/packages/chord/src/ChordLabels.tsx b/packages/chord/src/ChordLabels.tsx index 66d9f4c94..33c4abbc5 100644 --- a/packages/chord/src/ChordLabels.tsx +++ b/packages/chord/src/ChordLabels.tsx @@ -5,8 +5,8 @@ import { midAngle, // @ts-ignore getPolarLabelProps, - useTheme, } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useMotionConfig } from '@nivo/core' import { ArcDatum, ChordCommonProps } from './types' import { useInheritedColor } from '@nivo/colors' diff --git a/packages/chord/src/ChordRibbons.tsx b/packages/chord/src/ChordRibbons.tsx index fd19da5e8..ec7110fa5 100644 --- a/packages/chord/src/ChordRibbons.tsx +++ b/packages/chord/src/ChordRibbons.tsx @@ -1,11 +1,11 @@ import { memo } from 'react' import { useTransition } from '@react-spring/web' import { - useTheme, // @ts-ignore midAngle, useMotionConfig, } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor } from '@nivo/colors' import { ChordRibbon } from './ChordRibbon' import { diff --git a/packages/chord/src/types.ts b/packages/chord/src/types.ts index 7dafb931c..73b943f00 100644 --- a/packages/chord/src/types.ts +++ b/packages/chord/src/types.ts @@ -3,13 +3,13 @@ import { RibbonGenerator as D3RibbonGenerator } from 'd3-chord' import { Arc as D3Arc } from 'd3-shape' import { Box, - Theme, Dimensions, MotionProps, CssMixBlendMode, PropertyAccessor, ValueFormat, } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { LegendProps } from '@nivo/legends' @@ -114,7 +114,7 @@ export type ChordCommonProps = { innerRadiusRatio: number innerRadiusOffset: number - theme: Theme + theme: PartialTheme colors: OrdinalColorScaleConfig> arcOpacity: number diff --git a/packages/circle-packing/package.json b/packages/circle-packing/package.json index 99cda2cf1..6342c50dd 100644 --- a/packages/circle-packing/package.json +++ b/packages/circle-packing/package.json @@ -31,6 +31,7 @@ "dependencies": { "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-hierarchy": "^1.1.8", diff --git a/packages/circle-packing/src/CirclePackingCanvas.tsx b/packages/circle-packing/src/CirclePackingCanvas.tsx index d7b4f5407..c5fccef13 100644 --- a/packages/circle-packing/src/CirclePackingCanvas.tsx +++ b/packages/circle-packing/src/CirclePackingCanvas.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, createElement } from 'react' import * as React from 'react' -import { useDimensions, useTheme, Container } from '@nivo/core' +import { useDimensions, Container } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig, useInheritedColor } from '@nivo/colors' import { useTooltip } from '@nivo/tooltip' import { CirclePackingCanvasProps, ComputedDatum } from './types' diff --git a/packages/circle-packing/src/Circles.tsx b/packages/circle-packing/src/Circles.tsx index 3e5627382..9285319e1 100644 --- a/packages/circle-packing/src/Circles.tsx +++ b/packages/circle-packing/src/Circles.tsx @@ -1,7 +1,8 @@ import { createElement, useMemo, MouseEvent } from 'react' import * as React from 'react' import { useTransition, to, SpringValue } from '@react-spring/web' -import { useMotionConfig, useTheme } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor } from '@nivo/colors' import { useTooltip } from '@nivo/tooltip' import { ComputedDatum, CircleComponent, MouseHandlers, CirclePackingCommonProps } from './types' diff --git a/packages/circle-packing/src/LabelHtml.tsx b/packages/circle-packing/src/LabelHtml.tsx index 47ffa6891..4f8cabdba 100644 --- a/packages/circle-packing/src/LabelHtml.tsx +++ b/packages/circle-packing/src/LabelHtml.tsx @@ -1,5 +1,5 @@ import { animated } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { LabelProps } from './types' import { interpolatePosition, interpolateSize } from './CircleHtml' diff --git a/packages/circle-packing/src/LabelSvg.tsx b/packages/circle-packing/src/LabelSvg.tsx index 31677d832..6582b0e68 100644 --- a/packages/circle-packing/src/LabelSvg.tsx +++ b/packages/circle-packing/src/LabelSvg.tsx @@ -1,5 +1,5 @@ import { animated } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { LabelProps } from './types' export const LabelSvg = ({ node, label, style }: LabelProps) => { diff --git a/packages/circle-packing/src/hooks.ts b/packages/circle-packing/src/hooks.ts index 42ab46481..abcff1db6 100644 --- a/packages/circle-packing/src/hooks.ts +++ b/packages/circle-packing/src/hooks.ts @@ -2,13 +2,8 @@ import { useMemo, MouseEvent, MutableRefObject, useCallback } from 'react' import { pack as d3Pack, hierarchy as d3Hierarchy } from 'd3-hierarchy' import cloneDeep from 'lodash/cloneDeep' import sortBy from 'lodash/sortBy' -import { - usePropertyAccessor, - useValueFormatter, - useTheme, - getRelativeCursor, - getDistance, -} from '@nivo/core' +import { usePropertyAccessor, useValueFormatter, getRelativeCursor, getDistance } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors' import { CirclePackingCommonProps, diff --git a/packages/circle-packing/src/types.ts b/packages/circle-packing/src/types.ts index 21694d035..21bc8ec94 100644 --- a/packages/circle-packing/src/types.ts +++ b/packages/circle-packing/src/types.ts @@ -1,6 +1,7 @@ import * as React from 'react' import { Interpolation, SpringValue } from '@react-spring/web' -import { Box, MotionProps, Theme, PropertyAccessor, ValueFormat, SvgDefsAndFill } from '@nivo/core' +import { Box, MotionProps, PropertyAccessor, ValueFormat, SvgDefsAndFill } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' export interface ComputedDatum { @@ -55,7 +56,7 @@ export interface CirclePackingCommonProps { margin?: Box padding: number leavesOnly: boolean - theme?: Theme + theme?: PartialTheme colors: OrdinalColorScaleConfig, 'color' | 'fill'>> colorBy: 'id' | 'depth' inheritColorFromParent: boolean diff --git a/packages/colors/package.json b/packages/colors/package.json index 3a85b6033..9f6d98f24 100644 --- a/packages/colors/package.json +++ b/packages/colors/package.json @@ -21,7 +21,7 @@ "!dist/tsconfig.tsbuildinfo" ], "dependencies": { - "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@types/d3-color": "^2.0.0", "@types/d3-scale": "^3.2.3", "@types/d3-scale-chromatic": "^2.0.0", diff --git a/packages/colors/src/inheritedColor.ts b/packages/colors/src/inheritedColor.ts index fbd73fdf8..696adebb0 100644 --- a/packages/colors/src/inheritedColor.ts +++ b/packages/colors/src/inheritedColor.ts @@ -1,7 +1,7 @@ import { useMemo } from 'react' import { get, isPlainObject } from 'lodash' import { rgb, RGBColor } from 'd3-color' -import { Theme } from '@nivo/core' +import { Theme } from '@nivo/theming' export type ColorModifierBrightness = ['brighter', number] diff --git a/packages/core/package.json b/packages/core/package.json index 931fe76a1..f35c87c07 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -22,6 +22,7 @@ ], "dependencies": { "@nivo/recompose": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-shape": "^2.0.0", diff --git a/packages/core/src/components/Container.js b/packages/core/src/components/Container.js index 025cf8fbf..abf4a6a31 100644 --- a/packages/core/src/components/Container.js +++ b/packages/core/src/components/Container.js @@ -1,7 +1,7 @@ import { useRef } from 'react' import PropTypes from 'prop-types' import { TooltipProvider, Tooltip } from '@nivo/tooltip' -import { ThemeProvider } from '../theming' +import { ThemeProvider } from '@nivo/theming' import { MotionConfigProvider } from '../motion' import { ConditionalWrapper } from './ConditionalWrapper' diff --git a/packages/funnel/package.json b/packages/funnel/package.json index 2282d2e7f..c00235d71 100644 --- a/packages/funnel/package.json +++ b/packages/funnel/package.json @@ -32,6 +32,7 @@ "@nivo/annotations": "workspace:*", "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-scale": "^3.2.3", diff --git a/packages/funnel/src/PartLabel.tsx b/packages/funnel/src/PartLabel.tsx index 22bac86ac..c56352653 100644 --- a/packages/funnel/src/PartLabel.tsx +++ b/packages/funnel/src/PartLabel.tsx @@ -1,5 +1,6 @@ import { useSpring, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { FunnelDatum, FunnelPart } from './types' interface PartLabelProps { diff --git a/packages/funnel/src/Separator.tsx b/packages/funnel/src/Separator.tsx index b52f0f86f..92cc93cf6 100644 --- a/packages/funnel/src/Separator.tsx +++ b/packages/funnel/src/Separator.tsx @@ -1,5 +1,6 @@ import { useSpring, animated } from '@react-spring/web' -import { useTheme, useMotionConfig } from '@nivo/core' +import { useMotionConfig } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { SeparatorProps as SeparatorType } from './types' interface SeparatorProps { diff --git a/packages/funnel/src/hooks.ts b/packages/funnel/src/hooks.ts index ca026177a..eb0d8e265 100644 --- a/packages/funnel/src/hooks.ts +++ b/packages/funnel/src/hooks.ts @@ -2,7 +2,8 @@ import { createElement, useMemo, useState, MouseEvent } from 'react' import { line, area, curveBasis, curveLinear } from 'd3-shape' import { ScaleLinear, scaleLinear } from 'd3-scale' import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors' -import { useTheme, useValueFormatter } from '@nivo/core' +import { useValueFormatter } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useAnnotations } from '@nivo/annotations' import { useTooltip, TooltipActionsContextData } from '@nivo/tooltip' import { svgDefaultProps as defaults } from './props' diff --git a/packages/funnel/src/types.ts b/packages/funnel/src/types.ts index 1c4b35cab..5912c33f4 100644 --- a/packages/funnel/src/types.ts +++ b/packages/funnel/src/types.ts @@ -1,6 +1,7 @@ import { AriaAttributes, FunctionComponent, MouseEvent } from 'react' import { Area, Line } from 'd3-shape' -import { Box, Theme, Dimensions, MotionProps, ValueFormat } from '@nivo/core' +import { Box, Dimensions, MotionProps, ValueFormat } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { AnnotationMatcher } from '@nivo/annotations' import { PartTooltipProps } from './PartTooltip' @@ -93,7 +94,7 @@ export interface FunnelCommonProps { spacing: number shapeBlending: number - theme: Theme + theme: PartialTheme colors: OrdinalColorScaleConfig fillOpacity: number borderWidth: number diff --git a/packages/geo/index.d.ts b/packages/geo/index.d.ts index f0567d22c..c9cdaa572 100644 --- a/packages/geo/index.d.ts +++ b/packages/geo/index.d.ts @@ -1,5 +1,6 @@ import * as React from 'react' -import { Dimensions, Theme, Box } from '@nivo/core' +import { Dimensions, Box } from '@nivo/core' +import { PartialTheme } from '@nivo/theming' import { LegendProps } from '@nivo/legends' declare module '@nivo/geo' { @@ -37,7 +38,7 @@ declare module '@nivo/geo' { isInteractive?: boolean - theme?: Theme + theme?: PartialTheme } /////////////////////////////////////////////////////////////////////////// diff --git a/packages/geo/package.json b/packages/geo/package.json index 265be2a12..30912b2a8 100644 --- a/packages/geo/package.json +++ b/packages/geo/package.json @@ -32,6 +32,7 @@ "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "d3-format": "^1.4.4", "d3-geo": "^1.11.3", diff --git a/packages/geo/src/Choropleth.js b/packages/geo/src/Choropleth.js index 80ab7eb7f..76d0c5733 100644 --- a/packages/geo/src/Choropleth.js +++ b/packages/geo/src/Choropleth.js @@ -7,7 +7,8 @@ * file that was distributed with this source code. */ import { memo, Fragment, useCallback } from 'react' -import { SvgWrapper, withContainer, useDimensions, useTheme, bindDefs } from '@nivo/core' +import { SvgWrapper, withContainer, useDimensions, bindDefs } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { BoxLegendSvg } from '@nivo/legends' import { useTooltip } from '@nivo/tooltip' import { ChoroplethPropTypes, ChoroplethDefaultProps } from './props' diff --git a/packages/geo/src/ChoroplethCanvas.js b/packages/geo/src/ChoroplethCanvas.js index d9886e9c8..8b4b49b87 100644 --- a/packages/geo/src/ChoroplethCanvas.js +++ b/packages/geo/src/ChoroplethCanvas.js @@ -8,7 +8,8 @@ */ import { memo, useRef, useEffect, useCallback } from 'react' import { geoContains } from 'd3-geo' -import { getRelativeCursor, withContainer, useDimensions, useTheme } from '@nivo/core' +import { getRelativeCursor, withContainer, useDimensions } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { renderLegendToCanvas } from '@nivo/legends' import { useTooltip } from '@nivo/tooltip' import { ChoroplethCanvasDefaultProps, ChoroplethCanvasPropTypes } from './props' diff --git a/packages/geo/src/GeoMap.js b/packages/geo/src/GeoMap.js index fb4394906..7c3946b47 100644 --- a/packages/geo/src/GeoMap.js +++ b/packages/geo/src/GeoMap.js @@ -7,7 +7,8 @@ * file that was distributed with this source code. */ import { Fragment, useCallback, memo } from 'react' -import { SvgWrapper, withContainer, useDimensions, useTheme } from '@nivo/core' +import { SvgWrapper, withContainer, useDimensions } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useTooltip } from '@nivo/tooltip' import { GeoMapPropTypes, GeoMapDefaultProps } from './props' import GeoGraticule from './GeoGraticule' diff --git a/packages/geo/src/GeoMapCanvas.js b/packages/geo/src/GeoMapCanvas.js index 22a727455..a5327fd38 100644 --- a/packages/geo/src/GeoMapCanvas.js +++ b/packages/geo/src/GeoMapCanvas.js @@ -8,7 +8,8 @@ */ import { memo, useRef, useEffect, useCallback } from 'react' import { geoContains } from 'd3-geo' -import { getRelativeCursor, withContainer, useDimensions, useTheme } from '@nivo/core' +import { getRelativeCursor, withContainer, useDimensions } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useTooltip } from '@nivo/tooltip' import { GeoMapCanvasDefaultProps, GeoMapCanvasPropTypes } from './props' import { useGeoMap } from './hooks' diff --git a/packages/geo/src/hooks.js b/packages/geo/src/hooks.js index afc18d610..a8ce90f81 100644 --- a/packages/geo/src/hooks.js +++ b/packages/geo/src/hooks.js @@ -23,7 +23,8 @@ import { geoNaturalEarth1, geoGraticule, } from 'd3-geo' -import { guessQuantizeColorScale, useTheme } from '@nivo/core' +import { guessQuantizeColorScale } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor } from '@nivo/colors' import { useQuantizeColorScaleLegendData } from '@nivo/legends' diff --git a/packages/heatmap/package.json b/packages/heatmap/package.json index fa9a95806..ec4bcde27 100644 --- a/packages/heatmap/package.json +++ b/packages/heatmap/package.json @@ -35,6 +35,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", "@types/d3-scale": "^3.2.3", diff --git a/packages/heatmap/src/HeatMapCanvas.tsx b/packages/heatmap/src/HeatMapCanvas.tsx index 13d446103..4dda48a3d 100644 --- a/packages/heatmap/src/HeatMapCanvas.tsx +++ b/packages/heatmap/src/HeatMapCanvas.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useCallback, createElement, useMemo, MouseEvent } from 'react' -import { getRelativeCursor, isCursorInRect, useDimensions, useTheme, Container } from '@nivo/core' +import { getRelativeCursor, isCursorInRect, useDimensions, Container } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { renderAxesToCanvas, renderGridLinesToCanvas } from '@nivo/axes' import { useTooltip } from '@nivo/tooltip' import { renderContinuousColorLegendToCanvas } from '@nivo/legends' diff --git a/packages/heatmap/src/HeatMapCellCircle.tsx b/packages/heatmap/src/HeatMapCellCircle.tsx index f9848cef0..016b5d4a1 100644 --- a/packages/heatmap/src/HeatMapCellCircle.tsx +++ b/packages/heatmap/src/HeatMapCellCircle.tsx @@ -1,6 +1,6 @@ import { memo, useMemo } from 'react' import { animated, to } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { HeatMapDatum, CellComponentProps } from './types' const NonMemoizedHeatMapCellCircle = ({ diff --git a/packages/heatmap/src/HeatMapCellRect.tsx b/packages/heatmap/src/HeatMapCellRect.tsx index 960a50565..76cc55e88 100644 --- a/packages/heatmap/src/HeatMapCellRect.tsx +++ b/packages/heatmap/src/HeatMapCellRect.tsx @@ -1,6 +1,6 @@ import { memo, useMemo } from 'react' import { animated, to } from '@react-spring/web' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { CellComponentProps, HeatMapDatum } from './types' const NonMemoizedHeatMapCellRect = ({ diff --git a/packages/heatmap/src/hooks.ts b/packages/heatmap/src/hooks.ts index 513e07a24..513b13881 100644 --- a/packages/heatmap/src/hooks.ts +++ b/packages/heatmap/src/hooks.ts @@ -1,5 +1,6 @@ import { useMemo, useCallback, useState } from 'react' -import { useTheme, usePropertyAccessor, useValueFormatter } from '@nivo/core' +import { usePropertyAccessor, useValueFormatter } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { useInheritedColor, getContinuousColorScale } from '@nivo/colors' import { AnnotationMatcher, useAnnotations } from '@nivo/annotations' import { diff --git a/packages/heatmap/src/types.ts b/packages/heatmap/src/types.ts index 4a50850fb..69105634c 100644 --- a/packages/heatmap/src/types.ts +++ b/packages/heatmap/src/types.ts @@ -2,13 +2,12 @@ import { AriaAttributes, MouseEvent, FunctionComponent } from 'react' import { AnimatedProps } from '@react-spring/web' import { Box, - Theme, - CompleteTheme, Dimensions, MotionProps, PropertyAccessor, ValueFormat, } from '@nivo/core' +import { PartialTheme, Theme } from '@nivo/theming' import { AxisProps, CanvasAxisProps } from '@nivo/axes' import { InheritedColorConfig, ContinuousColorScaleConfig } from '@nivo/colors' import { AnchoredContinuousColorsLegendProps } from '@nivo/legends' @@ -103,7 +102,7 @@ export interface CellCanvasRendererProps { cell: ComputedCell borderWidth: number enableLabels: boolean - theme: CompleteTheme + theme: Theme } export type CellCanvasRenderer = ( ctx: CanvasRenderingContext2D, @@ -133,7 +132,7 @@ export type HeatMapCommonProps = { enableGridX: boolean enableGridY: boolean - theme: Theme + theme: PartialTheme colors: | ContinuousColorScaleConfig | (( diff --git a/packages/legends/package.json b/packages/legends/package.json index 9d9085522..3dc774a0b 100644 --- a/packages/legends/package.json +++ b/packages/legends/package.json @@ -24,6 +24,7 @@ "dependencies": { "@nivo/colors": "workspace:*", "@nivo/core": "workspace:*", + "@nivo/theming": "workspace:*", "@types/d3-scale": "^3.2.3", "@types/prop-types": "^15.7.2", "d3-scale": "^3.2.3", diff --git a/packages/legends/src/canvas.ts b/packages/legends/src/canvas.ts index 2f59d88a6..7303a6afc 100644 --- a/packages/legends/src/canvas.ts +++ b/packages/legends/src/canvas.ts @@ -1,4 +1,5 @@ -import { CompleteTheme, degreesToRadians } from '@nivo/core' +import { degreesToRadians } from '@nivo/core' +import { Theme } from '@nivo/theming' import { computeDimensions, computePositionFromAnchor, @@ -125,7 +126,7 @@ export const renderContinuousColorLegendToCanvas = ( titleOffset = continuousColorsLegendDefaults.titleOffset, theme, }: AnchoredContinuousColorsLegendProps & { - theme: CompleteTheme + theme: Theme } ) => { const { diff --git a/packages/legends/src/svg/ContinuousColorsLegendSvg.tsx b/packages/legends/src/svg/ContinuousColorsLegendSvg.tsx index feb2e5787..39f909848 100644 --- a/packages/legends/src/svg/ContinuousColorsLegendSvg.tsx +++ b/packages/legends/src/svg/ContinuousColorsLegendSvg.tsx @@ -1,5 +1,5 @@ import { Fragment } from 'react' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { computeContinuousColorsLegend } from '../compute' import { ContinuousColorsLegendProps } from '../types' import { continuousColorsLegendDefaults } from '../defaults' diff --git a/packages/legends/src/svg/LegendSvgItem.tsx b/packages/legends/src/svg/LegendSvgItem.tsx index 4aaa7fe2e..a21e5c70d 100644 --- a/packages/legends/src/svg/LegendSvgItem.tsx +++ b/packages/legends/src/svg/LegendSvgItem.tsx @@ -1,6 +1,6 @@ import { useState, useCallback } from 'react' import * as React from 'react' -import { useTheme } from '@nivo/core' +import { useTheme } from '@nivo/theming' import { LegendSvgItemProps } from '../types' import { computeItemLayout } from '../compute' import { SymbolCircle, SymbolDiamond, SymbolSquare, SymbolTriangle } from './symbols' diff --git a/packages/legends/src/types.ts b/packages/legends/src/types.ts index adea14c59..7018bba93 100644 --- a/packages/legends/src/types.ts +++ b/packages/legends/src/types.ts @@ -1,6 +1,7 @@ import * as React from 'react' import { ScaleDiverging, ScaleQuantize, ScaleSequential } from 'd3-scale' -import { CompleteTheme, ValueFormat } from '@nivo/core' +import { ValueFormat } from '@nivo/core' +import { Theme } from '@nivo/theming' import { SymbolProps } from './svg/symbols/types' /** @@ -135,7 +136,7 @@ export type LegendCanvasProps = { symbolSize?: number symbolSpacing?: number - theme: CompleteTheme + theme: Theme } & Required> & Pick< CommonLegendProps, diff --git a/packages/line/package.json b/packages/line/package.json index 0d54b2ad5..5bec8c63b 100644 --- a/packages/line/package.json +++ b/packages/line/package.json @@ -35,6 +35,7 @@ "@nivo/core": "workspace:*", "@nivo/legends": "workspace:*", "@nivo/scales": "workspace:*", + "@nivo/theming": "workspace:*", "@nivo/tooltip": "workspace:*", "@nivo/voronoi": "workspace:*", "@react-spring/web": "9.4.5 || ^9.7.2", diff --git a/packages/theming/LICENSE.md b/packages/theming/LICENSE.md new file mode 100644 index 000000000..faa45389e --- /dev/null +++ b/packages/theming/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) Raphaël Benitte + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/theming/README.md b/packages/theming/README.md new file mode 100644 index 000000000..a03dab875 --- /dev/null +++ b/packages/theming/README.md @@ -0,0 +1,6 @@ +nivo + +# `@nivo/theming` + +[![version](https://img.shields.io/npm/v/@nivo/theming?style=for-the-badge)](https://www.npmjs.com/package/@nivo/theming) +[![downloads](https://img.shields.io/npm/dm/@nivo/theming?style=for-the-badge)](https://www.npmjs.com/package/@nivo/theming) diff --git a/packages/theming/package.json b/packages/theming/package.json new file mode 100644 index 000000000..e5e74b3aa --- /dev/null +++ b/packages/theming/package.json @@ -0,0 +1,30 @@ +{ + "name": "@nivo/theming", + "version": "0.83.0", + "license": "MIT", + "author": { + "name": "Raphaël Benitte", + "url": "https://github.com/plouc" + }, + "repository": { + "type": "git", + "url": "https://github.com/plouc/nivo.git", + "directory": "packages/theming" + }, + "sideEffects": false, + "main": "./dist/nivo-theming.cjs.js", + "module": "./dist/nivo-theming.es.js", + "types": "./dist/types/index.d.ts", + "files": [ + "README.md", + "LICENSE.md", + "dist/", + "!dist/tsconfig.tsbuildinfo" + ], + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/theming/src/context.tsx b/packages/theming/src/context.tsx new file mode 100644 index 000000000..61b2906f5 --- /dev/null +++ b/packages/theming/src/context.tsx @@ -0,0 +1,30 @@ +import { createContext, useContext, PropsWithChildren } from 'react' +import { usePartialTheme } from './hooks' +import { PartialTheme, Theme } from './types' + +export const ThemeContext = createContext(null) + +// required to preserve equality +const defaultPartialTheme = {} + +export const ThemeProvider = ({ + theme: partialTheme = defaultPartialTheme, + children, +}: PropsWithChildren<{ + theme: PartialTheme +}>) => { + const theme = usePartialTheme(partialTheme) + + return {children} +} + +export const useTheme = () => { + const theme = useContext(ThemeContext) + if (theme === null) { + throw new Error( + 'Unable to find the theme, did you forget to wrap your component with ThemeProvider?' + ) + } + + return theme +} diff --git a/packages/theming/src/defaults.ts b/packages/theming/src/defaults.ts new file mode 100644 index 000000000..41ef028fd --- /dev/null +++ b/packages/theming/src/defaults.ts @@ -0,0 +1,137 @@ +import { ThemeWithoutInheritance } from './types' + +export const defaultTheme: ThemeWithoutInheritance = { + background: 'transparent', + text: { + fontFamily: 'sans-serif', + fontSize: 11, + fill: '#333333', + outlineWidth: 0, + outlineColor: '#ffffff', + outlineOpacity: 1, + }, + axis: { + domain: { + line: { + stroke: 'transparent', + strokeWidth: 1, + }, + }, + ticks: { + line: { + stroke: '#777777', + strokeWidth: 1, + }, + text: {}, + }, + legend: { + text: { + fontSize: 12, + }, + }, + }, + grid: { + line: { + stroke: '#dddddd', + strokeWidth: 1, + }, + }, + legends: { + hidden: { + symbol: { + fill: '#333333', + opacity: 0.6, + }, + text: { + fill: '#333333', + opacity: 0.6, + }, + }, + text: {}, + ticks: { + line: { + stroke: '#777777', + strokeWidth: 1, + }, + text: { + fontSize: 10, + }, + }, + title: { + text: {}, + }, + }, + labels: { + text: {}, + }, + markers: { + lineColor: '#000000', + lineStrokeWidth: 1, + text: {}, + }, + dots: { + text: {}, + }, + tooltip: { + container: { + background: 'white', + color: 'inherit', + fontSize: 'inherit', + borderRadius: '2px', + boxShadow: '0 1px 2px rgba(0, 0, 0, 0.25)', + padding: '5px 9px', + }, + basic: { + whiteSpace: 'pre', + display: 'flex', + alignItems: 'center', + }, + chip: { + marginRight: 7, + }, + table: {}, + tableCell: { + padding: '3px 5px', + }, + tableCellValue: { + fontWeight: 'bold', + }, + }, + crosshair: { + line: { + stroke: '#000000', + strokeWidth: 1, + strokeOpacity: 0.75, + strokeDasharray: '6 6', + }, + }, + annotations: { + text: { + fontSize: 13, + outlineWidth: 2, + outlineColor: '#ffffff', + outlineOpacity: 1, + }, + link: { + stroke: '#000000', + strokeWidth: 1, + outlineWidth: 2, + outlineColor: '#ffffff', + outlineOpacity: 1, + }, + outline: { + fill: 'none', + stroke: '#000000', + strokeWidth: 2, + outlineWidth: 2, + outlineColor: '#ffffff', + outlineOpacity: 1, + }, + symbol: { + fill: '#000000', + outlineWidth: 2, + outlineColor: '#ffffff', + outlineOpacity: 1, + }, + }, +} diff --git a/packages/theming/src/extend.ts b/packages/theming/src/extend.ts new file mode 100644 index 000000000..fd2ed67d2 --- /dev/null +++ b/packages/theming/src/extend.ts @@ -0,0 +1,38 @@ +import merge from 'lodash/merge' +import get from 'lodash/get' +import set from 'lodash/set' +import { ThemeWithoutInheritance, PartialTheme, Theme, TextStyle } from './types' + +const textPropsWithInheritance = [ + 'axis.ticks.text', + 'axis.legend.text', + 'legends.title.text', + 'legends.text', + 'legends.ticks.text', + 'legends.title.text', + 'labels.text', + 'dots.text', + 'markers.text', + 'annotations.text', +] + +export const inheritRootThemeText = ( + partialStyle: Partial, + rootStyle: TextStyle +): TextStyle => ({ + ...rootStyle, + ...partialStyle, +}) + +export const extendDefaultTheme = ( + defaultTheme: ThemeWithoutInheritance, + customTheme: PartialTheme +) => { + const theme = merge({}, defaultTheme, customTheme) as Theme + + textPropsWithInheritance.forEach(prop => { + set(theme, prop, inheritRootThemeText(get(theme, prop), theme.text)) + }) + + return theme +} diff --git a/packages/theming/src/hooks.ts b/packages/theming/src/hooks.ts new file mode 100644 index 000000000..99257d4f1 --- /dev/null +++ b/packages/theming/src/hooks.ts @@ -0,0 +1,8 @@ +import { useMemo } from 'react' +import { extendDefaultTheme } from './extend' +import { defaultTheme } from './defaults' +import { PartialTheme } from './types' + +export const usePartialTheme = (partialTheme: PartialTheme) => { + return useMemo(() => extendDefaultTheme(defaultTheme, partialTheme), [partialTheme]) +} diff --git a/packages/theming/src/index.ts b/packages/theming/src/index.ts new file mode 100644 index 000000000..c043d311a --- /dev/null +++ b/packages/theming/src/index.ts @@ -0,0 +1,5 @@ +export * from './context' +export * from './defaults' +export * from './extend' +export * from './hooks' +export * from './types' diff --git a/packages/theming/src/types.ts b/packages/theming/src/types.ts new file mode 100644 index 000000000..046a3c3fa --- /dev/null +++ b/packages/theming/src/types.ts @@ -0,0 +1,219 @@ +import { CSSProperties } from 'react' + +export type TextStyle = { + fontFamily: Exclude + fontSize: Exclude + fill: string + outlineWidth: number + outlineColor: string + outlineOpacity: number +} & Partial + +export type Theme = { + background: string + text: TextStyle + axis: { + domain: { + line: Partial + } + ticks: { + line: Partial + text: TextStyle + } + legend: { + text: TextStyle + } + } + grid: { + line: Partial + } + crosshair: { + line: { + stroke: string + strokeWidth: number + strokeOpacity: number + strokeDasharray: string + } + } + legends: { + hidden: { + symbol: Partial<{ + fill: string + opacity: number + }> + text: TextStyle + } + text: TextStyle + title: { + text: TextStyle + } + ticks: { + line: Partial + text: TextStyle + } + } + labels: { + text: TextStyle + } + markers: { + lineColor: string + lineStrokeWidth: number + text: TextStyle + } + dots: { + text: TextStyle + } + tooltip: { + container: Partial + basic: Partial + chip: Partial + table: Partial + tableCell: Partial + tableCellValue: Partial + } + annotations: { + text: TextStyle + link: { + stroke: string + strokeWidth: number + outlineWidth: number + outlineColor: string + outlineOpacity: number + } & Partial> + outline: { + stroke: string + strokeWidth: number + outlineWidth: number + outlineColor: string + outlineOpacity: number + } & Partial> + symbol: { + fill: string + outlineWidth: number + outlineColor: string + outlineOpacity: number + } & Partial> + } +} + +/** + * Theme which can be passed to chart components. + * + * Internal component will often rely on `Theme` to avoid + * having to recompute the inherited properties each time we need the theme. + */ +export type PartialTheme = Partial<{ + background: Theme['background'] + text: Partial + axis: Partial<{ + domain: Partial<{ + line: Partial + }> + ticks: Partial<{ + line: Partial + text: Partial + }> + legend: Partial<{ + text: Partial + }> + }> + grid: Partial<{ + line: Partial + }> + crosshair: Partial<{ + line: Partial + }> + legends: Partial<{ + hidden: Partial<{ + symbol: Theme['legends']['hidden']['symbol'] + text: Theme['legends']['hidden']['text'] + }> + title: Partial<{ + text: Partial + }> + text: Partial + ticks: Partial<{ + line: Partial + text: Partial + }> + }> + labels: Partial<{ + text: Partial + }> + markers: Partial + dots: Partial<{ + text: Partial + }> + tooltip: Partial + annotations: Partial<{ + text: Partial + link: Partial + outline: Partial + symbol: Partial + }> +}> + +/** + * Required properties without inheritance. + * + * The theme supports defining styles at the top level + * (for text for example), which are then used to populate + * similar nested properties. + * + * For example `text` will be merged with `axis.ticks.text`, + * we use this approach so that it's simpler to define global styles. + */ +export type ThemeWithoutInheritance = { + background: Theme['background'] + text: Theme['text'] + axis: { + domain: { + line: Theme['axis']['domain']['line'] + } + ticks: { + line: Theme['axis']['ticks']['line'] + text: Partial + } + legend: { + text: Partial + } + } + grid: { + line: Theme['grid']['line'] + } + crosshair: { + line: Theme['crosshair']['line'] + } + legends: { + hidden: { + symbol: Theme['legends']['hidden']['symbol'] + text: Partial + } + title: { + text: Partial + } + text: Partial + ticks: { + line: Theme['legends']['ticks']['line'] + text: Partial + } + } + labels: { + text: Partial + } + markers: { + lineColor: Theme['markers']['lineColor'] + lineStrokeWidth: Theme['markers']['lineStrokeWidth'] + text: Partial + } + dots: { + text: Partial + } + tooltip: Theme['tooltip'] + annotations: { + text: Partial + link: Theme['annotations']['link'] + outline: Theme['annotations']['outline'] + symbol: Theme['annotations']['symbol'] + } +} diff --git a/packages/theming/tsconfig.json b/packages/theming/tsconfig.json new file mode 100644 index 000000000..569f591b4 --- /dev/null +++ b/packages/theming/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.types.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "./dist/types", + "rootDir": "./src" + }, + "include": ["src/**/*"] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0508f32d..47d7a939c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -337,6 +337,9 @@ importers: '@nivo/core': specifier: workspace:* version: link:../core + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@react-spring/web': specifier: 9.4.5 || ^9.7.2 version: 9.7.2(react-dom@18.2.0)(react@18.2.0) @@ -361,6 +364,9 @@ importers: '@nivo/core': specifier: workspace:* version: link:../core + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@react-spring/web': specifier: 9.4.5 || ^9.7.2 version: 9.7.2(react-dom@18.2.0)(react@18.2.0) @@ -382,6 +388,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@react-spring/web': specifier: 9.4.5 || ^9.7.2 version: 9.7.2(react-dom@18.2.0)(react@18.2.0) @@ -427,6 +436,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -472,6 +484,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -514,6 +529,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -541,6 +559,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -571,6 +592,9 @@ importers: '@nivo/legends': specifier: workspace:* version: link:../legends + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -615,6 +639,9 @@ importers: '@nivo/legends': specifier: workspace:* version: link:../legends + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -645,6 +672,9 @@ importers: '@nivo/core': specifier: workspace:* version: link:../core + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -666,9 +696,9 @@ importers: packages/colors: dependencies: - '@nivo/core': + '@nivo/theming': specifier: workspace:* - version: link:../core + version: link:../theming '@types/d3-color': specifier: ^2.0.0 version: 2.0.3 @@ -705,6 +735,9 @@ importers: '@nivo/recompose': specifier: workspace:* version: link:../recompose + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -786,6 +819,9 @@ importers: '@nivo/core': specifier: workspace:* version: link:../core + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -843,6 +879,9 @@ importers: '@nivo/legends': specifier: workspace:* version: link:../legends + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -884,6 +923,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -908,6 +950,9 @@ importers: '@nivo/core': specifier: workspace:* version: link:../core + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@types/d3-scale': specifier: ^3.2.3 version: 3.3.2 @@ -944,6 +989,9 @@ importers: '@nivo/scales': specifier: workspace:* version: link:../scales + '@nivo/theming': + specifier: workspace:* + version: link:../theming '@nivo/tooltip': specifier: workspace:* version: link:../tooltip @@ -1482,6 +1530,12 @@ importers: specifier: '>= 16.14.0 < 19.0.0' version: 18.2.0 + packages/theming: + dependencies: + react: + specifier: '>= 16.14.0 < 19.0.0' + version: 18.2.0 + packages/tooltip: dependencies: '@nivo/core': @@ -11192,7 +11246,6 @@ packages: dependencies: ms: 2.1.3 supports-color: 5.5.0 - dev: true /debug@3.2.7(supports-color@8.1.1): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} @@ -11204,6 +11257,7 @@ packages: dependencies: ms: 2.1.3 supports-color: 8.1.1 + dev: true /debug@4.3.4(supports-color@5.5.0): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -11481,7 +11535,7 @@ packages: '@types/tmp': 0.0.33 application-config-path: 0.1.0 command-exists: 1.2.9 - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) eol: 0.9.1 get-port: 3.2.0 glob: 7.2.3 @@ -12237,7 +12291,7 @@ packages: /eslint-import-resolver-node@0.3.6: resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} dependencies: - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) resolve: 1.22.2 transitivePeerDependencies: - supports-color @@ -12246,7 +12300,7 @@ packages: /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} dependencies: - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) is-core-module: 2.12.0 resolve: 1.22.2 transitivePeerDependencies: @@ -12272,7 +12326,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 5.59.1(eslint@8.39.0)(typescript@4.9.5) - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) eslint-import-resolver-node: 0.3.6 find-up: 2.1.0 pkg-dir: 2.0.0 @@ -12302,7 +12356,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 5.59.1(eslint@8.39.0)(typescript@4.9.5) - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) eslint: 8.39.0 eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: @@ -12380,7 +12434,7 @@ packages: array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 8.39.0 eslint-import-resolver-node: 0.3.7 @@ -12924,7 +12978,7 @@ packages: resolution: {integrity: sha512-/l77JHcOUrDUX8V67E287VEUQT0lbm71gdGVoodnlWBziarYKgMcpqT7xvh/HM8Jv52phw8Bd8tY+a7QjOr7Yg==} engines: {node: '>=6.0.0'} dependencies: - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) es6-promise: 4.2.8 raw-body: 2.4.3 transitivePeerDependencies: @@ -18548,7 +18602,7 @@ packages: engines: {node: '>= 4.4.x'} hasBin: true dependencies: - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7(supports-color@5.5.0) iconv-lite: 0.4.24 sax: 1.2.4 transitivePeerDependencies: diff --git a/tsconfig.monorepo.json b/tsconfig.monorepo.json index f7f084084..dd6096aa7 100644 --- a/tsconfig.monorepo.json +++ b/tsconfig.monorepo.json @@ -5,6 +5,7 @@ // { "path": "./packages/core" }, // Shared next because charts need them + { "path": "./packages/theming" }, { "path": "./packages/canvas" }, { "path": "./packages/annotations" }, { "path": "./packages/scales" },