Skip to content

Commit 437188e

Browse files
v1.3.0-beta
1 parent 9830f46 commit 437188e

16 files changed

+177
-63
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ dist-ssr
2626
site
2727
todo_*
2828
tempCodeRunnerFile.*
29+
*.tgz

.npmignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ tsconfig.json
66
.gitignore
77
site
88
tailwind.config.js
9-
*.py
9+
*.py
10+
*.tgz
11+
screenshots
12+
tempCodeRunnerFile.*
13+
.release-it.json

package-lock.json

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "shadcn-theme-editor",
3-
"version": "1.3.0-alpha.2",
3+
"version": "1.3.0-beta",
44
"description": "Shadcn Theme Editor",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
@@ -14,7 +14,7 @@
1414
},
1515
"homepage": "https://github.com/programming-with-ia/shadcn-theme-editor#readme",
1616
"scripts": {
17-
"build": "rollup -c --bundleConfigAsCjs && python ./update-css-file.py && npm link",
17+
"build": "rollup -c --bundleConfigAsCjs && python ./update-css-file.py && npm link && npm pack",
1818
"test": "echo \"Error: no test specified\" && exit 1",
1919
"release": "release-it"
2020
},
@@ -62,6 +62,7 @@
6262
"class-variance-authority": "^0.7.0",
6363
"clsx": "^2.1.1",
6464
"colord": "^2.9.3",
65+
"emittor": "^0.1.0",
6566
"lodash.debounce": "^4.0.8",
6667
"zod": "^3.23.8"
6768
}

src/components/SideBarColors.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { getColors, ls, resetTheme, setColorsProperties } from "../lib/utils";
22
import React, { useEffect, useState } from "react";
33
import { Item } from "./item";
4-
import { ReadonlyThemeWithHSLColor } from "../lib/theme";
4+
import { ThemeWithHSLColor } from "../lib/theme";
55
import { useTheme } from "next-themes";
66
import { useDebounceCallback } from "../hooks/useDebounceCallback";
77
import z from "zod";
88
import { LOCAL_STORAGE_KEY } from "../lib/consts";
9+
import { useEmittor } from "emittor";
10+
import { themeEmittor } from "../lib/emittors";
911

1012
function print(...props: any) {
11-
if ((window as any).shadcnThemeEditorDebugMode) {
13+
if (typeof window !== "undefined" && (window as any).shadcnThemeEditorDebugMode) {
1214
console.log(...props);
1315
}
1416
}
@@ -34,38 +36,39 @@ function SideBarColors() {
3436
setCurrentTheme(resolvedTheme);
3537
}, [resolvedTheme]);
3638

37-
const [colors, setColors] = useState<
38-
ReadonlyThemeWithHSLColor[] | undefined
39-
>();
40-
// console.log("Current Theme is: ", currentTheme);
39+
const [colors, setColors] = useEmittor(themeEmittor.e);
4140
const saveLocalStorage = useDebounceCallback(() => {
4241
print("Saving the theme to local storage");
4342
ls.setLocalStorage(LOCAL_STORAGE_KEY + ":" + currentTheme, getColors(true));
4443
}, 2000);
4544

4645
useEffect(() => {
47-
resetTheme();
46+
// resetTheme();
4847
print("reading theme", LOCAL_STORAGE_KEY + ":" + currentTheme);
49-
let theme = ls.getLocalStorageItem<ReadonlyThemeWithHSLColor[]>(
48+
let theme = ls.getLocalStorageItem<ThemeWithHSLColor[]>(
5049
LOCAL_STORAGE_KEY + ":" + currentTheme
5150
);
5251
if (theme) {
5352
try {
5453
const isValid = ZodTheme.parse(theme);
5554
print("theme is valid and appling", isValid);
5655
print("applied theme", theme);
57-
setColorsProperties(theme);
58-
setColors(theme);
56+
themeEmittor.applyTheme(theme)
57+
// setColorsProperties(theme);
58+
// setColors(theme);
5959
return;
6060
} catch (error) {
6161
print("invalid theme found in localStorage");
6262
// localStorage.removeItem(LOCAL_STORAGE_KEY+":"+currentTheme); //* remove key
6363
}
6464
}
65-
theme = getColors(true) as any;
65+
// resetTheme()
66+
// theme = getColors(true) as any;
67+
// theme = getDefaultTheme()
6668
print("theme not found in localStorage");
6769
print("Now theme: ", theme);
68-
setColors(theme as any);
70+
// setColors(theme as any);
71+
themeEmittor.setDefaultTheme()
6972
}, [currentTheme]);
7073
return (
7174
<>

src/components/item.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReadonlyThemeWithHSLColor } from "../lib/theme";
1+
import { ThemeWithHSLColor } from "../lib/theme";
22
import React, { useEffect, useState } from "react";
33
import { Button } from "./ui/button";
44
import { copy2clipboard, HSL2ComputedColor, setStyleColor } from "../lib/utils";
@@ -9,7 +9,7 @@ export function Item({
99
theme,
1010
onSave,
1111
}: {
12-
theme: ReadonlyThemeWithHSLColor;
12+
theme: ThemeWithHSLColor;
1313
onSave: () => void;
1414
}) {
1515
const [color, setColor] = useState<string>("#000");

src/components/random.tsx

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,76 @@
1-
import React, { useState } from 'react'
2-
import { Button } from './ui/button'
3-
import { createRandomTheme } from '../lib/create-theme-config'
4-
import { useTheme } from 'next-themes'
5-
import { getComputedHSLColor, saveTheme, setColorsProperties } from '../lib/utils'
6-
import { Dices, Lock, UnLock } from './icons';
7-
import { ReadonlyThemeWithHSLColor, SystemThemes, themeModes } from '../lib/theme'
1+
import React, { useEffect, useState } from "react";
2+
import { Button } from "./ui/button";
3+
import { createRandomTheme } from "../lib/create-theme-config";
4+
import { useTheme } from "next-themes";
5+
import {
6+
getComputedHSLColor,
7+
saveTheme,
8+
setColorsProperties,
9+
} from "../lib/utils";
10+
import { Dices, Lock, UnLock } from "./icons";
11+
import {
12+
SystemThemes,
13+
themeModes,
14+
ThemeWithHSLColor,
15+
} from "../lib/theme";
16+
import { themeEmittor } from "../lib/emittors";
817

918
function RandomBtn() {
10-
const { resolvedTheme=""+undefined, systemTheme="dark" } = useTheme();
11-
const [lockPrimary, setLockPrimary] = useState(true);
12-
const onClickHandler = ()=>{
13-
const themes = createRandomTheme(lockPrimary ? getComputedHSLColor("--primary"): undefined)
14-
let theme;
19+
const {
20+
resolvedTheme: NresolvedTheme = "" + undefined,
21+
systemTheme: NsystemTheme = "dark",
22+
} = useTheme();
23+
const [resolvedTheme, setResolvedTheme] = useState<string>();
24+
const [systemTheme, setSystemTheme] = useState<string>();
25+
useEffect(() => {
26+
setResolvedTheme(NresolvedTheme);
27+
setSystemTheme(NsystemTheme);
28+
}, [NresolvedTheme, NsystemTheme]);
29+
const [lockPrimary, setLockPrimary] = useState(true);
30+
const onClickHandler = () => {
31+
const themes = createRandomTheme(
32+
lockPrimary ? getComputedHSLColor("--primary") : undefined
33+
);
34+
let theme;
1535

16-
if (SystemThemes.includes(resolvedTheme as any)){
17-
theme = themes[resolvedTheme as themeModes] as ReadonlyThemeWithHSLColor[];
18-
SystemThemes.forEach(theme=> saveTheme(resolvedTheme, themes[theme])) // save both themes
19-
} else {
20-
theme = themes[systemTheme] as ReadonlyThemeWithHSLColor[];
21-
saveTheme(resolvedTheme, theme)
22-
}
23-
setColorsProperties(theme)
36+
if (SystemThemes.includes(resolvedTheme as any)) {
37+
theme = themes[
38+
resolvedTheme as themeModes
39+
] as ThemeWithHSLColor[];
40+
SystemThemes.forEach((theme) => saveTheme(theme, themes[theme])); // save both themes
41+
} else {
42+
theme = themes[systemTheme as themeModes] as ThemeWithHSLColor[];
43+
saveTheme(resolvedTheme, theme);
2444
}
25-
const LockIcon = lockPrimary? Lock: UnLock
45+
themeEmittor.applyTheme(theme)
46+
// themeEmittor.e.setState(theme)
47+
// setColorsProperties(theme);
48+
};
49+
const LockIcon = lockPrimary ? Lock : UnLock;
2650
return (
27-
<Button onClick={onClickHandler} title={'Generate Random theme, Primary is '+(lockPrimary? "locked": "not locked")} variant={"colorbtn"} className='cursor-pointer'>
28-
<Dices className='size-5' /> Randomize <LockIcon onClick={(e)=>console.log(setLockPrimary(!lockPrimary), lockPrimary, e.stopPropagation())} aria-label={(lockPrimary ?'unlock' : 'lock')+ ' primary color'} className='ml-auto size-6 hover:opacity-80 rounded-md hover:bg-background hover:fill-foreground p-0.5 fill-current'/>
51+
<Button
52+
onClick={onClickHandler}
53+
title={
54+
"Generate Random theme, Primary is " +
55+
(lockPrimary ? "locked" : "not locked")
56+
}
57+
variant={"colorbtn"}
58+
className="cursor-pointer"
59+
>
60+
<Dices className="size-5" /> Randomize{" "}
61+
<LockIcon
62+
onClick={(e) =>
63+
console.log(
64+
setLockPrimary(!lockPrimary),
65+
lockPrimary,
66+
e.stopPropagation()
67+
)
68+
}
69+
aria-label={(lockPrimary ? "unlock" : "lock") + " primary color"}
70+
className="ml-auto size-6 hover:opacity-80 rounded-md hover:bg-background hover:fill-foreground p-0.5 fill-current"
71+
/>
2972
</Button>
30-
)
73+
);
3174
}
3275

33-
export default RandomBtn
76+
export default RandomBtn;

src/components/reset-theme.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { Button } from "./ui/button";
22
import { LOCAL_STORAGE_KEY } from "../lib/consts";
33
import { useTheme } from "next-themes";
44
import { ResetIcon } from "./icons";
5+
import { ls } from "../lib/utils";
6+
import { themeEmittor } from "../lib/emittors";
57

68
export function ResetTheme() {
79
const { resolvedTheme: currentTheme } = useTheme();
@@ -10,10 +12,13 @@ export function ResetTheme() {
1012
title="Reset to the default theme"
1113
variant={"toolbtn"}
1214
size="toolbtn"
13-
onClick={() => (
14-
localStorage.removeItem(LOCAL_STORAGE_KEY + ":" + currentTheme),
15+
onClick={(e) => (
16+
e.ctrlKey
17+
? ls.deleteAllThemes()
18+
: localStorage.removeItem(LOCAL_STORAGE_KEY + ":" + currentTheme),
1519
// resetTheme(),
16-
window.location.reload()
20+
themeEmittor.setDefaultTheme()
21+
// window.location.reload()
1722
)}
1823
>
1924
<ResetIcon />

src/components/sidebar-section.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
import React from "react";
2-
import { CompoProps } from "../../app/src/types/types";
32
import { cn } from "../lib/utils";
43

54
function Header({
65
children,
76
label,
7+
href
88
}: {
99
children?: React.ReactNode;
1010
label: string;
11+
href?: string;
1112
}) {
13+
const Comp = href ? "a": "div"
1214
return (
13-
<div
15+
<Comp
16+
href={href}
17+
target={href? "_blank": undefined}
1418
className={cn(
15-
"mb-1 flex items-center justify-between pl-2 py-1 text-sm font-semibold gap-2"
19+
"mb-1 mt-2 flex items-center justify-between pl-2 py-1 text-sm font-semibold gap-2",
20+
href && "hover:underline underline-offset-1"
1621
)}
1722
>
1823
{label} {children}
19-
</div>
24+
</Comp>
2025
);
2126
}
2227

@@ -34,7 +39,7 @@ function Section({
3439

3540
const SidebarSection = {
3641
Header,
37-
Root: Section,
42+
Body: Section,
3843
Seperator() {
3944
return <hr className="my-2" />;
4045
},

src/components/sidebar.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function Sidebar({ isOpen }: { isOpen: boolean }) {
1515
isOpen && "md:flex flex-col"
1616
)}
1717
>
18-
<div className="mb-1 flex items-center px-2 py-1 font-semibold">
18+
<div className="flex items-center px-2 py-1 font-semibold">
1919
Shadcn Theme Editor
2020
</div>
2121
<SidebarSection.Header label="Theming">
@@ -25,11 +25,14 @@ export function Sidebar({ isOpen }: { isOpen: boolean }) {
2525
</div>
2626
</SidebarSection.Header>
2727

28-
<div className="text-sm flex flex-col flex-1">
28+
<SidebarSection.Body className="flex-1">
2929
<SideBarColors />
30-
<hr className="my-2" />
30+
</SidebarSection.Body>
31+
{/* <SidebarSection.Seperator /> */}
32+
<SidebarSection.Header label="ui.jln.dev" href="https://ui.jln.dev/" />
33+
<SidebarSection.Body>
3134
<RandomBtn />
32-
</div>
35+
</SidebarSection.Body>
3336
<footer className="flex flex-col gap-2 text-sm pt-4 mt-2 border-t -mb-4">
3437
<div className="flex flex-wrap justify-between gap-2">
3538
<a

0 commit comments

Comments
 (0)