From 7ee912bd4374581d9b51a906c9f379314d57f7ee Mon Sep 17 00:00:00 2001 From: Nick B Date: Tue, 12 Nov 2024 17:08:07 -0800 Subject: [PATCH 1/7] Initial commit that starts the conversion of Material icons from Google Font-based to SVG-based. This commit creates the two SVG icons that had been used already as SVGs directly, and adds a wrapper component for convenient manipulation of the icons. It replaces those SVGs with the icon versions. Further work will replace the font-based icons that have not yet been converted to SVGs. --- .../components/header_bar/menu_desktop.tsx | 16 +++---- static/js/components/content/link_chips.tsx | 15 ++----- .../elements/icons/arrow_forward.tsx | 37 +++++++++++++++ static/js/components/elements/icons/icon.tsx | 45 +++++++++++++++++++ .../elements/icons/keyboard_arrow_down.tsx | 37 +++++++++++++++ 5 files changed, 130 insertions(+), 20 deletions(-) create mode 100644 static/js/components/elements/icons/arrow_forward.tsx create mode 100644 static/js/components/elements/icons/icon.tsx create mode 100644 static/js/components/elements/icons/keyboard_arrow_down.tsx diff --git a/static/js/apps/base/components/header_bar/menu_desktop.tsx b/static/js/apps/base/components/header_bar/menu_desktop.tsx index 02c4d49162..cbe90b8645 100644 --- a/static/js/apps/base/components/header_bar/menu_desktop.tsx +++ b/static/js/apps/base/components/header_bar/menu_desktop.tsx @@ -18,6 +18,8 @@ import React, { ReactElement, useEffect, useRef, useState } from "react"; +import { Icon } from "../../../../components/elements/icons/icon"; +import { KeyboardArrowDown } from "../../../../components/elements/icons/keyboard_arrow_down"; import { GA_EVENT_HEADER_CLICK, GA_PARAM_ID, @@ -138,15 +140,11 @@ const MenuDesktop = ({ openMenu === index ? "open" : "" }`} > - - - +
- {title &&

{title}

} + {title &&

{title}

}
    {linkChips.map((linkChip) => (
  • @@ -70,16 +72,7 @@ export const LinkChips = ({ }); }} > - - - - - + {linkChip.title}
  • diff --git a/static/js/components/elements/icons/arrow_forward.tsx b/static/js/components/elements/icons/arrow_forward.tsx new file mode 100644 index 0000000000..e4845b2a58 --- /dev/null +++ b/static/js/components/elements/icons/arrow_forward.tsx @@ -0,0 +1,37 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Arrow Forward + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const ArrowForward = ( + props: React.SVGProps +): ReactElement => ( + + + +); diff --git a/static/js/components/elements/icons/icon.tsx b/static/js/components/elements/icons/icon.tsx new file mode 100644 index 0000000000..3f64833e3f --- /dev/null +++ b/static/js/components/elements/icons/icon.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A component to simplify the interface of SVGs, providing + * simpler wrapping for commonly-used props for inline icons. + */ + +import React, { ReactElement, SVGProps } from "react"; + +interface IconProps extends SVGProps { + icon: (props: SVGProps) => ReactElement; + color?: string; + size?: number | string; +} + +export const Icon = ({ + icon: IconComponent, + color = "currentColor", + size = "1em", + ...props +}: IconProps): ReactElement | null => { + return ( + + ); +}; diff --git a/static/js/components/elements/icons/keyboard_arrow_down.tsx b/static/js/components/elements/icons/keyboard_arrow_down.tsx new file mode 100644 index 0000000000..8a2076c09d --- /dev/null +++ b/static/js/components/elements/icons/keyboard_arrow_down.tsx @@ -0,0 +1,37 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Keyboard Arrow Down + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const KeyboardArrowDown = ( + props: React.SVGProps +): ReactElement => ( + + + +); From 80623492e7c5e517bc537f68eacfc0c9b05f0069 Mon Sep 17 00:00:00 2001 From: Nick B Date: Tue, 12 Nov 2024 17:10:18 -0800 Subject: [PATCH 2/7] Description of interface. --- static/js/components/elements/icons/icon.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/static/js/components/elements/icons/icon.tsx b/static/js/components/elements/icons/icon.tsx index 3f64833e3f..d7a1960f39 100644 --- a/static/js/components/elements/icons/icon.tsx +++ b/static/js/components/elements/icons/icon.tsx @@ -22,8 +22,12 @@ import React, { ReactElement, SVGProps } from "react"; interface IconProps extends SVGProps { + //The SVG icon to be rendered by the icon component icon: (props: SVGProps) => ReactElement; + //The color of the SVG icon. If a color is not provided, this will be the + //color of the containing element. color?: string; + //the size of the icon. If not provided, this will default to 1em. size?: number | string; } From 397dcad05dc5bea86b1c545989cf3a59cd44475b Mon Sep 17 00:00:00 2001 From: Nick B Date: Fri, 15 Nov 2024 19:00:17 -0800 Subject: [PATCH 3/7] Application of SVG icons to core and homepage sections. --- static/css/core.scss | 36 +++-- .../header_bar/menu_desktop_section_group.tsx | 129 ------------------ .../components/header_bar/menu_mobile.tsx | 18 ++- .../header_bar/menu_rich_link_group.tsx | 12 +- .../header_bar/menu_rich_section_group.tsx | 10 +- .../components/elements/icons/arrow_back.tsx | 37 +++++ .../elements/icons/arrow_forward.tsx | 6 +- .../elements/icons/arrow_outward.tsx | 37 +++++ static/js/components/elements/icons/close.tsx | 35 +++++ static/js/components/elements/icons/icon.tsx | 2 +- .../elements/icons/keyboard_arrow_down.tsx | 6 +- static/js/components/elements/icons/menu.tsx | 35 +++++ .../js/components/elements/icons/rss_feed.tsx | 35 +++++ 13 files changed, 237 insertions(+), 161 deletions(-) delete mode 100644 static/js/apps/base/components/header_bar/menu_desktop_section_group.tsx create mode 100644 static/js/components/elements/icons/arrow_back.tsx create mode 100644 static/js/components/elements/icons/arrow_outward.tsx create mode 100644 static/js/components/elements/icons/close.tsx create mode 100644 static/js/components/elements/icons/menu.tsx create mode 100644 static/js/components/elements/icons/rss_feed.tsx diff --git a/static/css/core.scss b/static/css/core.scss index 5f402e71c1..cafd4913d2 100644 --- a/static/css/core.scss +++ b/static/css/core.scss @@ -266,10 +266,15 @@ section { } } h4 { + display: inline-flex; + align-items: center; font-family: $font-family-google-title; font-size: 1rem; font-weight: 500; margin-bottom: 16px; + .icon { + font-size: 20px; + } } p, .link-item, @@ -292,8 +297,10 @@ section { text-decoration: underline; } } - .material-icons-outlined { - font-size: 18px; + .icon { + display: flex; + align-items: center; + font-size: 17px; } } } @@ -404,16 +411,14 @@ section { padding: 0; background-color: transparent; cursor: pointer; - .material-icons-outline { - color: #5e5e5e; + color: #5e5e5e; + font-size: 32px; + transform: translateY(1px); // Optical correction + @media (max-width: 340px) { + font-size: 24px; } - .big { - font-size: 32px; - color: #5e5e5e; - transform: translateY(1px); // Optical correction - @media (max-width: 340px) { - font-size: 24px; - } + &.menu-toggle-close, &.menu-toggle-back { + font-size: 24px; } } @@ -511,6 +516,9 @@ section { border: 0; margin: 0; color: #474747; + .icon { + font-size: 24px; + } } } } @@ -561,8 +569,10 @@ section { text-decoration: underline; } } - .material-icons-outlined { - font-size: 18px; + .icon { + display: flex; + align-items: center; + font-size: 17px; } } } diff --git a/static/js/apps/base/components/header_bar/menu_desktop_section_group.tsx b/static/js/apps/base/components/header_bar/menu_desktop_section_group.tsx deleted file mode 100644 index a4030871a2..0000000000 --- a/static/js/apps/base/components/header_bar/menu_desktop_section_group.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* A component to render a section group of the rich menu */ - -import React, { ReactElement } from "react"; - -import { - GA_EVENT_HEADER_CLICK, - triggerGAEvent, -} from "../../../../shared/ga_events"; -import { HeaderMenuGroup, Routes } from "../../../../shared/types/base"; -import { resolveHref } from "../../utilities/utilities"; - -interface MenuDesktopSectionGroupProps { - //the menu group to be rendered inside a particular location in the rich menu - menuGroup: HeaderMenuGroup; - //the routes dictionary - this is used to convert routes to resolved urls - routes: Routes; -} - -const MenuDesktopSectionGroup = ({ - menuGroup, - routes, -}: MenuDesktopSectionGroupProps): ReactElement => { - return ( -
    - {menuGroup.title &&

    {menuGroup.title}

    } - {menuGroup.items.map((item, index) => ( -
    - {item.title && item.url ? ( -
    - { - triggerGAEvent(GA_EVENT_HEADER_CLICK, { - GA_PARAM_ID: `desktop ${menuGroup.id} ${index}`, - GA_PARAM_URL: item.url, - }); - return true; - }} - > - {item.linkType === "external" && ( - arrow_outward - )} - {item.linkType === "rss" && ( - rss_feed - )} - {item.title} - -
    - ) : ( -
    {item.title}
    - )} - - {item.description &&

    {item.description}

    } - - {item.links?.length > 0 && ( - - )} -
    - ))} -
    - ); -}; - -export default MenuDesktopSectionGroup; diff --git a/static/js/apps/base/components/header_bar/menu_mobile.tsx b/static/js/apps/base/components/header_bar/menu_mobile.tsx index 94a3b91b68..c106ba1707 100644 --- a/static/js/apps/base/components/header_bar/menu_mobile.tsx +++ b/static/js/apps/base/components/header_bar/menu_mobile.tsx @@ -24,6 +24,10 @@ import React, { useState, } from "react"; +import { ArrowBack } from "../../../../components/elements/icons/arrow_back"; +import { ArrowForward } from "../../../../components/elements/icons/arrow_forward"; +import { Close } from "../../../../components/elements/icons/close"; +import { Menu } from "../../../../components/elements/icons/menu"; import { GA_EVENT_HEADER_CLICK, GA_PARAM_ID, @@ -119,7 +123,7 @@ const MenuMobile = ({ ))}
@@ -133,18 +137,18 @@ const MenuMobile = ({
{selectedPrimaryItemIndex !== null && ( )}
@@ -182,8 +186,8 @@ const MenuMobile = ({ tabIndex={tabIndex} > {labels[item.label]} - - arrow_forward + + diff --git a/static/js/apps/base/components/header_bar/menu_rich_link_group.tsx b/static/js/apps/base/components/header_bar/menu_rich_link_group.tsx index 054cd08211..1a02419e51 100644 --- a/static/js/apps/base/components/header_bar/menu_rich_link_group.tsx +++ b/static/js/apps/base/components/header_bar/menu_rich_link_group.tsx @@ -18,6 +18,8 @@ import React, { ReactElement } from "react"; +import { ArrowOutward } from "../../../../components/elements/icons/arrow_outward"; +import { RssFeed } from "../../../../components/elements/icons/rss_feed"; import { HeaderMenuItemLink, Routes } from "../../../../shared/types/base"; import { resolveHref } from "../../utilities/utilities"; @@ -48,10 +50,12 @@ const MenuRichLinkGroup = ({ className={"link"} tabIndex={tabIndex} > - rss_feed + + + RSS Feed - {link.title &&

• {link.title}

} + {link.title && • {link.title}} ) : ( {link.linkType === "external" && ( - arrow_outward + + + )} {link.title} diff --git a/static/js/apps/base/components/header_bar/menu_rich_section_group.tsx b/static/js/apps/base/components/header_bar/menu_rich_section_group.tsx index 7914f336c0..1bbe5a2eb9 100644 --- a/static/js/apps/base/components/header_bar/menu_rich_section_group.tsx +++ b/static/js/apps/base/components/header_bar/menu_rich_section_group.tsx @@ -18,6 +18,8 @@ import React, { ReactElement } from "react"; +import { ArrowOutward } from "../../../../components/elements/icons/arrow_outward"; +import { RssFeed } from "../../../../components/elements/icons/rss_feed"; import { GA_EVENT_HEADER_CLICK, GA_PARAM_ID, @@ -67,10 +69,14 @@ const MenuRichSectionGroup = ({ tabIndex={tabIndex} > {item.linkType === "external" && ( - arrow_outward + + + )} {item.linkType === "rss" && ( - rss_feed + + + )} {item.title} diff --git a/static/js/components/elements/icons/arrow_back.tsx b/static/js/components/elements/icons/arrow_back.tsx new file mode 100644 index 0000000000..6e57c2adbe --- /dev/null +++ b/static/js/components/elements/icons/arrow_back.tsx @@ -0,0 +1,37 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Arrow Back + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const ArrowBack = ( + props: React.SVGProps +): ReactElement => ( + + + +); diff --git a/static/js/components/elements/icons/arrow_forward.tsx b/static/js/components/elements/icons/arrow_forward.tsx index e4845b2a58..d3dde3eb19 100644 --- a/static/js/components/elements/icons/arrow_forward.tsx +++ b/static/js/components/elements/icons/arrow_forward.tsx @@ -26,10 +26,10 @@ export const ArrowForward = ( ): ReactElement => ( diff --git a/static/js/components/elements/icons/arrow_outward.tsx b/static/js/components/elements/icons/arrow_outward.tsx new file mode 100644 index 0000000000..b64a4e9296 --- /dev/null +++ b/static/js/components/elements/icons/arrow_outward.tsx @@ -0,0 +1,37 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Arrow Outward + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const ArrowOutward = ( + props: React.SVGProps +): ReactElement => ( + + + +); diff --git a/static/js/components/elements/icons/close.tsx b/static/js/components/elements/icons/close.tsx new file mode 100644 index 0000000000..d8be4a0667 --- /dev/null +++ b/static/js/components/elements/icons/close.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Close + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const Close = (props: React.SVGProps): ReactElement => ( + + + +); diff --git a/static/js/components/elements/icons/icon.tsx b/static/js/components/elements/icons/icon.tsx index d7a1960f39..64746c7b93 100644 --- a/static/js/components/elements/icons/icon.tsx +++ b/static/js/components/elements/icons/icon.tsx @@ -42,7 +42,7 @@ export const Icon = ({ width={size} height={size} fill={color} - path={color} + stroke={color} {...props} /> ); diff --git a/static/js/components/elements/icons/keyboard_arrow_down.tsx b/static/js/components/elements/icons/keyboard_arrow_down.tsx index 8a2076c09d..e31d6c3702 100644 --- a/static/js/components/elements/icons/keyboard_arrow_down.tsx +++ b/static/js/components/elements/icons/keyboard_arrow_down.tsx @@ -26,10 +26,10 @@ export const KeyboardArrowDown = ( ): ReactElement => ( diff --git a/static/js/components/elements/icons/menu.tsx b/static/js/components/elements/icons/menu.tsx new file mode 100644 index 0000000000..29d8415c9f --- /dev/null +++ b/static/js/components/elements/icons/menu.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Menu + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const Menu = (props: React.SVGProps): ReactElement => ( + + + +); diff --git a/static/js/components/elements/icons/rss_feed.tsx b/static/js/components/elements/icons/rss_feed.tsx new file mode 100644 index 0000000000..c78f97be8a --- /dev/null +++ b/static/js/components/elements/icons/rss_feed.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Rss Feed + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const RssFeed = (props: React.SVGProps): ReactElement => ( + + + +); From 64768739890e4d49630ff63cc2036434c43beabf Mon Sep 17 00:00:00 2001 From: Nick B Date: Sat, 16 Nov 2024 11:12:37 -0800 Subject: [PATCH 4/7] Introduction of SVG icon macros to allow inline icons to be included directly into jinja templates (with the goal in mind of extending this ability to use flash-less icons to the templates). This parallels the React icon components. --- server/templates/macros/icons.html | 47 +++++++++++++++++++ server/templates/place.html | 9 ++-- .../resources/icons/progress_activity.svg | 1 + static/css/place/place.scss | 1 + 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 server/templates/macros/icons.html create mode 100644 server/templates/resources/icons/progress_activity.svg diff --git a/server/templates/macros/icons.html b/server/templates/macros/icons.html new file mode 100644 index 0000000000..a80787f0ac --- /dev/null +++ b/server/templates/macros/icons.html @@ -0,0 +1,47 @@ +{# +Copyright 2024 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +#} + +{# +A macro for inline insertion of svg icons into the templates. +Inline insertion avoids the potential for flashes the of content +that can occur with the font version of Material icons. + +Parameters: + + name: icon file name. + Must match the name of an SVG file (without extension) located in: + server/templates/resources/icons. + eg. "progress_activity" + +Example usage: + +{% from 'macros/icons.html' import inline_svg %} +{{ inline_svg('progress_activity') }} + +Adding icons: + To add a new icon, copy the SVG into /server/templates/resources/icons. + Although icons are not strictly limited to Material UI icons, these are + recommended for consistency and cohesiveness. Material icons may be + downloaded from: https://fonts.google.com/icons + + The SVG must have a width and height of "1em" and a fill of "currentColor" + to allow styling via CSS. +#} + +{% macro inline_svg(name) %} +{% set svg_path = 'resources/icons/' + name + '.svg' %} +{% include svg_path %} +{% endmacro %} \ No newline at end of file diff --git a/server/templates/place.html b/server/templates/place.html index 5c2ff0336c..61a43f2f3b 100644 --- a/server/templates/place.html +++ b/server/templates/place.html @@ -15,6 +15,8 @@ #} {%- extends BASE_HTML -%} +{% from 'macros/icons.html' import inline_svg %} + {% set main_id = 'dc-places' %} {% set page_id = 'page-dc-places' %} {% if category == '' %} @@ -68,10 +70,9 @@

{{ place_summary }}
- {# TRANSLATORS: A message shown on the page while the content is loading. #} -
- {# SVG: Material Icon: Progress Activity, Source: https://fonts.google.com/icons #} - +
+ {{ inline_svg('progress_activity') }} + {# TRANSLATORS: A message shown on the page while the content is loading. #}

{% trans %}Loading{% endtrans %}

diff --git a/server/templates/resources/icons/progress_activity.svg b/server/templates/resources/icons/progress_activity.svg new file mode 100644 index 0000000000..198bcb3a35 --- /dev/null +++ b/server/templates/resources/icons/progress_activity.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/css/place/place.scss b/static/css/place/place.scss index a1063304b9..b9bd128a46 100644 --- a/static/css/place/place.scss +++ b/static/css/place/place.scss @@ -82,6 +82,7 @@ h3 { align-items: center; gap: 8px; svg { + font-size: 24px; animation: rotating 2s linear infinite; } p { From e292867d113994b71e76979d369339aabe111eec Mon Sep 17 00:00:00 2001 From: Nick B Date: Sun, 17 Nov 2024 11:48:53 -0800 Subject: [PATCH 5/7] Simplified the direct use of the icons by removing the width attribute (allowing the icon to be sized without the need for the wrapper component). Removed the wrapper component. Converted the search bar icons to direct SVGs. --- server/templates/macros/icons.html | 2 +- .../resources/icons/progress_activity.svg | 2 +- static/css/core.scss | 8 +++ .../components/header_bar/menu_desktop.tsx | 7 +-- static/js/components/content/link_chips.tsx | 3 +- .../components/elements/icons/arrow_back.tsx | 1 - .../elements/icons/arrow_forward.tsx | 1 - .../elements/icons/arrow_outward.tsx | 1 - static/js/components/elements/icons/close.tsx | 1 - static/js/components/elements/icons/icon.tsx | 49 ------------------- .../elements/icons/keyboard_arrow_down.tsx | 1 - static/js/components/elements/icons/menu.tsx | 1 - .../js/components/elements/icons/rss_feed.tsx | 1 - .../js/components/elements/icons/search.tsx | 34 +++++++++++++ .../nl_search_bar/auto_complete_input.tsx | 10 ++-- 15 files changed, 52 insertions(+), 70 deletions(-) delete mode 100644 static/js/components/elements/icons/icon.tsx create mode 100644 static/js/components/elements/icons/search.tsx diff --git a/server/templates/macros/icons.html b/server/templates/macros/icons.html index a80787f0ac..47f0af21b0 100644 --- a/server/templates/macros/icons.html +++ b/server/templates/macros/icons.html @@ -37,7 +37,7 @@ recommended for consistency and cohesiveness. Material icons may be downloaded from: https://fonts.google.com/icons - The SVG must have a width and height of "1em" and a fill of "currentColor" + The SVG must have a height of "1em", no width and a fill of "currentColor" to allow styling via CSS. #} diff --git a/server/templates/resources/icons/progress_activity.svg b/server/templates/resources/icons/progress_activity.svg index 198bcb3a35..4395eec9b9 100644 --- a/server/templates/resources/icons/progress_activity.svg +++ b/server/templates/resources/icons/progress_activity.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/static/css/core.scss b/static/css/core.scss index cafd4913d2..0158b4e6df 100644 --- a/static/css/core.scss +++ b/static/css/core.scss @@ -625,6 +625,11 @@ section { border: none; border-color: var(--gm-3-ref-neutral-neutral-40); + .search-icon { + font-size: 24px; + line-height: 1; + } + .search-bar-content { display: flex; flex-wrap: nowrap; @@ -638,6 +643,9 @@ section { display: flex; align-items: center; color: #f1f1f1; + svg { + font-size: 24px; + } } .search-input-text { diff --git a/static/js/apps/base/components/header_bar/menu_desktop.tsx b/static/js/apps/base/components/header_bar/menu_desktop.tsx index cbe90b8645..8aacb840b1 100644 --- a/static/js/apps/base/components/header_bar/menu_desktop.tsx +++ b/static/js/apps/base/components/header_bar/menu_desktop.tsx @@ -18,7 +18,6 @@ import React, { ReactElement, useEffect, useRef, useState } from "react"; -import { Icon } from "../../../../components/elements/icons/icon"; import { KeyboardArrowDown } from "../../../../components/elements/icons/keyboard_arrow_down"; import { GA_EVENT_HEADER_CLICK, @@ -140,11 +139,7 @@ const MenuDesktop = ({ openMenu === index ? "open" : "" }`} > - +
- + {linkChip.title} diff --git a/static/js/components/elements/icons/arrow_back.tsx b/static/js/components/elements/icons/arrow_back.tsx index 6e57c2adbe..04ce84233d 100644 --- a/static/js/components/elements/icons/arrow_back.tsx +++ b/static/js/components/elements/icons/arrow_back.tsx @@ -28,7 +28,6 @@ export const ArrowBack = ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/arrow_forward.tsx b/static/js/components/elements/icons/arrow_forward.tsx index d3dde3eb19..0ae52d497c 100644 --- a/static/js/components/elements/icons/arrow_forward.tsx +++ b/static/js/components/elements/icons/arrow_forward.tsx @@ -28,7 +28,6 @@ export const ArrowForward = ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/arrow_outward.tsx b/static/js/components/elements/icons/arrow_outward.tsx index b64a4e9296..e47d845cea 100644 --- a/static/js/components/elements/icons/arrow_outward.tsx +++ b/static/js/components/elements/icons/arrow_outward.tsx @@ -28,7 +28,6 @@ export const ArrowOutward = ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/close.tsx b/static/js/components/elements/icons/close.tsx index d8be4a0667..9a4614d3d6 100644 --- a/static/js/components/elements/icons/close.tsx +++ b/static/js/components/elements/icons/close.tsx @@ -26,7 +26,6 @@ export const Close = (props: React.SVGProps): ReactElement => ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/icon.tsx b/static/js/components/elements/icons/icon.tsx deleted file mode 100644 index 64746c7b93..0000000000 --- a/static/js/components/elements/icons/icon.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * A component to simplify the interface of SVGs, providing - * simpler wrapping for commonly-used props for inline icons. - */ - -import React, { ReactElement, SVGProps } from "react"; - -interface IconProps extends SVGProps { - //The SVG icon to be rendered by the icon component - icon: (props: SVGProps) => ReactElement; - //The color of the SVG icon. If a color is not provided, this will be the - //color of the containing element. - color?: string; - //the size of the icon. If not provided, this will default to 1em. - size?: number | string; -} - -export const Icon = ({ - icon: IconComponent, - color = "currentColor", - size = "1em", - ...props -}: IconProps): ReactElement | null => { - return ( - - ); -}; diff --git a/static/js/components/elements/icons/keyboard_arrow_down.tsx b/static/js/components/elements/icons/keyboard_arrow_down.tsx index e31d6c3702..8ee820b6b0 100644 --- a/static/js/components/elements/icons/keyboard_arrow_down.tsx +++ b/static/js/components/elements/icons/keyboard_arrow_down.tsx @@ -28,7 +28,6 @@ export const KeyboardArrowDown = ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/menu.tsx b/static/js/components/elements/icons/menu.tsx index 29d8415c9f..d07d0ed3b2 100644 --- a/static/js/components/elements/icons/menu.tsx +++ b/static/js/components/elements/icons/menu.tsx @@ -26,7 +26,6 @@ export const Menu = (props: React.SVGProps): ReactElement => ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/rss_feed.tsx b/static/js/components/elements/icons/rss_feed.tsx index c78f97be8a..7e4739247b 100644 --- a/static/js/components/elements/icons/rss_feed.tsx +++ b/static/js/components/elements/icons/rss_feed.tsx @@ -26,7 +26,6 @@ export const RssFeed = (props: React.SVGProps): ReactElement => ( xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" - width="1em" fill="currentColor" {...props} > diff --git a/static/js/components/elements/icons/search.tsx b/static/js/components/elements/icons/search.tsx new file mode 100644 index 0000000000..3ff85e8405 --- /dev/null +++ b/static/js/components/elements/icons/search.tsx @@ -0,0 +1,34 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Material Icon: Search + * Source: https://fonts.google.com/icons + */ + +import React, { ReactElement } from "react"; + +export const Search = (props: React.SVGProps): ReactElement => ( + + + +); diff --git a/static/js/components/nl_search_bar/auto_complete_input.tsx b/static/js/components/nl_search_bar/auto_complete_input.tsx index 10f41ee709..fcf1491915 100644 --- a/static/js/components/nl_search_bar/auto_complete_input.tsx +++ b/static/js/components/nl_search_bar/auto_complete_input.tsx @@ -40,6 +40,8 @@ import { useInsideClickAlerter, useOutsideClickAlerter, } from "../../utils/click_alerter"; +import { ArrowForward } from "../elements/icons/arrow_forward"; +import { Search } from "../elements/icons/search"; import { AutoCompleteSuggestions } from "./auto_complete_suggestions"; const DEBOUNCE_INTERVAL_MS = 100; @@ -297,7 +299,9 @@ export function AutoCompleteInput( > {isHeaderBar && ( - search + + + )}
- {isHeaderBar && ( - arrow_forward - )} + {isHeaderBar && }
From f23caa0217099deed8154770a2eb0f9eaf396d0c Mon Sep 17 00:00:00 2001 From: Nick B Date: Mon, 18 Nov 2024 20:48:13 -0800 Subject: [PATCH 6/7] Addition of a script to facilitate the creation of the Material Design icons (either in React component or SVG form or both). This commit also includes documentation added to the developer guide and separate documentation describing how to use the script, how to create icons manually if required and how to use the icons in either React or the templates. --- docs/developer_guide.md | 8 + .../resources/icons/progress_activity.svg | 2 +- .../elements/icons/keyboard_arrow_down.tsx | 7 +- tools/resources/README.md | 111 +++++++++++ tools/resources/component_template.txt | 32 ++++ tools/resources/generate_icon.py | 181 ++++++++++++++++++ 6 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 tools/resources/README.md create mode 100644 tools/resources/component_template.txt create mode 100644 tools/resources/generate_icon.py diff --git a/docs/developer_guide.md b/docs/developer_guide.md index 5546fe8422..7c1054d8e8 100644 --- a/docs/developer_guide.md +++ b/docs/developer_guide.md @@ -352,3 +352,11 @@ the same region. ### Testing cloudbuild changes To test .yaml cloudbuild files, you can use cloud-build-local to dry run the file before actually pushing. Find documentation for how to install and use cloud-build-local [here](https://github.com/GoogleCloudPlatform/cloud-build-local). + +### Inline Icons + +The Data Commons site makes use of Material Design icons. In certain cases, font-based Material Design icon usage can result in +flashes of unstyled content that can be avoided by using SVG icons. + +We have provided tools to facilitate the creation and use of Material SVG icons in both the Jinja template and in React components. +For instructions on how to generate and use these SVGs and components, please see: [Icon Readme](../tools/resources/README.md): diff --git a/server/templates/resources/icons/progress_activity.svg b/server/templates/resources/icons/progress_activity.svg index 4395eec9b9..5458368a90 100644 --- a/server/templates/resources/icons/progress_activity.svg +++ b/server/templates/resources/icons/progress_activity.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/static/js/components/elements/icons/keyboard_arrow_down.tsx b/static/js/components/elements/icons/keyboard_arrow_down.tsx index 8ee820b6b0..d1246e7970 100644 --- a/static/js/components/elements/icons/keyboard_arrow_down.tsx +++ b/static/js/components/elements/icons/keyboard_arrow_down.tsx @@ -14,9 +14,14 @@ * limitations under the License. */ +/* + * Autogenerated by generate_icon.py + * + */ + /* * Material Icon: Keyboard Arrow Down - * Source: https://fonts.google.com/icons + * Source: https://github.com/google/material-design-icons */ import React, { ReactElement } from "react"; diff --git a/tools/resources/README.md b/tools/resources/README.md new file mode 100644 index 0000000000..c2c2f7d3e0 --- /dev/null +++ b/tools/resources/README.md @@ -0,0 +1,111 @@ +# Data Commons Material UI Icon Generation Tool + +## Produce via script + +A python script is provided to quickly and easily generate a React component +that displays a Material UI Icon, an SVG of a Material UI icon for use in the +Jinja templates or both. + +### Script Usage + +To generate both a React component and an SVG of a Material UI icon, run the +following command: + +```bash +python3 generate_icon.py {icon_name} +```` + +For example: + +```bash +python3 generate_icon.py arrow_forward +```` + +This will download the SVG from the Material UI repository, process it and +generate two files: +- An SVG for use in Jinja templates in the `server/templates/resources/icons` + directory. +- A React component in `static/js/components/elements/icons`. + +To generate only the SVG for the templates, run either of the following commands: + +```bash +python3 generate_icon.py -f arrow_forward +python3 generate_icon.py --flask arrow_forward +``` + +To generate only the React component run either of the following commands: + +```bash +python3 generate_icon.py -r arrow_forward +python3 generate_icon.py --react arrow_forward +``` + +It is recommended to run the prettier on the generated `.tsx` file. + +## Produce manually + +If for any reason you need to generate an icon manually (for example, if an icon +is not available from the repository via the script), you can do so with these +directions. Note that this should only rarely be required. +1. Download the SVG. If it is a Material UI font, it will likely come from + https://fonts.google.com/icons +2. Change the height to "1em". Change the fill to "currentColor". Remove the width. +3. For use in the Jinja templates, copy this SVG into `server/templates/resources/icons`. +4. For use as a React component + 1. open an existing component in `static/js/components/elements/icons`, and save it + with the new icon's name. + 2. Update the source to indicate the source of the SVG you are using. This might + be https://fonts.google.com/icons. + 3. Update the name in the comments. + 4. Paste the SVG over top of the old SVG. + 5. Add {...props} as the final prop in the SVG before the `>`. + +## Usage + +### Jinja Templates + +To use a generated icon in a Jinja template + +``` +{% from 'macros/icons.html' import inline_svg %} + +{{ inline_svg('arrow_forward') }} +``` + +### React + +You can use the React component directly inside the JSX: + +```jsx + +``` + +If done so without explicitly providing color and size, the icon +will inherit its color and size from the enclosing CSS, just as a +font icon would. For example: + +```css +span.big-red-icon { + font-size: 50px; + color: red; +} +``` +```jsx + + + +``` +This allows you to use the React component icons much as you would the Material +Icons provided through Google Fonts, with the added advantage that they are inline +and not subject to flashes of unstyled content. + +You can also style the icons directly with its props. Each added icon +component can take any prop that you can send into an SVG. + +```jsx + +``` \ No newline at end of file diff --git a/tools/resources/component_template.txt b/tools/resources/component_template.txt new file mode 100644 index 0000000000..060d6831ba --- /dev/null +++ b/tools/resources/component_template.txt @@ -0,0 +1,32 @@ +/** + * Copyright {{ year }} Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Autogenerated by generate_icon.py + */ + +/* + * Material Icon: {{ icon name }} + * Source: https://github.com/google/material-design-icons + */ + +import React, { ReactElement } from "react"; + +export const {{ icon component name }} = ( + props: React.SVGProps +): ReactElement => ( + {{ svg }} +); \ No newline at end of file diff --git a/tools/resources/generate_icon.py b/tools/resources/generate_icon.py new file mode 100644 index 0000000000..b380316c01 --- /dev/null +++ b/tools/resources/generate_icon.py @@ -0,0 +1,181 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script imports a Material Design icon by name in snake_case. (e.g. chevron_left). +# The name of the icon is provided as a parameter. +# With the -r or --react flag, only the React component will be created. +# With the -f or --flask flag, the version for use in the Jinja templates will be created +# With no flag given, both will be created. + +import argparse +from datetime import datetime +import os +import sys +import xml.etree.ElementTree as ET + +import requests + + +def parse_arguments(): + parser = argparse.ArgumentParser( + description= + 'Download and generate Material Design icons for use in Jinja templates and as React components.' + ) + parser.add_argument( + 'icon_name', + type=str, + help='Name of the icon in snake_case (e.g., chevron_left)') + parser.add_argument('-r', + '--react', + action='store_true', + help='Generate only the React component version') + parser.add_argument( + '-f', + '--flask', + action='store_true', + help='Generate only the SVG version for use in Jinja templates') + return parser.parse_args() + + +def convert_snake_to_camel(icon_name): + components = icon_name.split('_') + return ''.join(x.capitalize() for x in components) + + +def convert_snake_to_title(icon_name): + components = icon_name.split('_') + return ' '.join(x.capitalize() for x in components) + + +def download_svg(icon_name): + """ + Downloads the requested SVG from the Material Design icon repository. + """ + base_url = 'https://raw.githubusercontent.com/google/material-design-icons/refs/heads/master/symbols/web' + svg_url = f'{base_url}/{icon_name}/materialsymbolsoutlined/{icon_name}_24px.svg' + + print(f'Downloading SVG from: {svg_url}') + response = requests.get(svg_url) + if response.status_code == 200: + print('SVG download complete.') + return response.text + else: + print(f'Error: Failed to download SVG. Status Code: {response.status_code}') + return None + + +def process_svg(svg_content): + """ + Processes the SVG content to prepare to allow it to be styled through CSS similar to how a font is + """ + + ET.register_namespace('', "http://www.w3.org/2000/svg") + + try: + root = ET.fromstring(svg_content) + except ET.ParseError as e: + print(f'Error parsing SVG: {e}') + return None + + if 'width' in root.attrib: + del root.attrib['width'] + + root.set('height', '1em') + + root.set('fill', 'currentColor') + + for elem in root.iter(): + if 'fill' in elem.attrib: + elem.set('fill', 'currentColor') + + processed_svg = ET.tostring(root, encoding='unicode') + return processed_svg + + +def save_svg(svg_content, output_path): + os.makedirs(os.path.dirname(output_path), exist_ok=True) + with open(output_path, 'w', encoding='utf-8') as f: + f.write(svg_content) + print(f'Saved SVG to {output_path}') + + +def generate_react_component(icon_name, svg_content, react_dir, template_path): + """ + Generates a React .tsx component for the icon based on the template found in "component_template.txt" + """ + component_name = convert_snake_to_camel(icon_name) + icon_title = convert_snake_to_title(icon_name) + current_year = datetime.now().year + try: + with open(template_path, 'r', encoding='utf-8') as template_file: + template = template_file.read() + except FileNotFoundError: + print(f'Error: Template file not found at {template_path}.') + return + + svg_tag_start = svg_content.find('', svg_tag_start) + + # We need to add {...props} so the props of the SVG can be overridden by the component. + svg_with_props = (svg_content[:svg_tag_end] + ' {...props}' + + svg_content[svg_tag_end:]) + + component = template.replace('{{ year }}', str(current_year)) + component = component.replace('{{ icon name }}', icon_title) + component = component.replace('{{ icon component name }}', component_name) + component = component.replace('{{ svg }}', svg_with_props) + + component_file_name = f'{icon_name}.tsx' + component_path = os.path.join(react_dir, component_file_name) + + with open(component_path, 'w', encoding='utf-8') as f: + f.write(component) + print(f'Generated React component at {component_path}') + + +def main(): + args = parse_arguments() + icon_name = args.icon_name.lower() + generate_react_svg = args.react or not (args.react or args.flask) + generate_flask_svg = args.flask or not (args.react or args.flask) + + script_dir = os.path.dirname(os.path.abspath(__file__)) + root_dir = os.path.abspath(os.path.join(script_dir, '..', '..')) + + html_icons_dir = os.path.join(root_dir, 'server', 'templates', 'resources', + 'icons') + react_icons_dir = os.path.join(root_dir, 'static', 'js', 'components', + 'elements', 'icons') + + template_path = os.path.join(script_dir, 'component_template.txt') + + svg_content = download_svg(icon_name) + if not svg_content: + sys.exit(1) + + processed_svg = process_svg(svg_content) + if not processed_svg: + sys.exit(1) + + if generate_flask_svg: + html_svg_path = os.path.join(html_icons_dir, f'{icon_name}.svg') + save_svg(processed_svg, html_svg_path) + + if generate_react_svg: + generate_react_component(icon_name, processed_svg, react_icons_dir, + template_path) + + +if __name__ == '__main__': + main() From 47e8ea761345ff427753d24b6f21e25dd8152c56 Mon Sep 17 00:00:00 2001 From: Nick B Date: Tue, 19 Nov 2024 16:39:24 -0800 Subject: [PATCH 7/7] Creation of a requirements.txt file for the python library and a run.sh bash script that installs those requirements in a venv and runs the script. --- docs/developer_guide.md | 2 +- tools/resources/{ => icons}/README.md | 14 ++++++------- .../{ => icons}/component_template.txt | 0 tools/resources/{ => icons}/generate_icon.py | 2 +- tools/resources/icons/requirements.txt | 1 + tools/resources/icons/run.sh | 20 +++++++++++++++++++ 6 files changed, 30 insertions(+), 9 deletions(-) rename tools/resources/{ => icons}/README.md (91%) rename tools/resources/{ => icons}/component_template.txt (100%) rename tools/resources/{ => icons}/generate_icon.py (99%) create mode 100644 tools/resources/icons/requirements.txt create mode 100755 tools/resources/icons/run.sh diff --git a/docs/developer_guide.md b/docs/developer_guide.md index 7c1054d8e8..c94395869c 100644 --- a/docs/developer_guide.md +++ b/docs/developer_guide.md @@ -359,4 +359,4 @@ The Data Commons site makes use of Material Design icons. In certain cases, font flashes of unstyled content that can be avoided by using SVG icons. We have provided tools to facilitate the creation and use of Material SVG icons in both the Jinja template and in React components. -For instructions on how to generate and use these SVGs and components, please see: [Icon Readme](../tools/resources/README.md): +For instructions on how to generate and use these SVGs and components, please see: [Icon Readme](../tools/resources/icons/README.md): diff --git a/tools/resources/README.md b/tools/resources/icons/README.md similarity index 91% rename from tools/resources/README.md rename to tools/resources/icons/README.md index c2c2f7d3e0..d88701c769 100644 --- a/tools/resources/README.md +++ b/tools/resources/icons/README.md @@ -9,16 +9,16 @@ Jinja templates or both. ### Script Usage To generate both a React component and an SVG of a Material UI icon, run the -following command: +following command from inside the `tools/resources/icons` directory: ```bash -python3 generate_icon.py {icon_name} +./run.sh {icon_name} ```` For example: ```bash -python3 generate_icon.py arrow_forward +./run.sh arrow_forward ```` This will download the SVG from the Material UI repository, process it and @@ -30,15 +30,15 @@ generate two files: To generate only the SVG for the templates, run either of the following commands: ```bash -python3 generate_icon.py -f arrow_forward -python3 generate_icon.py --flask arrow_forward +./run.sh -f arrow_forward +./run.sh --flask arrow_forward ``` To generate only the React component run either of the following commands: ```bash -python3 generate_icon.py -r arrow_forward -python3 generate_icon.py --react arrow_forward +./run.sh -r arrow_forward +./run.sh --react arrow_forward ``` It is recommended to run the prettier on the generated `.tsx` file. diff --git a/tools/resources/component_template.txt b/tools/resources/icons/component_template.txt similarity index 100% rename from tools/resources/component_template.txt rename to tools/resources/icons/component_template.txt diff --git a/tools/resources/generate_icon.py b/tools/resources/icons/generate_icon.py similarity index 99% rename from tools/resources/generate_icon.py rename to tools/resources/icons/generate_icon.py index b380316c01..92d7084cbe 100644 --- a/tools/resources/generate_icon.py +++ b/tools/resources/icons/generate_icon.py @@ -151,7 +151,7 @@ def main(): generate_flask_svg = args.flask or not (args.react or args.flask) script_dir = os.path.dirname(os.path.abspath(__file__)) - root_dir = os.path.abspath(os.path.join(script_dir, '..', '..')) + root_dir = os.path.abspath(os.path.join(script_dir, '..', '..', '..')) html_icons_dir = os.path.join(root_dir, 'server', 'templates', 'resources', 'icons') diff --git a/tools/resources/icons/requirements.txt b/tools/resources/icons/requirements.txt new file mode 100644 index 0000000000..077c95d8a4 --- /dev/null +++ b/tools/resources/icons/requirements.txt @@ -0,0 +1 @@ +requests==2.31.0 \ No newline at end of file diff --git a/tools/resources/icons/run.sh b/tools/resources/icons/run.sh new file mode 100755 index 0000000000..418d9beb42 --- /dev/null +++ b/tools/resources/icons/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +python3 -m venv .env +source .env/bin/activate +python3 -m pip install --upgrade pip +pip3 install -r requirements.txt +python3 generate_icon.py "$@"