diff --git a/src/i18/en.ts b/src/i18/en.ts index 2e41726..776e43f 100644 --- a/src/i18/en.ts +++ b/src/i18/en.ts @@ -76,6 +76,8 @@ export class En implements Local { form_number_input_min_warning = "allow min value is {value}"; form_number_input_max_warning = "allow max value is {value}"; form_fill_the_screen_label = "Fill The Screen"; + form_main_container_bg_color = "Background Color"; + form_enable_main_container_shadow = "Enable Shadow"; form_show_cell_indicators = "Show Cell Indicators"; form_cell_shape = "Cell Shape"; form_cell_shape_circle = "Circle"; diff --git a/src/i18/types.ts b/src/i18/types.ts index 63b5af4..e2b0f8f 100644 --- a/src/i18/types.ts +++ b/src/i18/types.ts @@ -73,6 +73,8 @@ export interface Local { form_number_input_min_warning: string; form_number_input_max_warning: string; form_fill_the_screen_label: string; + form_main_container_bg_color: string; + form_enable_main_container_shadow: string; form_show_cell_indicators: string; form_cell_shape: string; form_cell_shape_circle: string; diff --git a/src/i18/zh.ts b/src/i18/zh.ts index 2303290..5245ad3 100644 --- a/src/i18/zh.ts +++ b/src/i18/zh.ts @@ -75,6 +75,8 @@ export class Zh implements Local { form_number_input_min_warning = "允许的最小值为 {value}"; form_number_input_max_warning = "允许的最大值为 {value}"; form_fill_the_screen_label = "充满屏幕"; + form_main_container_bg_color = "背景颜色"; + form_enable_main_container_shadow = "启用阴影"; form_show_cell_indicators = "显示单元格指示器"; form_cell_shape = "单元格形状"; form_cell_shape_circle = "圆形"; diff --git a/src/processor/types.ts b/src/processor/types.ts index 2357a8c..7d9fc39 100644 --- a/src/processor/types.ts +++ b/src/processor/types.ts @@ -21,8 +21,10 @@ import { } from "src/util/dateUtils"; export class YamlGraphConfig { + /** + * basic settings + */ title?: string; - titleStyle: Partial; graphType: string; dataSource: DataSource; dateRangeValue?: number; @@ -30,11 +32,18 @@ export class YamlGraphConfig { fromDate?: string; toDate?: string; data: Contribution[]; + + /** + * style settings + */ + titleStyle: Partial; + fillTheScreen: boolean; startOfWeek: number; + enableMainContainerShadow?: boolean; + showCellRuleIndicators: boolean; + mainContainerStyle?: Partial; cellStyle?: Partial; cellStyleRules?: CellStyleRule[]; - showCellRuleIndicators: boolean; - fillTheScreen: boolean; // deprecated days?: number; @@ -60,6 +69,7 @@ export class YamlGraphConfig { dateField: {}, } as DataSource; this.fillTheScreen = false; + this.enableMainContainerShadow = false; // deprecated this.query = undefined; @@ -73,7 +83,7 @@ export class YamlGraphConfig { ): ContributionGraphConfig { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { query, dateField, ...rest } = config; - + if (config.dateRangeType != "FIXED_DATE_RANGE") { if (config.dateRangeType == "LATEST_DAYS") { return { diff --git a/src/render/calendarGraphRender.ts b/src/render/calendarGraphRender.ts index 2e15591..af6bf80 100644 --- a/src/render/calendarGraphRender.ts +++ b/src/render/calendarGraphRender.ts @@ -23,16 +23,10 @@ export class CalendarGraphRender extends BaseGraphRender { } render(root: HTMLElement, graphConfig: ContributionGraphConfig): void { - const graphEl = createDiv({ - cls: "contribution-graph", - parent: root, - }); + const graphEl = this.createGraphEl(root) // main - const main = createDiv({ - cls: "main", - parent: graphEl, - }); + const main = this.createMainEl(graphEl, graphConfig) // title if (graphConfig.title && graphConfig.title.trim() != "") { diff --git a/src/render/gitStyleTrackGraphRender.ts b/src/render/gitStyleTrackGraphRender.ts index a242629..224bfaa 100644 --- a/src/render/gitStyleTrackGraphRender.ts +++ b/src/render/gitStyleTrackGraphRender.ts @@ -17,16 +17,10 @@ export class GitStyleTrackGraphRender extends BaseGraphRender { } render(root: HTMLElement, graphConfig: ContributionGraphConfig): void { - const graphEl = createDiv({ - cls: "contribution-graph", - parent: root, - }); + const graphEl = this.createGraphEl(root) // main - const main = createDiv({ - cls: `main ${graphConfig.fillTheScreen ? "fill-the-screen" : ""}`, - parent: graphEl, - }); + const main = this.createMainEl(graphEl, graphConfig) // title if (graphConfig.title && graphConfig.title.trim() != "") { diff --git a/src/render/graphRender.ts b/src/render/graphRender.ts index 19431b1..a04d120 100644 --- a/src/render/graphRender.ts +++ b/src/render/graphRender.ts @@ -30,6 +30,31 @@ export abstract class BaseGraphRender implements GraphRender { abstract graphType(): string; + createGraphEl(root: HTMLElement): HTMLDivElement { + return createDiv({ + cls: "contribution-graph", + parent: root, + }); + } + + createMainEl( + parent: HTMLElement, + graphConfig: ContributionGraphConfig + ): HTMLDivElement { + let cls = "main"; + if (graphConfig.fillTheScreen && this.graphType() != "calendar") { + cls = `main ${graphConfig.fillTheScreen ? "fill-the-screen" : ""}`; + } + const main = createDiv({ + cls: cls, + parent: parent, + }); + if (graphConfig.mainContainerStyle) { + Object.assign(main.style, graphConfig.mainContainerStyle); + } + return main; + } + renderTitle( graphConfig: ContributionGraphConfig, parent: HTMLElement @@ -106,22 +131,22 @@ export abstract class BaseGraphRender implements GraphRender { const closeButton = createEl("button", { cls: "close-button", - text: 'x', + text: "x", parent: contaienr, - }) + }); closeButton.onclick = () => { contaienr.empty(); - } + }; let summary; if (cellData.value > 0) { - summary = Locals.get().you_have_contributed_to - .replace("{date}", cellData.date) + summary = Locals.get() + .you_have_contributed_to.replace("{date}", cellData.date) .replace("{value}", cellData.value.toString()); } else { - summary = Locals.get().you_have_no_contributions_on - .replace("{date}", cellData.date) + summary = Locals.get() + .you_have_no_contributions_on.replace("{date}", cellData.date) .replace("{value}", "0"); } createDiv({ @@ -237,7 +262,6 @@ export abstract class BaseGraphRender implements GraphRender { cellEl.style.backgroundColor = defaultRule.color; cellEl.innerText = defaultRule.text || ""; } - } bindCellAttribute( diff --git a/src/render/monthTrackGraphRender.ts b/src/render/monthTrackGraphRender.ts index ae33df1..578e228 100644 --- a/src/render/monthTrackGraphRender.ts +++ b/src/render/monthTrackGraphRender.ts @@ -16,16 +16,10 @@ export class MonthTrackGraphRender extends BaseGraphRender { } render(root: HTMLElement, graphConfig: ContributionGraphConfig): void { - const graphEl = createDiv({ - cls: "contribution-graph", - parent: root, - }); + const graphEl = this.createGraphEl(root) // main - const main = createDiv({ - cls: `main ${graphConfig.fillTheScreen ? "fill-the-screen" : ""}`, - parent: graphEl, - }); + const main = this.createMainEl(graphEl, graphConfig) // title if (graphConfig.title && graphConfig.title.trim() != "") { diff --git a/src/types.ts b/src/types.ts index 9fd1bcb..de2b3c6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,6 +11,11 @@ export class ContributionGraphConfig { */ titleStyle: Partial = {}; + /** + * the style of the main container + */ + mainContainerStyle: Partial = {}; + /** * recent days to show */ diff --git a/src/view/form/CellRuleFormItem.tsx b/src/view/form/CellRuleFormItem.tsx index b7b0a45..69f9456 100644 --- a/src/view/form/CellRuleFormItem.tsx +++ b/src/view/form/CellRuleFormItem.tsx @@ -64,12 +64,6 @@ export function CellRuleItem(props: { onChange={(e) => changeRule("max", e.target.value)} /> = - {/* changeRule("color", e.target.value)} - /> */} void; +}): JSX.Element { + const [showColorPicker, setShowColorPicker] = useState(false); + const { refs, floatingStyles, context } = useFloating({ + open: showColorPicker, + onOpenChange: (open) => setShowColorPicker(open), + middleware: [offset(6), flip(), shift(), inline()], + whileElementsMounted: autoUpdate, + }); + + const dismiss = useDismiss(context); + const { getFloatingProps } = useInteractions([dismiss]); + + return ( + <> + setShowColorPicker(!showColorPicker)} + > + {showColorPicker ? ( +
+ { + props.onChange(color.hexa); + }} + /> +
+ ) : null} + + ); +} diff --git a/src/view/form/GraphForm.tsx b/src/view/form/GraphForm.tsx index 4af2314..d8e6ddd 100644 --- a/src/view/form/GraphForm.tsx +++ b/src/view/form/GraphForm.tsx @@ -18,6 +18,7 @@ import { DataSourceFormItem } from "./DataSourceFormItem"; import { DateRangeType, YamlGraphConfig } from "src/processor/types"; import { Tab } from "../tab/Tab"; import NumberInput from "../number-input"; +import { ColorPicker } from "./ColorPicker"; export function CreateContributionGraphForm(props: { yamlConfig: YamlGraphConfig; @@ -406,6 +407,71 @@ export function CreateContributionGraphForm(props: { )} + +
+ + {local.form_main_container_bg_color} + +
+ { + changeFormData( + "mainContainerStyle", + { + ...formData.mainContainerStyle, + backgroundColor: + color, + } + ); + }} + /> +
+
+ +
+ + { + local.form_enable_main_container_shadow + } + +
+ { + if (e.target.checked) { + changeFormData( + "mainContainerStyle", + { + ...formData.mainContainerStyle, + boxShadow: + "rgba(0, 0, 0, 0.16) 0px 1px 4px", + } + ); + } else { + changeFormData( + "mainContainerStyle", + { + ...formData.mainContainerStyle, + boxShadow: + undefined, + } + ); + } + }} + /> +
+
+
{local.form_show_cell_indicators} diff --git a/styles.css b/styles.css index 60b72ea..9365436 100644 --- a/styles.css +++ b/styles.css @@ -2,6 +2,7 @@ margin-bottom: 6px; position: relative; width: 100%; + padding: 2px; } .contribution-graph .center { @@ -10,11 +11,11 @@ } .contribution-graph .main { - padding: 2px; line-height: normal; display: grid; margin-top: 26px; justify-content: center; + border-radius: 8px; } .contribution-graph .main.fill-the-screen { @@ -806,7 +807,6 @@ flex-wrap: wrap; gap: 0.6rem; padding: 0.4rem; - margin-top: 1rem; position: relative; }