Skip to content

Commit

Permalink
Merge branch 'snehilvj:master' into add-type-simplegrid
Browse files Browse the repository at this point in the history
  • Loading branch information
namakshenas authored Dec 3, 2024
2 parents 7398676 + 3124e27 commit 9c7206f
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 10 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
- Added `disabled` prop to `Radio` #425 by @namakshenas
- Added `type` prop to `SimpleGrid` #433 by @namakshenas

- Added the `add_figure_templates()` function which creates Mantine-styled Plotly figure templates for
both light and dark modes using the default Mantine theme. It registers the templates with plotly.io.templates as
"mantine_light" and "mantine_dark", and optionally sets one of the themes as a default. #431 by @AnnMarie

- Added various props: `acceptValueOnBlur` to `TagsInput`, `gradient` to `LineChart`, `hideWithOnePage` to `Pagination`, `name` to `Avatar`, and `disabled` to `NumberInput`. #440 by @AnnMarieW

- Added `SemiCircleProgress` component #434 by @AnnMarieW


### Fixed
- Fixed closing of Popovers when clicking outside. #423 by @magicmq

Expand Down
3 changes: 2 additions & 1 deletion dash_mantine_components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ._imports_ import *
from ._imports_ import __all__
from .theme import DEFAULT_THEME
from .figure_templates import add_figure_templates

if not hasattr(_dash, "__plotly_dash") and not hasattr(_dash, "development"):
print(
Expand Down Expand Up @@ -64,4 +65,4 @@
setattr(locals()[_component], "_css_dist", _css_dist)


__all__ += [DEFAULT_THEME, styles]
__all__ += [DEFAULT_THEME, styles, add_figure_templates]
112 changes: 112 additions & 0 deletions dash_mantine_components/figure_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from .theme import DEFAULT_THEME
import plotly.graph_objects as go
import plotly.io as pio
import copy


def add_figure_templates(default=None):

"""
Create and register Plotly figure templates styled to match the Mantine default theme.
This function generates two custom Plotly templates:
- "mantine_light" for light mode
- "mantine_dark" for dark mode
Templates are registered with `plotly.io.templates`, allowing you to apply them to Plotly figures
using the template names "mantine_light" or "mantine_dark". These templates include Mantine-inspired
color palettes, background colors, and other layout customizations.
Parameters:
- default (str): The default template to apply globally. Must be either "mantine_light" or "mantine_dark".
If not set, the default Plotly template remains unchanged.
Returns:
- None: The templates are registered and optionally set as the default, but no value is returned.
"""

colors = DEFAULT_THEME["colors"]
font_family = DEFAULT_THEME["fontFamily"]
# pallet generated from https://www.learnui.design/tools/data-color-picker.html#palette
custom_colorscale = [
"#1864ab", # blue[9]
"#7065b9",
"#af61b7",
"#e35ea5",
"#ff6587",
"#ff7c63",
"#ff9e3d",
"#fcc419", # yellow[5]
]

# Default theme configurations
default_themes = {
"light": {
"colorway": [
colors[color][6]
for color in ["blue", "red", "green", "violet", "orange", "cyan", "pink", "yellow"]
],
"paper_bgcolor": "#ffffff", # mantine background color
"plot_bgcolor": "#ffffff",
"gridcolor": "#dee2e6",
},
"dark": {
"colorway": [
colors[color][8]
for color in ["blue", "red", "green", "violet", "orange", "cyan", "pink", "yellow"]
],
"paper_bgcolor": colors["dark"][7], # mantine background color
"plot_bgcolor": colors["dark"][7],
"gridcolor": "#343a40",
}
}

def make_template(name):
#Start with either a light or dark Plotly template
base = "plotly_white" if name == "light" else "plotly_dark"
template = copy.deepcopy(pio.templates[base])

layout = template.layout
theme_config = default_themes[name]

# Apply theme settings
layout.colorway = theme_config["colorway"]
layout.colorscale.sequential = custom_colorscale
layout.piecolorway = theme_config["colorway"]
layout.paper_bgcolor = theme_config["paper_bgcolor"]
layout.plot_bgcolor = theme_config["plot_bgcolor"]
layout.font.family = font_family

# Grid settings
for axis in (layout.xaxis, layout.yaxis):
axis.gridcolor = theme_config["gridcolor"]
axis.gridwidth = 0.5
axis.zerolinecolor = theme_config["gridcolor"]

# Geo settings
layout.geo.bgcolor = theme_config["plot_bgcolor"]
layout.geo.lakecolor = theme_config["plot_bgcolor"]
layout.geo.landcolor = theme_config["plot_bgcolor"]

# Hover label settings
layout.hoverlabel.font.family = font_family

# Scatter plot settings
template.data.scatter = (go.Scatter(marker_line_color=theme_config["plot_bgcolor"]),)
template.data.scattergl = (go.Scattergl(marker_line_color=theme_config["plot_bgcolor"]),)

return template


# #register templates
pio.templates["mantine_light"] = make_template("light")
pio.templates["mantine_dark"] = make_template("dark")

# set the default
if default in ["mantine_light", "mantine_dark"]:
pio.templates.default = default
elif default:
raise ValueError(f"unrecognized {default=}, allowed values are 'mantine_light' and 'mantine_dark'")

return None
9 changes: 7 additions & 2 deletions src/ts/components/charts/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { LineChart as MantineLineChart } from "@mantine/charts";
import {
LineChartCurveType,
LineChartSeries,
LineChartGradientStop,
LineChartType,
} from "@mantine/charts/lib/LineChart/LineChart";
import { BoxProps } from "props/box";
import { GridChartBaseProps } from "props/charts";
Expand Down Expand Up @@ -52,10 +54,13 @@ interface Props
highlightHover?: boolean
/** Determines whether each point should have associated label, False by default */
withPointLabels?: boolean;

/** Data used to generate gradient stops, [{ offset: 0, color: 'red' }, { offset: 100, color: 'blue' }] by default */
gradientStops?: LineChartGradientStop[];
/** Controls styles of the line 'default' | 'gradient'. 'default' by default */
type?: LineChartType;
}

/** LineChart */
/** Mantine-themed line chart built on top of the Recharts library, */
const LineChart = (props: Props) => {
const { setProps, loading_state, clickData, hoverData, clickSeriesName, hoverSeriesName, series, highlightHover, lineChartProps, activeDotProps, lineProps, ...others } = props;

Expand Down
4 changes: 3 additions & 1 deletion src/ts/components/core/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ interface Props
radius?: MantineRadius;
/** Determines whether active item text color should depend on `background-color` of the indicator. If luminosity of the `color` prop is less than `theme.luminosityThreshold`, then `theme.white` will be used for text color, otherwise `theme.black`. Overrides `theme.autoContrast`. */
autoContrast?: boolean;
/** Determines whether the pagination should be hidden when only one page is available (total=1), False by default */
hideWithOnePage?: boolean;
}

/** Pagination */
/** Use the Pagination component to display active page and navigate between multiple pages */
const Pagination = (props: Props) => {
const {
setProps,
Expand Down
55 changes: 55 additions & 0 deletions src/ts/components/core/SemiCircleProgress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
MantineColor,
SemiCircleProgress as MantineSemiCircleProgess,
} from "@mantine/core";
import { BoxProps } from "props/box";
import { DashBaseProps } from "props/dash";
import { StylesApiProps } from "props/styles";
import React from "react";

interface Props extends BoxProps, StylesApiProps, DashBaseProps {
/** Progress value from `0` to `100` */
value: number;

/** Diameter of the svg in px, `200` by default */
size?: number;

/** Circle thickness in px, `12` by default */
thickness?: number;

/** Orientation of the circle, `'up'` by default */
orientation?: 'up' | 'down';

/** Direction from which the circle is filled, `'left-to-right'` by default */
fillDirection?: 'right-to-left' | 'left-to-right';

/** Key of `theme.colors` or any valid CSS color value, `theme.primaryColor` by default */
filledSegmentColor?: MantineColor;

/** Key of `theme.colors` or any valid CSS color value, by default the value is determined based on the color scheme value */
emptySegmentColor?: MantineColor;

/** Transition duration of filled section styles changes in ms, `0` by default */
transitionDuration?: number;

/** Label rendered inside the circle */
label?: React.ReactNode;

/** Label position relative to the circle center, `'bottom'` by default */
labelPosition?: 'center' | 'bottom';
}

/** Use to represent progress with semi circle diagram */
const SemiCircleProgress = (props: Props) => {
const { setProps, loading_state, ...others } = props;

return (
<MantineSemiCircleProgess
{...others}
/>
);
};

SemiCircleProgress.defaultProps = {};

export default SemiCircleProgress;
8 changes: 5 additions & 3 deletions src/ts/components/core/avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ interface Props extends BoxProps, StylesApiProps, DashBaseProps {
size?: MantineSize | (string & {}) | number;
/** Key of `theme.radius` or any valid CSS value to set border-radius, `'100%'` by default */
radius?: MantineRadius;
/** Key of `theme.colors` or any valid CSS color, default value is `theme.primaryColor` */
color?: MantineColor;
/** Key of `theme.colors` or any valid CSS color, default value is `theme.primaryColor`. Set to "initials" to auto generate color based on `name` */
color?: MantineColor | "initials";
/** Gradient configuration used when `variant="gradient"`, default value is `theme.defaultGradient` */
gradient?: MantineGradient;
/** Image url, if the image cannot be loaded or `src={null}`, then placeholder is displayed instead */
Expand All @@ -29,9 +29,11 @@ interface Props extends BoxProps, StylesApiProps, DashBaseProps {
children?: React.ReactNode;
/** Determines whether text color with filled variant should depend on `background-color`. If luminosity of the `color` prop is less than `theme.luminosityThreshold`, then `theme.white` will be used for text color, otherwise `theme.black`. Overrides `theme.autoContrast`. */
autoContrast?: boolean;
/** Name of the user. When src is not set, used to display initials and to generate color when color="initials" is set. */
name?: string;
}

/** Avatar */
/** Use the Avatar component to display user profile image, initials or fallback icon */
const Avatar = (props: Props) => {
const { children, setProps, loading_state, ...others } = props;

Expand Down
5 changes: 3 additions & 2 deletions src/ts/components/core/combobox/TagsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ interface Props
hiddenInputValuesDivider?: string;
/** Props passed down to the underlying `ScrollArea` component in the dropdown */
scrollAreaProps?: ScrollAreaProps;
/** Determines whether the value typed in by the user but not submitted should be accepted when the input is blurred, true by default */
acceptValueOnBlur?: boolean;
}

/** TagsInput */
/** TagsInput captures a list of values from user with free input and suggestions */
const TagsInput = (props: Props) => {
const { setProps, loading_state, data, searchValue, value, ...others } =
props;
Expand Down Expand Up @@ -80,7 +82,6 @@ const TagsInput = (props: Props) => {
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
wrapperProps={{ autoComplete: "off" }}
data={options}
onChange={setSelected}
value={selected}
Expand Down
5 changes: 4 additions & 1 deletion src/ts/components/core/input/NumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ interface Props
stepHoldDelay?: number;
/** (string; default "off") Enables the browser to attempt autocompletion based on user history. For more information, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete */
autoComplete?: string;
/** Sets disabled attribute on the input element */
disabled?: boolean;

}

/** NumberInput */
/** The NumberInput component allows users to input numeric values */
const NumberInput = (props: Props) => {
const {
setProps,
Expand Down
2 changes: 2 additions & 0 deletions src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ import ProgressSection from "./components/core/progress/ProgressSection";
import Radio from "./components/core/radio/Radio";
import RadioGroup from "./components/core/radio/RadioGroup";
import RangeSlider from "./components/core/slider/RangeSlider";
import SemiCircleProgress from "./components/core/SemiCircleProgress";
import Slider from "./components/core/slider/Slider";
import Stepper from "./components/core/stepper/Stepper";
import StepperCompleted from "./components/core/stepper/StepperCompleted";
Expand Down Expand Up @@ -264,6 +265,7 @@ export {
RangeSlider,
Rating,
RingProgress,
SemiCircleProgress,
ScatterChart,
ScrollArea,
SegmentedControl,
Expand Down

0 comments on commit 9c7206f

Please sign in to comment.