Skip to content

Commit c71d298

Browse files
authored
Merge pull request #55 from dev-five-git/impl-theme
Implement theme
2 parents 37169ca + 7f19bd5 commit c71d298

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1039
-187
lines changed

.changeset/eight-kings-live.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@devup-ui/wasm": patch
3+
---
4+
5+
Fix desctructing issue, Support for number in typo, Implement theme selector

.changeset/quiet-rabbits-attend.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@devup-ui/react": patch
3+
---
4+
5+
Implement ThemeScript, useTheme, getTheme, setTheme

.changeset/quiet-waves-confess.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@devup-ui/webpack-plugin": patch
3+
"@devup-ui/vite-plugin": patch
4+
---
5+
6+
Update

Cargo.lock

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

apps/landing/src/app/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'sanitize.css'
22

3+
import { ThemeHead } from '@devup-ui/react'
34
import type { Metadata } from 'next'
45

56
import { Footer } from '../components/Footer'
@@ -16,8 +17,9 @@ export default function RootLayout({
1617
children: React.ReactNode
1718
}>) {
1819
return (
19-
<html lang="en">
20+
<html lang="en" suppressHydrationWarning>
2021
<head>
22+
<ThemeHead auto />
2123
<base
2224
href={process.env.NODE_ENV === 'production' ? '/devup-ui' : '/'}
2325
/>

apps/landing/src/app/page.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ import Link from 'next/link'
44
import { CodeBoard } from '../components/CodeBoard'
55
import { Container } from '../components/Container'
66
import { Discord } from '../components/Discord'
7-
import { Header } from '../components/Header'
87
import { URL_PREFIX } from '../constants'
98

109
export default function HomePage() {
1110
return (
1211
<>
13-
<Header />
1412
<Box mt="150px">
1513
<VStack alignItems="center" gap="50px" maxW="800px" mx="auto">
1614
<VStack alignItems="center" gap="24px">

apps/landing/public/light.svg renamed to apps/landing/src/components/Header/ThemeSwitch.tsx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
1-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2-
<path fill-rule="evenodd" clip-rule="evenodd"
1+
'use client'
2+
3+
import { Box, getTheme, setTheme } from '@devup-ui/react'
4+
5+
export function ThemeSwitch() {
6+
return (
7+
<Box
8+
_themeDark={{
9+
color: 'white',
10+
}}
11+
_themeDefault={{
12+
color: 'black',
13+
}}
14+
boxSize="24px"
15+
cursor="pointer"
16+
onClick={() => {
17+
setTheme(getTheme() === 'dark' ? 'default' : 'dark')
18+
}}
19+
>
20+
<svg
21+
fill="none"
22+
height="24"
23+
viewBox="0 0 24 24"
24+
width="24"
25+
xmlns="http://www.w3.org/2000/svg"
26+
>
27+
<path
28+
clipRule="evenodd"
329
d="M13 5C13 5.55228 12.5523 6 12 6C11.4477 6 11 5.55228 11 5C11 4.44772 11.4477 4 12 4C12.5523 4 13 4.44772 13 5ZM17 8C17.5523 8 18 7.55228 18 7C18 6.44772 17.5523 6 17 6C16.4477 6 16 6.44772 16 7C16 7.55228 16.4477 8 17 8ZM17 12C17 14.7614 14.7614 17 12 17C9.23858 17 7 14.7614 7 12C7 9.23858 9.23858 7 12 7C14.7614 7 17 9.23858 17 12ZM13 19C13 19.5523 12.5523 20 12 20C11.4477 20 11 19.5523 11 19C11 18.4477 11.4477 18 12 18C12.5523 18 13 18.4477 13 19ZM17 18C17.5523 18 18 17.5523 18 17C18 16.4477 17.5523 16 17 16C16.4477 16 16 16.4477 16 17C16 17.5523 16.4477 18 17 18ZM20 12C20 12.5523 19.5523 13 19 13C18.4477 13 18 12.5523 18 12C18 11.4477 18.4477 11 19 11C19.5523 11 20 11.4477 20 12ZM7 8C7.55228 8 8 7.55228 8 7C8 6.44772 7.55228 6 7 6C6.44772 6 6 6.44772 6 7C6 7.55228 6.44772 8 7 8ZM6 12C6 12.5523 5.55228 13 5 13C4.44772 13 4 12.5523 4 12C4 11.4477 4.44772 11 5 11C5.55228 11 6 11.4477 6 12ZM7 18C7.55228 18 8 17.5523 8 17C8 16.4477 7.55228 16 7 16C6.44772 16 6 16.4477 6 17C6 17.5523 6.44772 18 7 18Z"
4-
fill="#1A1A1A"/>
5-
</svg>
30+
fill="currentColor"
31+
fillRule="evenodd"
32+
/>
33+
</svg>
34+
</Box>
35+
)
36+
}

apps/landing/src/components/Header/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Link from 'next/link'
33

44
import { URL_PREFIX } from '../../constants'
55
import { HeaderWrap } from './HeaderWrap'
6+
import { ThemeSwitch } from './ThemeSwitch'
67

78
export function Header() {
89
return (
@@ -66,7 +67,7 @@ export function Header() {
6667
</Link>
6768
</Flex>
6869
<Flex alignItems="center" px="10px">
69-
<Image boxSize="24px" src={URL_PREFIX + '/light.svg'} />
70+
<ThemeSwitch />
7071
</Flex>
7172
</Flex>
7273
</Flex>

bindings/devup-ui-wasm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ js-sys = "0.3.76"
2525

2626
[dev-dependencies]
2727
wasm-bindgen-test = "0.3.50"
28-
28+
serial_test = "3.2.0"

bindings/devup-ui-wasm/src/lib.rs

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,33 @@ pub fn code_extract(
113113
pub fn object_to_typography(obj: Object, level: u8) -> Result<Typography, JsValue> {
114114
Ok(Typography::new(
115115
Reflect::get(&obj, &JsValue::from_str("fontFamily"))
116-
.map(|v| v.as_string())
116+
.as_ref()
117+
.map(js_value_to_string)
117118
.unwrap_or(None),
118119
Reflect::get(&obj, &JsValue::from_str("fontSize"))
119-
.map(|v| v.as_string())
120+
.as_ref()
121+
.map(js_value_to_string)
120122
.unwrap_or(None),
121123
Reflect::get(&obj, &JsValue::from_str("fontWeight"))
122-
.map(|v| v.as_string())
124+
.as_ref()
125+
.map(js_value_to_string)
123126
.unwrap_or(None),
124127
Reflect::get(&obj, &JsValue::from_str("lineHeight"))
125-
.map(|v| v.as_string())
128+
.as_ref()
129+
.map(js_value_to_string)
126130
.unwrap_or(None),
127131
Reflect::get(&obj, &JsValue::from_str("letterSpacing"))
128-
.map(|v| v.as_string())
132+
.as_ref()
133+
.map(js_value_to_string)
129134
.unwrap_or(None),
130135
level,
131136
))
132137
}
138+
pub fn js_value_to_string(js_value: &JsValue) -> Option<String> {
139+
js_value
140+
.as_string()
141+
.or_else(|| js_value.as_f64().map(|v| v.to_string()))
142+
}
133143

134144
fn theme_object_to_hashmap(js_value: JsValue) -> Result<Theme, JsValue> {
135145
let mut theme = Theme::default();
@@ -229,10 +239,12 @@ pub fn get_theme_interface(
229239
package_name: &str,
230240
color_interface_name: &str,
231241
typography_interface_name: &str,
232-
) -> Result<String, JsValue> {
242+
theme_interface_name: &str,
243+
) -> String {
233244
let sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
234245
let mut color_keys = HashSet::new();
235246
let mut typography_keys = HashSet::new();
247+
let mut theme_keys = HashSet::new();
236248
for color_theme in sheet.theme.colors.themes.values() {
237249
color_theme.keys().for_each(|key| {
238250
color_keys.insert(key.clone());
@@ -242,11 +254,15 @@ pub fn get_theme_interface(
242254
typography_keys.insert(key.clone());
243255
});
244256

257+
sheet.theme.colors.themes.keys().for_each(|key| {
258+
theme_keys.insert(key.clone());
259+
});
260+
245261
if color_keys.is_empty() && typography_keys.is_empty() {
246-
Ok("".to_string())
262+
String::new()
247263
} else {
248-
Ok(format!(
249-
"import \"{}\";declare module \"{}\"{{interface {} {{{}}}interface {} {{{}}}}}",
264+
format!(
265+
"import \"{}\";declare module \"{}\"{{interface {}{{{}}}interface {}{{{}}}interface {}{{{}}}}}",
250266
package_name,
251267
package_name,
252268
color_interface_name,
@@ -260,7 +276,83 @@ pub fn get_theme_interface(
260276
.into_iter()
261277
.map(|key| format!("{}:null;", key))
262278
.collect::<Vec<String>>()
279+
.join(""),
280+
theme_interface_name,
281+
theme_keys
282+
.into_iter()
283+
// key to pascal
284+
.map(|key| format!("{}:null;", key))
285+
.collect::<Vec<String>>()
263286
.join("")
264-
))
287+
)
288+
}
289+
}
290+
#[cfg(test)]
291+
mod tests {
292+
use super::*;
293+
use serial_test::serial;
294+
295+
#[test]
296+
#[serial]
297+
fn test_code_extract() {
298+
{
299+
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
300+
*sheet = StyleSheet::default();
301+
}
302+
assert_eq!(get_css().unwrap(), "");
303+
304+
{
305+
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
306+
let mut theme = Theme::default();
307+
let mut color_theme = ColorTheme::default();
308+
color_theme.add_color("primary", "#000");
309+
theme.colors.add_theme("dark", color_theme);
310+
311+
let mut color_theme = ColorTheme::default();
312+
color_theme.add_color("primary", "#FFF");
313+
theme.colors.add_theme("default", color_theme);
314+
sheet.set_theme(theme);
315+
}
316+
317+
assert_eq!(
318+
get_css().unwrap(),
319+
":root{--primary:#FFF;}\n:root[data-theme=dark]{--primary:#000;}\n"
320+
);
321+
}
322+
323+
#[test]
324+
#[serial]
325+
fn test_get_theme_interface() {
326+
{
327+
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
328+
*sheet = StyleSheet::default();
329+
}
330+
assert_eq!(
331+
get_theme_interface(
332+
"package",
333+
"ColorInterface",
334+
"TypographyInterface",
335+
"ThemeInterface"
336+
),
337+
""
338+
);
339+
340+
{
341+
let mut sheet = GLOBAL_STYLE_SHEET.lock().unwrap();
342+
let mut theme = Theme::default();
343+
let mut color_theme = ColorTheme::default();
344+
color_theme.add_color("primary", "#000");
345+
theme.colors.add_theme("dark", color_theme);
346+
sheet.set_theme(theme);
347+
}
348+
assert_eq!(
349+
get_theme_interface(
350+
"package",
351+
"ColorInterface",
352+
"TypographyInterface",
353+
"ThemeInterface"
354+
),
355+
"import \"package\";declare module \"package\"{interface ColorInterface{$primary:null;}interface TypographyInterface{}interface ThemeInterface{dark:null;}}"
356+
);
265357
}
266358
}

0 commit comments

Comments
 (0)