-
Notifications
You must be signed in to change notification settings - Fork 55
feat(theme): add font icons support for themes #243
feat(theme): add font icons support for themes #243
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
src/lib/renderComponent.tsx
Outdated
@@ -120,7 +122,8 @@ const renderComponent = <P extends {}>( | |||
}: IThemeInput | IThemePrepared = {}) => { | |||
const ElementType = getElementType({ defaultProps }, props) | |||
|
|||
const stateAndProps = { ...state, ...props } | |||
const derivedProps = getExtraProps({ icons }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So derivedProps
or extraProps
?
src/components/Icon/Icon.tsx
Outdated
return this.props.svg | ||
? this.renderSvgIcon(ElementType, icons, classes, rest, accessibility) | ||
: this.renderFontIcon(ElementType, classes, rest, accessibility) | ||
return this.isFontBased(icons) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the fact that you do similar calculation to what you've already done in getExtraProps()
. Primarily not because of the performance but because for me (as a component developer) it is difficult to understand what the extraProps
are good for - they are used to calculate styles, accessibility... why there are not used to render the component?
renderComponent()
should receive extraProps
as a parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, we can remove getExtraProps
entirely if we check the type of the icon instead. To limit the number of ideas and patterns in the library, I propose we also allow values or functions (as with variables and styles):
const icons = {
// value form
umbrella: <svg></svg>,
user: { fontFamily: 'Icons', content: "\\f0152" },
// function form
umbrella: () => <svg></svg>,
user: () => ({ fontFamily: 'Icons', content: "\\f0152" }),
}
React.isValidElement(callable(icons.umbrella)()) ? isSVG : isFONT
This would allow us to pass values to the icon later. It also removes the need for the getExtraProps
function.
src/components/Icon/Icon.tsx
Outdated
@@ -130,10 +136,26 @@ class Icon extends UIComponent<Extendable<IIconProps>, any> { | |||
) | |||
} | |||
|
|||
isFontBased(themeIcons: ThemeIcons): boolean { | |||
const { name } = this.props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: from the function signature, it is not obvious that it checks current icon (in this).
I would change the signature to isFontBased(name, themeIcons)
src/components/Icon/Icon.tsx
Outdated
fontIconFromTheme: isFontBased && icons[this.props.name], | ||
} | ||
} | ||
|
||
renderComponent({ ElementType, classes, rest, accessibility, icons }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propose we pass the entire theme
to renderComponent
as it is more generic and seems more useful in a wider range of scenarios. Icons alone probably are not that useful to many other components.
Codecov Report
@@ Coverage Diff @@
## feat/themable-icons #243 +/- ##
=======================================================
- Coverage 91.78% 91.32% -0.46%
=======================================================
Files 60 60
Lines 1035 1038 +3
Branches 132 154 +22
=======================================================
- Hits 950 948 -2
- Misses 82 86 +4
- Partials 3 4 +1
Continue to review full report at Codecov.
|
agreed with @miroslavstastny to reduce amount of style parts exposed for SVG icons to absolute necessary minimum (instead of |
@@ -103,7 +98,9 @@ const iconStyles = { | |||
width: '1em', | |||
height: '1em', | |||
|
|||
...(isFontBased ? getFontStyles(font, name, size) : {}), | |||
...(isFontBased |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simplify this one
types/theme.d.ts
Outdated
export type RenderSvgIconFunction = (classes: Classes) => React.ReactNode | ||
type SvgIconFuncArg = { | ||
classes: Classes | ||
props: any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
props
should be eliminated for now
* add SVG icons to teams theme * udpate theme icons api, add example enumerating icons * generalize API for svg and font-based icons * feat(theme): add font icons support for themes (#243) * generalize API for svg and font-based icons * remove 'svg' prop in IconSet example * add mechanism for providing font-based icons in theme * fix UTs * remove getExtraProps method * fix theme icons example in docs * generalize object and function types as icon descriptors * fix unit tests * address review comments * fix lint issues * fix import statement * replace helper methods * remove 'derivedProps' from renderer * remove unused styles for SVG paths * address review comments * fix lint issues * changelog
This PR is introduced as one of the steps necessary to address #230.
Overview
Support for font icons is introduced for themes, icon types are generalized (no need to specify
svg
prop to switch between SVG and font-based icons).API changes for SVG icons
Before
Now
Font icons support for themes
Theme authors are able to introduce custom set of icons, both font-based and SVGs are supported.