Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

components: Add tailwind provider, better types #53

Merged
merged 3 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/components/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Preview } from "@storybook/react";
import React from "react";
import "../src/main.css";
import ThemeWrapper from "../src/tailwind/Wrapper";
import ThemeProvider from "../src/tailwind/context";

const preview: Preview = {
parameters: {
Expand All @@ -15,9 +15,9 @@ const preview: Preview = {
},
decorators: [
Story => (
<ThemeWrapper>
<ThemeProvider>
<Story />
</ThemeWrapper>
</ThemeProvider>
),
],
};
Expand Down
2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@dolthub/react-components",
"author": "DoltHub",
"description": "A collection of React components for common tasks",
"version": "0.1.4",
"version": "0.1.5",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/index.d.ts",
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/Textarea/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@

.mobileFriendly {
@media (max-width: 640px) {
@apply border-t border-ld-lightgrey p-4 bg-white;
@apply border-t border-ld-lightgrey px-4 pt-3 mb-0 pb-4 bg-white;

&:focus-within {
@apply bg-ld-lightpurple;
}
}
}

Expand Down Expand Up @@ -42,7 +46,7 @@
@apply px-0 py-1 bg-white text-primary border-none;

&:focus {
@apply bg-white outline outline-blue-300;
@apply bg-ld-lightpurple;
}

&:disabled {
Expand Down
6 changes: 3 additions & 3 deletions packages/components/src/Textarea/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cx from "classnames";
import React, { forwardRef } from "react";
import React, { ForwardedRef, forwardRef } from "react";
import css from "./index.module.css";

type Props = {
Expand Down Expand Up @@ -30,7 +30,7 @@ const Textarea = (
mobileFriendly = false,
...textAreaProps
}: Props,
ref: any,
ref: ForwardedRef<HTMLTextAreaElement>,
) => (
<div
className={cx(
Expand Down Expand Up @@ -58,7 +58,7 @@ const Textarea = (
onChangeString ? onChangeString(e.target.value) : onChange?.(e)
}
ref={ref}
aria-label={textAreaProps["aria-label"] || "textarea"}
aria-label={textAreaProps["aria-label"] ?? "textarea"}
/>
</div>
);
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ export { default as Popup, PopupProps } from "./Popup";
export { default as SmallLoader } from "./SmallLoader";
export { default as SuccessMsg } from "./SuccessMsg";
export { default as Textarea } from "./Textarea";
export { default as applyTailwindTheme } from "./tailwind/applyTheme";
export { ITheme } from "./tailwind/applyTheme/types";
export { default as ThemeProvider, useThemeContext } from "./tailwind/context";
export { mergeConfig } from "./tailwind/mergeConfig";
export { colors as dolthubColors } from "./tailwind/theme/dolthub/colors";
export {
colors as hostedColors,
tailwindColorTheme as hostedTailwindColorTheme,
} from "./tailwind/theme/hosted/colors";
export {
colors as workbenchColors,
tailwindColorTheme as workbenchTailwindColorTheme,
} from "./tailwind/theme/workbench/colors";
export { IThemeColors, IThemeRGB } from "./tailwind/types";
14 changes: 0 additions & 14 deletions packages/components/src/tailwind/Wrapper.tsx

This file was deleted.

50 changes: 0 additions & 50 deletions packages/components/src/tailwind/applyTheme/index.ts

This file was deleted.

11 changes: 0 additions & 11 deletions packages/components/src/tailwind/applyTheme/types.ts

This file was deleted.

38 changes: 38 additions & 0 deletions packages/components/src/tailwind/context/applyTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { IThemeRGB, IThemeVariables } from "../types";

// Should be used to apply the theme to the root element of the app. Will use
// base colors in `theme/base/colors.ts` if no overrides are provided.
export default function applyTheme(themeRGB: IThemeRGB) {
const themeObject: IThemeVariables = mapTheme(themeRGB);
const root = document.documentElement;

Object.keys(themeObject).forEach(v => {
const propertyVal = themeObject[v as keyof IThemeVariables];
const validation = validateRGB(propertyVal);
if (!validation) {
throw new Error(`Invalid RGB value for ${v}: ${propertyVal}`);
}

root.style.setProperty(v, propertyVal);
});
}

function mapTheme(rgb: IThemeRGB): IThemeVariables {
return {
"--color-primary": rgb["rgb-primary"] ?? "",
"--color-acc-1": rgb["rgb-acc-1"] ?? "",
"--color-background-acc-1": rgb["rgb-background-acc-1"] ?? "",
"--color-background-acc-start": rgb["rgb-background-acc-start"] ?? "",
"--color-button-1": rgb["rgb-button-1"] ?? "",
"--color-link-1": rgb["rgb-link-1"] ?? "",
"--color-button-2": rgb["rgb-button-2"] ?? "",
"--color-link-2": rgb["rgb-link-2"] ?? "",
"--color-link-light": rgb["rgb-link-light"] ?? "",
};
}

function validateRGB(rgb: string): boolean {
if (!rgb) return true;
const rgbRegex = /^(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})$/;
return rgbRegex.test(rgb);
}
58 changes: 58 additions & 0 deletions packages/components/src/tailwind/context/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { createContext, useContext, useEffect } from "react";
import { baseColorVariableValues } from "../theme/base/colors";
import { IThemeColors, IThemeRGB } from "../types";
import applyTheme from "./applyTheme";
import { rgbToHex } from "./utils";

type Props = {
children: React.ReactNode;
themeRGBOverrides?: IThemeRGB;
};

type ThemeContextType = {
themeRGB: IThemeRGB;
convertThemeRGBToHex: () => IThemeColors;
};

const ThemeContext = createContext<ThemeContextType>({
themeRGB: baseColorVariableValues,
convertThemeRGBToHex: () => {
return {};
},
});

// ThemedProvider applies tailwind theme default, potentially with provided
// overrides. Must wrap your app root in this provider to use this library.
export default function ThemeProvider(props: Props) {
const themeRGB: IThemeRGB = {
...baseColorVariableValues,
...(props.themeRGBOverrides ?? {}),
};

useEffect(() => {
applyTheme(themeRGB);
}, []);

// Converts the theme from RGB to Hex
function convertThemeRGBToHex(): IThemeColors {
const hexThemeRGB: IThemeColors = {};
Object.keys(themeRGB).forEach(key => {
const rgb = themeRGB[key as keyof IThemeRGB];
if (rgb) {
const color = key.replace("rgb-", "");
hexThemeRGB[color as keyof IThemeColors] = rgbToHex(rgb);
}
});
return hexThemeRGB;
}

return (
<ThemeContext.Provider value={{ themeRGB, convertThemeRGBToHex }}>
{props.children}
</ThemeContext.Provider>
);
}

export function useThemeContext(): ThemeContextType {
return useContext(ThemeContext);
}
9 changes: 9 additions & 0 deletions packages/components/src/tailwind/context/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function rgbToHex(rgb: string): string {
const [r, g, b] = rgb.split(", ").map(Number);
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
}

function componentToHex(c: number): string {
const hex = c.toString(16);
return hex.length === 1 ? `0${hex}` : hex;
}
40 changes: 21 additions & 19 deletions packages/components/src/tailwind/theme/base/colors.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
import { IThemeColors, IThemeRGB } from "../../types";

// TODO: Improve these names
const staticColors = {
"acc-grey": "#b2c0c4",
"acc-red": "#ff9a99",
"acc-green": "#5ac58d",
"acc-lightgrey": "#c6cdd0",
"ld-darkgrey": "#95a3a7",
"ld-lightgrey": "#e1e5e7",
"ld-lightpurple": "#f1f3f8",
"ld-lightblue": "#f6f8f9",
"ld-darkergrey": "#384B52",
"ld-blue": "#6db0fc",
"ld-darkerblue": "#1e2842",
"ld-darkergrey": "#384B52",
"ld-darkestblue": "#182134",
"ld-blue": "#6db0fc",
"ld-darkgrey": "#95a3a7",
"ld-green": "#5deda2",
"acc-linkblue": "#1f6dc6",
"acc-hoverlinkblue": "#3d91f0",
"acc-hoverblue": "#1d2c7f",
"ld-lightblue": "#f6f8f9",
"ld-lightgrey": "#e1e5e7",
"ld-lightpurple": "#f1f3f8",

"acc-bright-green": "#29e3c1",
"acc-code": "#575662",
"acc-darkgrey": "#5d6280",
"acc-green": "#5ac58d",
"acc-grey": "#b2c0c4",
"acc-hoverblue": "#1d2c7f",
"acc-hovergreen": "#6fdda4",
"acc-lightgreen": "#d4f5e4",
"acc-hoverlinkblue": "#3d91f0",
"acc-hoverred": "#fca8a7",
"acc-code": "#575662",
"acc-lightgreen": "#d4f5e4",
"acc-lightgrey": "#c6cdd0",
"acc-linkblue": "#1f6dc6",
"acc-orange": "#ed8936",
"acc-pink": "#d588d5",
"acc-bright-green": "#29e3c1",
"acc-purple": "#805EDD",
"acc-red": "#ff9a99",
};

const configurableColors = {
const configurableColors: IThemeColors = {
primary: withOpacity("--color-primary"),
"acc-1": withOpacity("--color-acc-1"),
"background-acc-1": withOpacity("--color-background-acc-1"),
Expand All @@ -46,7 +49,7 @@ export default colors;

// Can override these values by passing this object with different values to
// `applyTheme`
export const baseColorVariableValues = {
export const baseColorVariableValues: IThemeRGB = {
"rgb-primary": "1, 10, 64",
"rgb-acc-1": "252, 66, 201",
"rgb-background-acc-1": "24, 33, 52",
Expand All @@ -60,7 +63,6 @@ export const baseColorVariableValues = {

// Reference for using CSS variables in Tailwind:
// https://tailwindcss.com/docs/customizing-colors#using-css-variables

function withOpacity(variableName: string): string {
return `rgba(var(${variableName}), <alpha-value>)`;
}
4 changes: 2 additions & 2 deletions packages/components/src/tailwind/theme/dolthub/colors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export const colors = {
"ld-pink": "#fc42c9",
"ld-darkblue": "#010a40",
"ld-pink": "#fc42c9",

"acc-altlightgreen": "#defbe4",
"acc-lightred": "#ffeaec",
"acc-darkblue": "#183362",
"acc-light-text": "#999db3",
"acc-lightred": "#ffeaec",
};
10 changes: 6 additions & 4 deletions packages/components/src/tailwind/theme/hosted/colors.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { IThemeRGB } from "../../types";

export const colors = {
"ld-darkblue": "#183362",
"ld-mediumblue": "#2b5db6",
"ld-bluegrey": "#284f94",
"ld-grey": "#f2f5fb",
"ld-brightgreen": "#29e3c1",
"ld-darkblue": "#183362",
"ld-grey": "#f2f5fb",
"ld-mediumblue": "#2b5db6",
"ld-orange": "#ff820f",
};

export const tailwindColorTheme = {
export const tailwindColorTheme: IThemeRGB = {
"rgb-primary": "24, 51, 98", // ld-darkblue
"rgb-acc-1": "237, 137, 54", // ld-orange
"rgb-background-acc-1": "43, 93, 182", // ld-mediumblue
Expand Down
Loading
Loading