UNPKG

@nivo/theming

Version:
1 lines 18.4 kB
{"version":3,"file":"nivo-theming.mjs","sources":["../src/borderRadius.ts","../src/bridge.ts","../src/extend.ts","../src/defaults.ts","../src/hooks.ts","../src/context.tsx"],"sourcesContent":["export interface BorderRadiusCorners<V = number> {\n topLeft: V\n topRight: V\n bottomRight: V\n bottomLeft: V\n}\n\nexport interface BorderRadiusObject<V = number> extends Partial<BorderRadiusCorners<V>> {\n top?: V\n bottom?: V\n left?: V\n right?: V\n}\n\nexport type BorderRadius<V = number> = V | BorderRadiusObject<V>\n\n/**\n * Normalize a borderRadius input into explicit corner values.\n *\n * Priority order is:\n * 1. Uniform number\n * 2. Explicit corner\n * 3. Group (top/bottom/left/right)\n * 4. 0\n *\n * We use a generic type here to allow for react-spring animated values.\n *\n * @param radius either a uniform number, or an object mixing group+corner values\n * @returns an object with topLeft, topRight, bottomRight, bottomLeft\n */\nexport const normalizeBorderRadius = <V = number>(\n radius: BorderRadius<V>\n): BorderRadiusCorners<V> => {\n // Uniform number\n if (radius == null || typeof radius !== 'object') {\n const uniform = radius as V\n return { topLeft: uniform, topRight: uniform, bottomRight: uniform, bottomLeft: uniform }\n }\n\n // Groups and corners\n const obj = radius as BorderRadiusObject<V>\n const uniform = 0 as V\n const top = obj.top\n const bottom = obj.bottom\n const left = obj.left\n const right = obj.right\n\n return {\n topLeft: obj.topLeft ?? (top !== undefined ? top : (left ?? uniform)),\n topRight: obj.topRight ?? (top !== undefined ? top : (right ?? uniform)),\n bottomRight: obj.bottomRight ?? (bottom !== undefined ? bottom : (right ?? uniform)),\n bottomLeft: obj.bottomLeft ?? (bottom !== undefined ? bottom : (left ?? uniform)),\n }\n}\n\n/**\n * Adjusts corner radii so they never exceed half of the width/height or sum constraints.\n */\nexport const constrainBorderRadius = (\n radius: BorderRadius,\n width: number,\n height: number\n): BorderRadiusCorners => {\n const { topLeft, topRight, bottomRight, bottomLeft } = normalizeBorderRadius(radius)\n\n let topLeftConstrained = Math.max(0, topLeft)\n let topRightConstrained = Math.max(0, topRight)\n let bottomRightConstrained = Math.max(0, bottomRight)\n let bottomLeftConstrained = Math.max(0, bottomLeft)\n\n // Horizontal constraints per edge\n const sumTop = topLeftConstrained + topRightConstrained\n if (sumTop > width) {\n const scale = width / sumTop\n topLeftConstrained *= scale\n topRightConstrained *= scale\n }\n const sumBottom = bottomLeftConstrained + bottomRightConstrained\n if (sumBottom > width) {\n const scale = width / sumBottom\n bottomLeftConstrained *= scale\n bottomRightConstrained *= scale\n }\n\n // Vertical constraints per edge\n const sumLeft = topLeftConstrained + bottomLeftConstrained\n if (sumLeft > height) {\n const scale = height / sumLeft\n topLeftConstrained *= scale\n bottomLeftConstrained *= scale\n }\n const sumRight = topRightConstrained + bottomRightConstrained\n if (sumRight > height) {\n const scale = height / sumRight\n topRightConstrained *= scale\n bottomRightConstrained *= scale\n }\n\n return {\n topLeft: topLeftConstrained,\n topRight: topRightConstrained,\n bottomRight: bottomRightConstrained,\n bottomLeft: bottomLeftConstrained,\n }\n}\n","import { TextStyle } from './types'\nimport { BorderRadiusCorners } from './borderRadius'\n\nexport type Engine = 'svg' | 'css' | 'canvas'\n\nexport type TextAlign = 'start' | 'center' | 'end'\nexport type TextBaseline = 'top' | 'center' | 'bottom'\n\nexport interface EngineStyleAttributesMapping {\n textAlign: Record<TextAlign, string>\n textBaseline: Record<TextBaseline, string>\n}\n\nexport const svgStyleAttributesMapping: EngineStyleAttributesMapping = {\n textAlign: {\n start: 'start',\n center: 'middle',\n end: 'end',\n },\n textBaseline: {\n top: 'text-before-edge',\n center: 'middle',\n bottom: 'text-after-edge',\n },\n}\n\nexport const cssStyleAttributesMapping: EngineStyleAttributesMapping = {\n textAlign: {\n start: 'left',\n center: 'center',\n end: 'right',\n },\n textBaseline: {\n top: 'top',\n center: 'middle',\n bottom: 'bottom',\n },\n}\n\nexport const canvasStyleAttributesMapping: EngineStyleAttributesMapping = {\n textAlign: {\n start: 'left',\n center: 'center',\n end: 'right',\n },\n textBaseline: {\n top: 'top',\n center: 'middle',\n bottom: 'bottom',\n },\n}\n\nexport const styleAttributesMapping: Record<Engine, EngineStyleAttributesMapping> = {\n svg: svgStyleAttributesMapping,\n css: cssStyleAttributesMapping,\n canvas: canvasStyleAttributesMapping,\n}\n\nexport const convertStyleAttribute = <K extends keyof EngineStyleAttributesMapping>(\n engine: Engine,\n attr: K,\n value: keyof EngineStyleAttributesMapping[K]\n) => {\n return styleAttributesMapping[engine][attr][value]\n}\n\nexport const sanitizeSvgTextStyle = (\n style: TextStyle\n): Omit<TextStyle, 'outlineWidth' | 'outlineColor' | 'outlineOpacity'> => {\n const { outlineWidth, outlineColor, outlineOpacity, ...sanitized } = style\n\n return sanitized\n}\n\nexport const sanitizeHtmlTextStyle = (\n style: TextStyle\n): Omit<TextStyle, 'outlineWidth' | 'outlineColor' | 'outlineOpacity' | 'fill'> => {\n const { fill, outlineWidth, outlineColor, outlineOpacity, ...sanitized } = style\n\n return {\n ...sanitized,\n color: fill,\n }\n}\n\n/**\n * Render a CSS-compatible border-radius string (e.g. \"4px 4px 0 0\").\n */\nexport const borderRadiusToCss = ({\n topLeft,\n topRight,\n bottomRight,\n bottomLeft,\n}: BorderRadiusCorners): string => {\n return `${topLeft}px ${topRight}px ${bottomRight}px ${bottomLeft}px`\n}\n","import merge from 'lodash/merge.js'\nimport get from 'lodash/get.js'\nimport set from 'lodash/set.js'\nimport { ThemeWithoutInheritance, PartialTheme, Theme, TextStyle } from './types'\n\nconst textPropsWithInheritance = [\n 'axis.ticks.text',\n 'axis.legend.text',\n 'legends.title.text',\n 'legends.text',\n 'legends.ticks.text',\n 'legends.title.text',\n 'labels.text',\n 'dots.text',\n 'markers.text',\n 'annotations.text',\n]\n\nexport const inheritRootThemeText = (\n partialStyle: Partial<TextStyle>,\n rootStyle: TextStyle\n): TextStyle => ({\n ...rootStyle,\n ...partialStyle,\n})\n\nexport const extendDefaultTheme = (\n defaultTheme: ThemeWithoutInheritance,\n customTheme: PartialTheme\n) => {\n const theme = merge({}, defaultTheme, customTheme) as Theme\n\n textPropsWithInheritance.forEach(prop => {\n set(theme, prop, inheritRootThemeText(get(theme, prop), theme.text))\n })\n\n return theme\n}\n\n// We support various types of axes, top, right, bottom, polar...\n// Adding new entries for each axis type is not necessarily ideal to\n// allow the customization of the theme for a specific axis.\n// We might even support multiple axes of the same type in the future.\n// We can use this helper to extend the theme for a specific axis type,\n// the overrides being provided as a property of the axis type.\n// This helper assumes that we're extending a complete theme,\n// because it's going to be used deeper in the component tree.\nexport const extendAxisTheme = (\n axisTheme: Theme['axis'],\n overrides: PartialTheme['axis']\n): Theme['axis'] => {\n if (!overrides) return axisTheme\n return merge({}, axisTheme, overrides)\n}\n","import { ThemeWithoutInheritance } from './types'\n\nexport const defaultTheme: ThemeWithoutInheritance = {\n background: 'transparent',\n text: {\n fontFamily: 'sans-serif',\n fontSize: 11,\n fill: '#333333',\n outlineWidth: 0,\n outlineColor: '#ffffff',\n outlineOpacity: 1,\n },\n axis: {\n domain: {\n line: {\n stroke: 'transparent',\n strokeWidth: 1,\n },\n },\n ticks: {\n line: {\n stroke: '#777777',\n strokeWidth: 1,\n },\n text: {},\n },\n legend: {\n text: {\n fontSize: 12,\n },\n },\n },\n grid: {\n line: {\n stroke: '#dddddd',\n strokeWidth: 1,\n },\n },\n legends: {\n hidden: {\n symbol: {\n fill: '#333333',\n opacity: 0.6,\n },\n text: {\n fill: '#333333',\n opacity: 0.6,\n },\n },\n text: {},\n ticks: {\n line: {\n stroke: '#777777',\n strokeWidth: 1,\n },\n text: {\n fontSize: 10,\n },\n },\n title: {\n text: {},\n },\n },\n labels: {\n text: {},\n },\n markers: {\n lineColor: '#000000',\n lineStrokeWidth: 1,\n text: {},\n },\n dots: {\n text: {},\n },\n tooltip: {\n container: {\n background: 'white',\n color: 'inherit',\n fontSize: 'inherit',\n borderRadius: '2px',\n boxShadow: '0 1px 2px rgba(0, 0, 0, 0.25)',\n padding: '5px 9px',\n },\n basic: {\n whiteSpace: 'pre',\n display: 'flex',\n alignItems: 'center',\n },\n chip: {\n marginRight: 7,\n },\n table: {},\n tableCell: {\n padding: '3px 5px',\n },\n tableCellValue: {\n fontWeight: 'bold',\n },\n },\n crosshair: {\n line: {\n stroke: '#000000',\n strokeWidth: 1,\n strokeOpacity: 0.75,\n strokeDasharray: '6 6',\n },\n },\n annotations: {\n text: {\n fontSize: 13,\n outlineWidth: 2,\n outlineColor: '#ffffff',\n outlineOpacity: 1,\n },\n link: {\n stroke: '#000000',\n strokeWidth: 1,\n outlineWidth: 2,\n outlineColor: '#ffffff',\n outlineOpacity: 1,\n },\n outline: {\n fill: 'none',\n stroke: '#000000',\n strokeWidth: 2,\n outlineWidth: 2,\n outlineColor: '#ffffff',\n outlineOpacity: 1,\n },\n symbol: {\n fill: '#000000',\n outlineWidth: 2,\n outlineColor: '#ffffff',\n outlineOpacity: 1,\n },\n },\n}\n","import { useMemo } from 'react'\nimport { extendDefaultTheme, extendAxisTheme } from './extend'\nimport { defaultTheme } from './defaults'\nimport { PartialTheme, Theme } from './types'\n\nexport const usePartialTheme = (partialTheme: PartialTheme) => {\n return useMemo(() => extendDefaultTheme(defaultTheme, partialTheme), [partialTheme])\n}\n\nexport const useExtendedAxisTheme = (axisTheme: Theme['axis'], overrides: PartialTheme['axis']) => {\n return useMemo(() => extendAxisTheme(axisTheme, overrides), [axisTheme, overrides])\n}\n","import { createContext, useContext, PropsWithChildren } from 'react'\nimport { usePartialTheme } from './hooks'\nimport { PartialTheme, Theme } from './types'\n\nexport const ThemeContext = createContext<Theme | null>(null)\n\n// required to preserve equality\nconst defaultPartialTheme = {}\n\nexport const ThemeProvider = ({\n theme: partialTheme = defaultPartialTheme,\n children,\n}: PropsWithChildren<{\n theme: PartialTheme\n}>) => {\n const theme = usePartialTheme(partialTheme)\n\n return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>\n}\n\nexport const useTheme = () => {\n const theme = useContext(ThemeContext)\n if (theme === null) {\n throw new Error(\n 'Unable to find the theme, did you forget to wrap your component with ThemeProvider?'\n )\n }\n\n return theme\n}\n"],"names":["normalizeBorderRadius","radius","_obj$topLeft","_obj$topRight","_obj$bottomRight","_obj$bottomLeft","topLeft","topRight","bottomRight","bottomLeft","obj","top","bottom","left","right","undefined","constrainBorderRadius","width","height","_normalizeBorderRadiu","topLeftConstrained","Math","max","topRightConstrained","bottomRightConstrained","bottomLeftConstrained","sumTop","scale","sumBottom","sumLeft","sumRight","svgStyleAttributesMapping","textAlign","start","center","end","textBaseline","cssStyleAttributesMapping","canvasStyleAttributesMapping","styleAttributesMapping","svg","css","canvas","convertStyleAttribute","engine","attr","value","sanitizeSvgTextStyle","style","outlineWidth","outlineColor","outlineOpacity","_objectWithoutPropertiesLoose","_excluded","sanitizeHtmlTextStyle","fill","_extends","_excluded2","color","borderRadiusToCss","_ref","textPropsWithInheritance","inheritRootThemeText","partialStyle","rootStyle","extendDefaultTheme","defaultTheme","customTheme","theme","merge","forEach","prop","set","get","text","extendAxisTheme","axisTheme","overrides","background","fontFamily","fontSize","axis","domain","line","stroke","strokeWidth","ticks","legend","grid","legends","hidden","symbol","opacity","title","labels","markers","lineColor","lineStrokeWidth","dots","tooltip","container","borderRadius","boxShadow","padding","basic","whiteSpace","display","alignItems","chip","marginRight","table","tableCell","tableCellValue","fontWeight","crosshair","strokeOpacity","strokeDasharray","annotations","link","outline","usePartialTheme","partialTheme","useMemo","useExtendedAxisTheme","ThemeContext","createContext","defaultPartialTheme","ThemeProvider","_ref$theme","children","_jsx","Provider","useTheme","useContext","Error"],"mappings":"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"}