diff --git a/.changeset/rude-wasps-judge.md b/.changeset/rude-wasps-judge.md
new file mode 100644
index 00000000..7a4cf68c
--- /dev/null
+++ b/.changeset/rude-wasps-judge.md
@@ -0,0 +1,5 @@
+---
+"@devup-ui/wasm": patch
+---
+
+Fix negative issue, literal issue
diff --git a/apps/landing/src/components/SearchModal/SearchContent.tsx b/apps/landing/src/components/SearchModal/SearchContent.tsx
index 2922577c..ff473b06 100644
--- a/apps/landing/src/components/SearchModal/SearchContent.tsx
+++ b/apps/landing/src/components/SearchModal/SearchContent.tsx
@@ -2,7 +2,7 @@
import { Box, Center, css, Flex, Text, VStack } from '@devup-ui/react'
import Link from 'next/link'
import { useSearchParams } from 'next/navigation'
-import { Fragment, useEffect, useState } from 'react'
+import { Fragment, useEffect, useMemo, useState } from 'react'
import { URL_PREFIX } from '../../constants'
@@ -38,6 +38,7 @@ export function SearchContent() {
)
}
}, [query])
+ const reg = useMemo(() => new RegExp(`(${query})`, 'gi'), [query])
if (!query) return
const inner = data ? (
<>
@@ -58,8 +59,22 @@ export function SearchContent() {
p="10px"
>
{item.title}
-
- {item.text}
+
+ {item.text
+ .substring(0, 100)
+ .split(reg)
+ .map((part, idx) =>
+ part.toLowerCase() === query.toLowerCase() ? (
+
+ {part}
+
+ ) : (
+
+ {part}
+
+ ),
+ )}
+ ...
diff --git a/libs/extractor/src/lib.rs b/libs/extractor/src/lib.rs
index 42efbcde..16e2b53e 100644
--- a/libs/extractor/src/lib.rs
+++ b/libs/extractor/src/lib.rs
@@ -6,28 +6,20 @@ mod prop_modify_utils;
mod style_extractor;
mod utils;
mod visit;
-
-use oxc_codegen::Codegen;
-use std::collections::BTreeMap;
-
use crate::extract_style::ExtractStyleValue;
use crate::visit::DevupVisitor;
use oxc_allocator::Allocator;
use oxc_ast::ast::Expression;
use oxc_ast::VisitMut;
+use oxc_codegen::Codegen;
use oxc_parser::{Parser, ParserReturn};
use oxc_span::SourceType;
+use std::collections::BTreeMap;
use std::error::Error;
-
-/// result of extracting style properties from props
#[derive(Debug)]
pub enum ExtractStyleProp<'a> {
Static(ExtractStyleValue),
StaticArray(Vec>),
- /// static + static ex) margin={test?"4px":"8px"} --> className={test?"margin-4px-0":"margin-8px-0"}
- /// static + dynamic ex) margin={test?a:"8px"} --> className={test?"margin-0":"margin-8px-0"} style={{ "--margin-0": a }}
- /// dynamic + dynamic ex) margin={test?a:b} --> className="margin-0" style={{ "--margin-0": test?a:b }}
- /// issue case: dynamic + dynamic ex) margin={test?a:(b ? "8px": c)} --> className="margin-0" style={{ "--margin-0": test?a:(b ? "8px": c) }}
Conditional {
condition: Expression<'a>,
consequent: Option>>,
@@ -42,6 +34,7 @@ pub enum ExtractStyleProp<'a> {
expression: Expression<'a>,
},
}
+
impl ExtractStyleProp<'_> {
pub fn extract(&self) -> Vec {
match self {
@@ -345,6 +338,19 @@ mod tests {
}
)
.unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.tsx",
+ r"import {Flex} from '@devup-ui/core'
+
+ ",
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
}
#[test]
@@ -1427,6 +1433,100 @@ export {
)
.unwrap());
}
+ #[test]
+ #[serial]
+ fn negative_props() {
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+ }
#[test]
#[serial]
@@ -1932,4 +2032,60 @@ import {Button} from '@devup/ui'
)
.unwrap());
}
+
+ #[test]
+ #[serial]
+ fn template_literal_props() {
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+
+ reset_class_map();
+ assert_debug_snapshot!(extract(
+ "test.js",
+ r#"import {Box} from '@devup-ui/core'
+
+ "#,
+ ExtractOption {
+ package: "@devup-ui/core".to_string(),
+ css_file: None
+ }
+ )
+ .unwrap());
+ }
}
diff --git a/libs/extractor/src/snapshots/extractor__tests__extract_style_props-6.snap b/libs/extractor/src/snapshots/extractor__tests__extract_style_props-6.snap
new file mode 100644
index 00000000..2b47e2a1
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__extract_style_props-6.snap
@@ -0,0 +1,27 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.tsx\",\nr\"import {Flex} from '@devup-ui/core'\n \n \",\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "display",
+ value: "flex",
+ level: 0,
+ selector: None,
+ basic: true,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "padding",
+ value: "-4px",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-2.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-2.snap
new file mode 100644
index 00000000..1b9dfe48
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-2.snap
@@ -0,0 +1,17 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Dynamic(
+ ExtractDynamicStyle {
+ property: "zIndex",
+ level: 0,
+ identifier: "-a",
+ selector: None,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-3.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-3.snap
new file mode 100644
index 00000000..6cfcb6d8
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-3.snap
@@ -0,0 +1,17 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Dynamic(
+ ExtractDynamicStyle {
+ property: "zIndex",
+ level: 0,
+ identifier: "-(1 + a)",
+ selector: None,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-4.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-4.snap
new file mode 100644
index 00000000..80de2c55
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-4.snap
@@ -0,0 +1,17 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Dynamic(
+ ExtractDynamicStyle {
+ property: "zIndex",
+ level: 0,
+ identifier: "-1 * a",
+ selector: None,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-5.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-5.snap
new file mode 100644
index 00000000..ae8131c3
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-5.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-1",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-6.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-6.snap
new file mode 100644
index 00000000..bbadc7a3
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-6.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-1",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props-7.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props-7.snap
new file mode 100644
index 00000000..895ebbcf
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props-7.snap
@@ -0,0 +1,36 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-1",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-2",
+ level: 1,
+ selector: None,
+ basic: false,
+ },
+ ),
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-3",
+ level: 2,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__negative_props.snap b/libs/extractor/src/snapshots/extractor__tests__negative_props.snap
new file mode 100644
index 00000000..a4191c17
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__negative_props.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "zIndex",
+ value: "-1",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props-2.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-2.snap
new file mode 100644
index 00000000..33affea3
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-2.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "margin",
+ value: "4px",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props-3.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-3.snap
new file mode 100644
index 00000000..7e53ebf1
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-3.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "margin",
+ value: "-4px",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props-4.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-4.snap
new file mode 100644
index 00000000..7c01927c
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props-4.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "margin",
+ value: "1 2",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/snapshots/extractor__tests__template_literal_props.snap b/libs/extractor/src/snapshots/extractor__tests__template_literal_props.snap
new file mode 100644
index 00000000..e8694602
--- /dev/null
+++ b/libs/extractor/src/snapshots/extractor__tests__template_literal_props.snap
@@ -0,0 +1,18 @@
+---
+source: libs/extractor/src/lib.rs
+expression: "extract(\"test.js\",\nr#\"import {Box} from '@devup-ui/core'\n \n \"#,\nExtractOption\n{ package: \"@devup-ui/core\".to_string(), css_file: None }).unwrap()"
+---
+ExtractOutput {
+ styles: [
+ Static(
+ ExtractStaticStyle {
+ property: "background",
+ value: "red",
+ level: 0,
+ selector: None,
+ basic: false,
+ },
+ ),
+ ],
+ code: "import \"@devup-ui/core/devup-ui.css\";\n;\n",
+}
diff --git a/libs/extractor/src/style_extractor.rs b/libs/extractor/src/style_extractor.rs
index a876ceb9..0ce986af 100644
--- a/libs/extractor/src/style_extractor.rs
+++ b/libs/extractor/src/style_extractor.rs
@@ -251,272 +251,294 @@ pub fn extract_style_from_expression<'a>(
}
typo = name == "typography";
}
- match expression {
- Expression::ComputedMemberExpression(mem) => {
- extract_style_from_member_expression(ast_builder, name, mem, level, selector)
- }
- Expression::NumericLiteral(v) => name
- .map(|name| {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Static(
- ExtractStaticStyle::new(
- name,
- &v.value.to_string(),
+ if let Some(value) = get_number_by_literal_expression(expression) {
+ name.map(|name| {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Static(
+ ExtractStaticStyle::new(
+ name,
+ &value.to_string(),
+ level,
+ selector.map(|s| s.into()),
+ ),
+ ))])
+ })
+ .unwrap_or(ExtractResult::Maintain)
+ } else if let Some(value) = get_string_by_literal_expression(expression) {
+ name.map(|name| {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(if typo {
+ Typography(value.as_str().to_string())
+ } else {
+ Static(ExtractStaticStyle::new(
+ name,
+ value.as_str(),
+ level,
+ selector.map(|s| s.into()),
+ ))
+ })])
+ })
+ .unwrap_or(ExtractResult::Maintain)
+ } else {
+ match expression {
+ Expression::UnaryExpression(_) | Expression::BinaryExpression(_) => {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Dynamic(
+ ExtractDynamicStyle::new(
+ name.unwrap(),
level,
+ expression_to_code(expression).as_str(),
selector.map(|s| s.into()),
),
))])
- })
- .unwrap_or(ExtractResult::Maintain),
- Expression::TemplateLiteral(tmp) => {
- if let Some(name) = name {
- if tmp.quasis.len() == 1 {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(if typo {
- Typography(tmp.quasis[0].value.raw.as_str().to_string())
+ }
+ Expression::ComputedMemberExpression(mem) => {
+ extract_style_from_member_expression(ast_builder, name, mem, level, selector)
+ }
+ Expression::TemplateLiteral(tmp) => {
+ if let Some(name) = name {
+ if tmp.quasis.len() == 1 {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(if typo {
+ Typography(tmp.quasis[0].value.raw.as_str().to_string())
+ } else {
+ Static(ExtractStaticStyle::new(
+ name,
+ tmp.quasis[0].value.raw.as_str(),
+ level,
+ selector.map(|s| s.into()),
+ ))
+ })])
+ } else if typo {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Expression {
+ expression: ast_builder.expression_template_literal(
+ SPAN,
+ ast_builder.vec_from_array([
+ ast_builder.template_element(
+ SPAN,
+ false,
+ TemplateElementValue {
+ raw: ast_builder.atom("typo-"),
+ cooked: None,
+ },
+ ),
+ ast_builder.template_element(
+ SPAN,
+ true,
+ TemplateElementValue {
+ raw: ast_builder.atom(""),
+ cooked: None,
+ },
+ ),
+ ]),
+ ast_builder
+ .vec_from_array([expression.clone_in(ast_builder.allocator)]),
+ ),
+ styles: vec![],
+ }])
} else {
- Static(ExtractStaticStyle::new(
- name,
- tmp.quasis[0].value.raw.as_str(),
- level,
- selector.map(|s| s.into()),
- ))
- })])
- } else if typo {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Expression {
- expression: ast_builder.expression_template_literal(
- SPAN,
- ast_builder.vec_from_array([
- ast_builder.template_element(
- SPAN,
- false,
- TemplateElementValue {
- raw: ast_builder.atom("typo-"),
- cooked: None,
- },
- ),
- ast_builder.template_element(
- SPAN,
- true,
- TemplateElementValue {
- raw: ast_builder.atom(""),
- cooked: None,
- },
- ),
- ]),
- ast_builder
- .vec_from_array([expression.clone_in(ast_builder.allocator)]),
- ),
- styles: vec![],
- }])
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Dynamic(
+ ExtractDynamicStyle::new(
+ name,
+ level,
+ expression_to_code(expression).as_str(),
+ selector.map(|s| s.into()),
+ ),
+ ))])
+ }
} else {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Dynamic(
- ExtractDynamicStyle::new(
- name,
- level,
- expression_to_code(expression).as_str(),
- selector.map(|s| s.into()),
- ),
- ))])
+ ExtractResult::Maintain
}
- } else {
- ExtractResult::Maintain
}
- }
- Expression::StringLiteral(v) => name
- .map(|name| {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(if typo {
- Typography(v.value.as_str().to_string())
- } else {
- Static(ExtractStaticStyle::new(
- name,
- v.value.as_str(),
- level,
- selector.map(|s| s.into()),
- ))
- })])
- })
- .unwrap_or(ExtractResult::Maintain),
- Expression::Identifier(identifier) => {
- if IGNORED_IDENTIFIERS.contains(&identifier.name.as_str()) {
- ExtractResult::Maintain
- } else if let Some(name) = name {
- if typo {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Expression {
- expression: ast_builder.expression_template_literal(
- SPAN,
- ast_builder.vec_from_array([
- ast_builder.template_element(
- SPAN,
- false,
- TemplateElementValue {
- raw: ast_builder.atom("typo-"),
- cooked: None,
- },
- ),
- ast_builder.template_element(
- SPAN,
- true,
- TemplateElementValue {
- raw: ast_builder.atom(""),
- cooked: None,
- },
- ),
- ]),
- ast_builder
- .vec_from_array([expression.clone_in(ast_builder.allocator)]),
- ),
- styles: vec![],
- }])
+ Expression::Identifier(identifier) => {
+ if IGNORED_IDENTIFIERS.contains(&identifier.name.as_str()) {
+ ExtractResult::Maintain
+ } else if let Some(name) = name {
+ if typo {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Expression {
+ expression: ast_builder.expression_template_literal(
+ SPAN,
+ ast_builder.vec_from_array([
+ ast_builder.template_element(
+ SPAN,
+ false,
+ TemplateElementValue {
+ raw: ast_builder.atom("typo-"),
+ cooked: None,
+ },
+ ),
+ ast_builder.template_element(
+ SPAN,
+ true,
+ TemplateElementValue {
+ raw: ast_builder.atom(""),
+ cooked: None,
+ },
+ ),
+ ]),
+ ast_builder
+ .vec_from_array([expression.clone_in(ast_builder.allocator)]),
+ ),
+ styles: vec![],
+ }])
+ } else {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Dynamic(
+ ExtractDynamicStyle::new(
+ name,
+ level,
+ identifier.name.as_str(),
+ selector.map(|s| s.into()),
+ ),
+ ))])
+ }
} else {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Static(Dynamic(
- ExtractDynamicStyle::new(
- name,
- level,
- identifier.name.as_str(),
- selector.map(|s| s.into()),
- ),
- ))])
+ ExtractResult::Maintain
}
- } else {
- ExtractResult::Maintain
}
- }
- Expression::LogicalExpression(logical) => {
- let res = name.and_then(|name| {
- match extract_style_from_expression(
- ast_builder,
- Some(name),
- &mut logical.right,
- level,
- selector,
- ) {
- ExtractResult::ExtractStyle(styles) => {
- Some(Box::new(ExtractStyleProp::StaticArray(styles)))
+ Expression::LogicalExpression(logical) => {
+ let res = name.and_then(|name| {
+ match extract_style_from_expression(
+ ast_builder,
+ Some(name),
+ &mut logical.right,
+ level,
+ selector,
+ ) {
+ ExtractResult::ExtractStyle(styles) => {
+ Some(Box::new(ExtractStyleProp::StaticArray(styles)))
+ }
+ _ => None,
}
- _ => None,
- }
- });
- match logical.operator {
- LogicalOperator::Or => {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
- condition: logical.left.clone_in(ast_builder.allocator),
- consequent: None,
- alternate: res,
- }])
- }
- LogicalOperator::And => {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
- condition: logical.left.clone_in(ast_builder.allocator),
- consequent: res,
- alternate: None,
- }])
- }
- LogicalOperator::Coalesce => {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
- condition: Expression::LogicalExpression(
- ast_builder.alloc_logical_expression(
- SPAN,
- Expression::BinaryExpression(ast_builder.alloc_binary_expression(
- SPAN,
- logical.left.clone_in(ast_builder.allocator),
- BinaryOperator::StrictInequality,
- Expression::NullLiteral(ast_builder.alloc_null_literal(SPAN)),
- )),
- LogicalOperator::And,
- Expression::BinaryExpression(ast_builder.alloc_binary_expression(
+ });
+ match logical.operator {
+ LogicalOperator::Or => {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
+ condition: logical.left.clone_in(ast_builder.allocator),
+ consequent: None,
+ alternate: res,
+ }])
+ }
+ LogicalOperator::And => {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
+ condition: logical.left.clone_in(ast_builder.allocator),
+ consequent: res,
+ alternate: None,
+ }])
+ }
+ LogicalOperator::Coalesce => {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
+ condition: Expression::LogicalExpression(
+ ast_builder.alloc_logical_expression(
SPAN,
- logical.left.clone_in(ast_builder.allocator),
- BinaryOperator::StrictInequality,
- Expression::Identifier(
- ast_builder.alloc_identifier_reference(SPAN, "undefined"),
+ Expression::BinaryExpression(
+ ast_builder.alloc_binary_expression(
+ SPAN,
+ logical.left.clone_in(ast_builder.allocator),
+ BinaryOperator::StrictInequality,
+ Expression::NullLiteral(
+ ast_builder.alloc_null_literal(SPAN),
+ ),
+ ),
),
- )),
+ LogicalOperator::And,
+ Expression::BinaryExpression(
+ ast_builder.alloc_binary_expression(
+ SPAN,
+ logical.left.clone_in(ast_builder.allocator),
+ BinaryOperator::StrictInequality,
+ Expression::Identifier(
+ ast_builder
+ .alloc_identifier_reference(SPAN, "undefined"),
+ ),
+ ),
+ ),
+ ),
),
- ),
- consequent: None,
- alternate: res,
- }])
- }
- }
- }
- Expression::ParenthesizedExpression(parenthesized) => extract_style_from_expression(
- ast_builder,
- name,
- &mut parenthesized.expression,
- level,
- selector,
- ),
- Expression::ArrayExpression(array) => {
- let mut props = vec![];
-
- for (idx, element) in array.elements.iter_mut().enumerate() {
- if let ExtractResult::ExtractStyle(mut styles) = extract_style_from_expression(
- ast_builder,
- name,
- element.to_expression_mut(),
- idx as u8,
- selector,
- ) {
- props.append(&mut styles);
+ consequent: None,
+ alternate: res,
+ }])
+ }
}
}
+ Expression::ParenthesizedExpression(parenthesized) => extract_style_from_expression(
+ ast_builder,
+ name,
+ &mut parenthesized.expression,
+ level,
+ selector,
+ ),
+ Expression::ArrayExpression(array) => {
+ let mut props = vec![];
- if props.is_empty() {
- ExtractResult::Maintain
- } else {
- ExtractResult::ExtractStyle(props)
- }
- }
- Expression::ConditionalExpression(ref mut conditional) => {
- ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
- condition: conditional.test.clone_in(ast_builder.allocator),
- consequent: if let ExtractResult::ExtractStyle(styles) =
- extract_style_from_expression(
- ast_builder,
- name,
- &mut conditional.consequent,
- level,
- selector,
- ) {
- Some(Box::new(ExtractStyleProp::StaticArray(styles)))
- } else {
- None
- },
- alternate: if let ExtractResult::ExtractStyle(styles) =
- extract_style_from_expression(
+ for (idx, element) in array.elements.iter_mut().enumerate() {
+ if let ExtractResult::ExtractStyle(mut styles) = extract_style_from_expression(
ast_builder,
name,
- &mut conditional.alternate,
- level,
- selector,
- ) {
- Some(Box::new(ExtractStyleProp::StaticArray(styles)))
- } else {
- None
- },
- }])
- }
- Expression::ObjectExpression(obj) => {
- let mut props = vec![];
- for p in obj.properties.iter_mut() {
- if let ObjectPropertyKind::ObjectProperty(ref mut o) = p {
- if let ExtractResult::ExtractStyle(ref mut ret) = extract_style_from_expression(
- ast_builder,
- Some(&o.key.name().unwrap()),
- &mut o.value,
- level,
+ element.to_expression_mut(),
+ idx as u8,
selector,
) {
- props.append(ret);
+ props.append(&mut styles);
}
- };
+ }
+
+ if props.is_empty() {
+ ExtractResult::Maintain
+ } else {
+ ExtractResult::ExtractStyle(props)
+ }
}
- if props.is_empty() {
- ExtractResult::Remove
- } else {
- ExtractResult::ExtractStyle(props)
+ Expression::ConditionalExpression(ref mut conditional) => {
+ ExtractResult::ExtractStyle(vec![ExtractStyleProp::Conditional {
+ condition: conditional.test.clone_in(ast_builder.allocator),
+ consequent: if let ExtractResult::ExtractStyle(styles) =
+ extract_style_from_expression(
+ ast_builder,
+ name,
+ &mut conditional.consequent,
+ level,
+ selector,
+ ) {
+ Some(Box::new(ExtractStyleProp::StaticArray(styles)))
+ } else {
+ None
+ },
+ alternate: if let ExtractResult::ExtractStyle(styles) =
+ extract_style_from_expression(
+ ast_builder,
+ name,
+ &mut conditional.alternate,
+ level,
+ selector,
+ ) {
+ Some(Box::new(ExtractStyleProp::StaticArray(styles)))
+ } else {
+ None
+ },
+ }])
+ }
+ Expression::ObjectExpression(obj) => {
+ let mut props = vec![];
+ for p in obj.properties.iter_mut() {
+ if let ObjectPropertyKind::ObjectProperty(ref mut o) = p {
+ if let ExtractResult::ExtractStyle(ref mut ret) =
+ extract_style_from_expression(
+ ast_builder,
+ Some(&o.key.name().unwrap()),
+ &mut o.value,
+ level,
+ selector,
+ )
+ {
+ props.append(ret);
+ }
+ };
+ }
+ if props.is_empty() {
+ ExtractResult::Remove
+ } else {
+ ExtractResult::ExtractStyle(props)
+ }
}
+ // val if let Some(value) = get_number_by_literal_expression(val) => {}
+ _ => ExtractResult::Maintain,
}
- _ => ExtractResult::Maintain,
}
}
@@ -720,33 +742,43 @@ fn extract_style_from_member_expression<'a>(
fn get_number_by_literal_expression(expr: &Expression) -> Option {
match expr {
- Expression::NumericLiteral(num) => Some(num.value),
- Expression::UnaryExpression(unary) => {
- if let Expression::NumericLiteral(ref num) = unary.argument {
- match unary.operator {
- UnaryOperator::UnaryNegation => Some(-num.value),
- UnaryOperator::UnaryPlus => Some(num.value),
- _ => None,
- }
- } else {
- None
- }
+ Expression::ParenthesizedExpression(parenthesized) => {
+ get_number_by_literal_expression(&parenthesized.expression)
}
+ Expression::NumericLiteral(num) => Some(num.value),
+ Expression::UnaryExpression(unary) => get_number_by_literal_expression(&unary.argument)
+ .and_then(|num| match unary.operator {
+ UnaryOperator::UnaryNegation => Some(-num),
+ UnaryOperator::UnaryPlus => Some(num),
+ _ => None,
+ }),
_ => None,
}
}
fn get_string_by_literal_expression(expr: &Expression) -> Option {
- match expr {
- Expression::StringLiteral(str) => Some(str.value.as_str().to_string()),
- Expression::TemplateLiteral(tmp) => {
- if tmp.quasis.len() == 1 {
- Some(tmp.quasis[0].value.raw.as_str().to_string())
- } else {
- None
+ get_number_by_literal_expression(expr)
+ .map(|num| num.to_string())
+ .or_else(|| match expr {
+ Expression::ParenthesizedExpression(parenthesized) => {
+ get_string_by_literal_expression(&parenthesized.expression)
}
- }
- Expression::NumericLiteral(num) => Some(num.value.to_string()),
- _ => None,
- }
+ Expression::StringLiteral(str) => Some(str.value.as_str().to_string()),
+ Expression::TemplateLiteral(tmp) => {
+ let mut collect = vec![];
+ for (idx, q) in tmp.quasis.iter().enumerate() {
+ collect.push(q.value.raw.to_string());
+ if idx < tmp.expressions.len() {
+ if let Some(value) = get_string_by_literal_expression(&tmp.expressions[idx])
+ {
+ collect.push(value);
+ } else {
+ return None;
+ }
+ }
+ }
+ Some(collect.join(""))
+ }
+ _ => None,
+ })
}