Skip to content

Commit

Permalink
feat: suport query component
Browse files Browse the repository at this point in the history
  • Loading branch information
CCherry07 committed Jul 17, 2024
1 parent 7a14ee0 commit 2e73894
Show file tree
Hide file tree
Showing 21 changed files with 210 additions and 52 deletions.
1 change: 1 addition & 0 deletions packages/icons/playground-react/farm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default defineConfig({
visualizer(),
["@farmfe/plugin-react", { runtime: "automatic" }],
["@farmfe/plugin-icons", {
scale: 1,
/**
* @description Whether to automatically install the required dependencies
* @type {boolean}
Expand Down
18 changes: 11 additions & 7 deletions packages/icons/playground-react/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useState } from "react";
import "./main.css";
import reactLogo from "./assets/react.svg";
import FarmLogo from "./assets/logo.png";
// import 'virtual:uno.css'
import ReactLogo from '~icons/logos/react'
import ReactLogoComponent from "./assets/react.svg?component";
import LocalReactLogo from "~icons/local/react";
import RemoteComponent from "~icons/remote/react";
import ReactLogoIconify from '~icons/logos/react'
export function Main() {
const [count, setCount] = useState(0);
console.log("rendering Main component")
Expand All @@ -14,11 +15,14 @@ export function Main() {
<img src={FarmLogo} className="logo" alt="Farm logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
{/* <img src={reactLogo} className="logo react" alt="React logo" /> */}
</a>
<div style={{display:'flex',alignItems:"center"}}>
<div><ReactLogo className=" text-100px text-#00D8FF"/></div>
<div className="i-logos-react text-100px text-#00D8FF"></div>
<div style={{ display: 'flex', alignItems: "center" }}>
<div className="i-logos-react text-100px text-#00D8FF"></div>
<ReactLogoIconify className=" text-100px text-#00D8FF" />
<ReactLogoComponent className="text-100px h-1em w-1em" />
<LocalReactLogo className="text-100px h-1em w-1em" />
<RemoteComponent className="text-100px h-1em w-1em" />
</div>
</div>
<h1>Farm + React</h1>
Expand Down
4 changes: 2 additions & 2 deletions packages/icons/playground-react/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"include": ["src","@farmfe/plugin-icons/types/react.d.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}
}
4 changes: 2 additions & 2 deletions packages/icons/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub struct GetCompilerParams {

pub struct CompilerParams {
pub svg: String,
pub svg_name: String,
pub root_path: String,
pub svg_name: Option<String>,
pub root_path: Option<String>,
}

pub fn get_compiler(param: GetCompilerParams) -> impl Fn(CompilerParams) -> String {
Expand Down
2 changes: 1 addition & 1 deletion packages/icons/src/compiler/svelte.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn svelte_compiler(param: CompilerParams) -> String {
let CompilerParams { svg, root_path, .. } = param;
let mut svelte_runes = SVELTE_RUNES.lock().unwrap();
if svelte_runes.is_none() {
*svelte_runes = match get_svelte_version(&root_path) {
*svelte_runes = match get_svelte_version(&root_path.unwrap()) {
Some(version) => Some(version >= 5),
None => Some(false),
};
Expand Down
6 changes: 3 additions & 3 deletions packages/icons/src/compiler/vue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub fn vue_compiler(param: CompilerParams) -> String {
let CompileResult { code, .. } = compile(
&code,
CompileOptions {
filename: std::borrow::Cow::Borrowed(&svg_name),
filename: std::borrow::Cow::Borrowed(&svg_name.unwrap_or("Index".to_string())),
id: std::borrow::Cow::Borrowed("index"),
is_prod: Some(true),
ssr: Some(false),
Expand Down Expand Up @@ -36,8 +36,8 @@ mod tests {
</template>"#;
let params = CompilerParams {
svg: svg.to_string(),
root_path,
svg_name: "abc".to_string(),
root_path: Some(root_path),
svg_name: Some("abc".to_string()),
};
let result = vue_compiler(params);
println!("{}", result)
Expand Down
91 changes: 55 additions & 36 deletions packages/icons/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use loader::{
};
use options::Options;
use serde_json::Value;
use std::collections::HashMap;
use std::{collections::HashMap, path::Path};

const PUBLIC_ICON_PREFIX: &str = "virtual:__FARM_ICON_ASSET__:";

Expand All @@ -40,7 +40,10 @@ impl FarmfePluginIcons {
.collections_node_resolve_path
.unwrap_or(config.root.clone()),
);

println!(
"collections_node_resolve_path: {:?}",
collections_node_resolve_path
);
let jsx = options::guess_jsx(&config.root);

Self {
Expand All @@ -57,6 +60,9 @@ impl Plugin for FarmfePluginIcons {
fn name(&self) -> &str {
"FarmfePluginIcons"
}
fn priority(&self) -> i32 {
101
}
fn resolve(
&self,
param: &farmfe_core::plugin::PluginResolveHookParam,
Expand All @@ -65,19 +71,10 @@ impl Plugin for FarmfePluginIcons {
) -> farmfe_core::error::Result<Option<farmfe_core::plugin::PluginResolveHookResult>> {
let meta = get_path_meta(&param.source);
let query = parse_query(&meta.query);
if query.iter().any(|(k, _)| k == "component") {
let res = meta.base_path.clone();
if res.ends_with(".svg") {
return Ok(Some(PluginResolveHookResult {
resolved_path: format!("{PUBLIC_ICON_PREFIX}{}", res),
external: false,
side_effects: false,
query,
..Default::default()
}));
}
let query_is_component = query.iter().any(|(k, _)| k == "component");
if query_is_component {
return Ok(None);
}

if is_icon_path(&param.source) {
let res = meta.base_path.clone();
let compiler = {
Expand All @@ -91,6 +88,13 @@ impl Plugin for FarmfePluginIcons {
.unwrap_or_else(|| "jsx".to_string())
}
};
let mut source_path = res.clone();
if query_is_component {
let import_path = Path::new(&source_path);
if import_path.is_relative() {
source_path = format!("{}{}", import_path.to_string_lossy().to_string(), ".svg");
}
}
let resolved_path = match compiler.as_str() {
"jsx" => format!("{}.jsx", res),
"svelte" => format!("{}.svelte", res),
Expand All @@ -103,9 +107,11 @@ impl Plugin for FarmfePluginIcons {
external: false,
side_effects: false,
query,
meta: HashMap::from([("source_path".to_string(), source_path)]),
..Default::default()
}));
}

Ok(None)
}
fn load(
Expand All @@ -114,6 +120,38 @@ impl Plugin for FarmfePluginIcons {
_context: &std::sync::Arc<farmfe_core::context::CompilationContext>,
_hook_context: &farmfe_core::plugin::PluginHookContext,
) -> farmfe_core::error::Result<Option<farmfe_core::plugin::PluginLoadHookResult>> {
if param.query.iter().any(|(k, _)| k == "component") {
let query_map = param.query.iter().cloned().collect::<HashMap<_, _>>();
let svg_builder = SvgModifier::new(SvgModifier {
fill: query_map.get("fill").and_then(|v| v.parse().ok()),
stroke: query_map.get("stroke").and_then(|v| v.parse().ok()),
stroke_width: query_map.get("stroke-width").and_then(|v| v.parse().ok()),
width: query_map.get("width").and_then(|v| v.parse().ok()),
height: query_map.get("height").and_then(|v| v.parse().ok()),
class: self.options.default_class.clone(),
style: self.options.default_style.clone(),
view_box: None,
});
let svg = svg_builder.apply_to_svg(&get_svg_by_local_path(param.resolved_path));
let compiler = get_compiler(GetCompilerParams {
jsx: self.options.jsx.clone().unwrap_or_default(),
compiler: self.options.compiler.clone().unwrap_or_default(),
});
let code = compiler(CompilerParams {
svg,
root_path: None,
svg_name: None,
});
let module_type = get_module_type_by_compiler(GetCompilerParams {
jsx: self.options.jsx.clone().unwrap_or_default(),
compiler: self.options.compiler.clone().unwrap_or_default(),
});
return Ok(Some(PluginLoadHookResult {
content: code,
module_type,
source_map: None,
}));
}
if let Some(source) = param.resolved_path.strip_prefix(PUBLIC_ICON_PREFIX) {
let root_path = self
.options
Expand All @@ -124,7 +162,6 @@ impl Plugin for FarmfePluginIcons {
jsx: self.options.jsx.clone().unwrap_or_default(),
compiler: self.options.compiler.clone().unwrap_or_default(),
});
let meta = resolve_icons_path(source);
let query_map = param.query.iter().cloned().collect::<HashMap<_, _>>();
let svg_builder = SvgModifier::new(SvgModifier {
fill: query_map.get("fill").and_then(|v| v.parse().ok()),
Expand All @@ -136,25 +173,7 @@ impl Plugin for FarmfePluginIcons {
style: self.options.default_style.clone(),
view_box: None,
});

if query_map.contains_key("component") {
let svg = svg_builder.apply_to_svg(&get_svg_by_local_path(&param.resolved_path));
let code = compiler(CompilerParams {
svg,
root_path,
svg_name: meta.icon,
});
let module_type = get_module_type_by_compiler(GetCompilerParams {
jsx: self.options.jsx.clone().unwrap_or_default(),
compiler: self.options.compiler.clone().unwrap_or_default(),
});
return Ok(Some(PluginLoadHookResult {
content: code,
module_type,
source_map: None,
}));
}

let meta = resolve_icons_path(source);
let mut svg_raw = String::new();
let custom_collections = self
.options
Expand Down Expand Up @@ -226,8 +245,8 @@ impl Plugin for FarmfePluginIcons {
}
let code = compiler(CompilerParams {
svg: svg_raw,
root_path,
svg_name: meta.icon,
root_path:Some(root_path),
svg_name: Some(meta.icon),
});
let module_type = get_module_type_by_compiler(GetCompilerParams {
jsx: self.options.jsx.clone().unwrap_or_default(),
Expand Down
10 changes: 10 additions & 0 deletions packages/icons/types/astro.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// <reference types="astro/astro-jsx" />

declare module '~icons/*' {
const component: (props: astroHTML.JSX.SVGAttributes) => astroHTML.JSX.Element
export default component
}
declare module 'virtual:icons/*' {
const component: (props: astroHTML.JSX.SVGAttributes) => astroHTML.JSX.Element
export default component
}
1 change: 1 addition & 0 deletions packages/icons/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../dist/types'
12 changes: 12 additions & 0 deletions packages/icons/types/preact.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare module 'virtual:icons/*' {
import type { JSX } from 'preact'

const component: (props: JSX.SVGAttributes<SVGSVGElement>) => JSX.Element
export default component
}
declare module '~icons/*' {
import type { JSX } from 'preact'

const component: (props: JSX.SVGAttributes<SVGSVGElement>) => JSX.Element
export default component
}
12 changes: 12 additions & 0 deletions packages/icons/types/qwik.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare module 'virtual:icons/*' {
import type { FunctionComponent, QwikIntrinsicElements } from '@builder.io/qwik'

const Component: FunctionComponent<QwikIntrinsicElements['svg']>
export default Component
}
declare module '~icons/*' {
import type { FunctionComponent, QwikIntrinsicElements } from '@builder.io/qwik'

const Component: FunctionComponent<QwikIntrinsicElements['svg']>
export default Component
}
8 changes: 8 additions & 0 deletions packages/icons/types/raw.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'virtual:icons/*' {
const component: string
export default string
}
declare module '~icons/*' {
const component: string
export default component
}
14 changes: 14 additions & 0 deletions packages/icons/types/react.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
declare module 'virtual:icons/*' {
import type { SVGProps } from 'react'
import type React from 'react'

const component: (props: SVGProps<SVGSVGElement>) => React.ReactElement
export default component
}
declare module '~icons/*' {
import type { SVGProps } from 'react'
import type React from 'react'

const component: (props: SVGProps<SVGSVGElement>) => React.ReactElement
export default component
}
12 changes: 12 additions & 0 deletions packages/icons/types/solid.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare module 'virtual:icons/*' {
import type { ComponentProps, JSX } from 'solid-js'

const component: (props: ComponentProps<'svg'>) => JSX.Element
export default component
}
declare module '~icons/*' {
import type { ComponentProps, JSX } from 'solid-js'

const component: (props: ComponentProps<'svg'>) => JSX.Element
export default component
}
1 change: 1 addition & 0 deletions packages/icons/types/svelte.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './svelte4.d.ts'
9 changes: 9 additions & 0 deletions packages/icons/types/svelte3.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare module 'virtual:icons/*' {
export { SvelteComponentDev as default } from 'svelte/internal'
}

declare module '~icons/*' {
import { SvelteComponentTyped } from 'svelte'

export default class extends SvelteComponentTyped<svelte.JSX.IntrinsicElements['svg']> {}
}
13 changes: 13 additions & 0 deletions packages/icons/types/svelte4.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
declare module 'virtual:icons/*' {
import { SvelteComponent } from 'svelte'
import type { SvelteHTMLElements } from 'svelte/elements'

export default class extends SvelteComponent<SvelteHTMLElements['svg']> {}
}

declare module '~icons/*' {
import { SvelteComponent } from 'svelte'
import type { SvelteHTMLElements } from 'svelte/elements'

export default class extends SvelteComponent<SvelteHTMLElements['svg']> {}
}
1 change: 1 addition & 0 deletions packages/icons/types/vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './vue3'
12 changes: 12 additions & 0 deletions packages/icons/types/vue3.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare module 'virtual:icons/*' {
import type { FunctionalComponent, SVGAttributes } from 'vue'

const component: FunctionalComponent<SVGAttributes>
export default component
}
declare module '~icons/*' {
import type { FunctionalComponent, SVGAttributes } from 'vue'

const component: FunctionalComponent<SVGAttributes>
export default component
}
8 changes: 8 additions & 0 deletions packages/icons/types/web-components.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'virtual:icons/*' {
const component: HTMLElement
export default component
}
declare module '~icons/*' {
const component: HTMLElement
export default component
}
Loading

0 comments on commit 2e73894

Please sign in to comment.