-
Notifications
You must be signed in to change notification settings - Fork 53
Conversation
Codecov Report
@@ Coverage Diff @@
## master #33 +/- ##
=======================================
Coverage 88.37% 88.37%
=======================================
Files 47 47
Lines 774 774
Branches 101 110 +9
=======================================
Hits 684 684
Misses 87 87
Partials 3 3
Continue to review full report at Codecov.
|
@mnajdova will take over, it's probably good to go as is |
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.
thank you 👍
src/components/Avatar/avatarRules.ts
Outdated
@@ -1,5 +1,5 @@ | |||
import { pxToRem } from '../../lib' | |||
import { PositionProperty } from '../../../node_modules/csstype' | |||
import { PositionProperty } from 'csstype' |
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.
+1, thanks for fixing this
src/components/Label/Label.tsx
Outdated
} | ||
|
||
static handledProps = ['as', 'children', 'circular', 'className', 'content'] | ||
static handledProps = ['as', 'children', 'circular', 'className', 'content', 'variables'] |
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.
+1
src/lib/UIComponent.tsx
Outdated
class UIComponent<P, S> extends React.Component<P, S> { | ||
export interface UIComponentProps extends HTMLAttributes<HTMLElement> { | ||
as?: string | Function | ||
variables?: (siteVariables: object) => object |
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.
actually, we should make it clear whether plain object could be accepted as value for variables
prop - there are quite a few places where this approach is used now
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.
my vote would be to support both options, due to otherwise we could introduce unnecessary additional complexity for the client of this code in certain cases (where it is about just providing some predefined variables independent of theming aspects)
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 will address this, agreed.
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.
This will go away with #16, which adds typings for all theming concerns:
src/lib/UIComponent.tsx
Outdated
import renderComponent, { IRenderResultConfig } from './renderComponent' | ||
|
||
class UIComponent<P, S> extends React.Component<P, S> { | ||
export interface UIComponentProps extends HTMLAttributes<HTMLElement> { |
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.
This will flood the user's intellisense with a lot of HTML prop noise. That will make it difficult to know which props are for the component specifically.
There have been some community proposals and discussions in SUIR for how to handle typings like this. The current resolution is to include only typings for the props our components specifically handle. See Semantic-Org/Semantic-UI-React#1072.
Beyond this, there is also some desire to have strict typings that do not allow [key: string]: any
. The ideas have not yet been merged, but you can see the need and proposal here: Semantic-Org/Semantic-UI-React#2836
Can we get more information on the issue at hand and how this solves it? I'm not sure this should be merged. |
There were some interfaces added for some of the Components's props, that started complaining when using some props that were not included in the interface (like the variables prop). This is the reason why we added this logic. If we decide not to merge this, then I will create a PR that will delete the usage of the props interfaces for now, and once we have a clear idea how to proceed this, I will return to this. Is this ok? @kuzhelov @levithomason |
I agree with making a step back with the types support, and afterwards make an incremental changes that will steadily introduce this back (starting from the general properties that are library-wide, and moving to component-specific interfaces). While doing that, we should keep an eye on preventing IntelliSense flood, as @levithomason has noticed - as well as ensuring that this won't decrease developer's productivity with false compiler warnings and complains. In general, support @mnajdova proposal on this. |
As a min bar, I think we should include typings for the current props. I don't see a downside to this as it offers intellisense. To avoid the issue of not allowing other props in the typings, we can just add |
@levithomason that's actually a good point, but I would rather wait for the typescript build issues to be resolved first. What do you think? |
I have captured the thoughts here in #117. Let's add typings one component per PR. I'm sure there will be plenty of fixes / discussions on each as we go. |
@Bugaa92 I have scoped this PR to "Accordion" since it is first on the #117 list and I'd like to set precedent for linking PRs to each component there. Would you like to update it to fix Accordion's props per our conclusions? |
# Conflicts: # src/components/Avatar/avatarRules.ts # src/components/Button/Button.tsx # src/components/Icon/Icon.tsx # src/components/Label/Label.tsx # src/components/Text/Text.tsx # src/lib/UIComponent.tsx
Guys, I added initial proposal for the props interface for the Accordion in this PR. Please share your thoughts, and let's use this PR for discussing all aspects of the props interface definitions, so that after this is merged, we can apply the same on the other components as well. cc @Bugaa92 @kuzhelov @smykhailov @miroslavstastny @levithomason |
export interface IAccordionProps extends IAccordionPropsStrict { | ||
[key: string]: 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.
you can try to define following generic type:
type NotStrictProps<T> = T & {
[key: string]: any
}
then you should be able to use:
interface IAccordionPropsStrict {
/** An element type to render as (string or function). */
as?: any
}
type IAccordionProps = NotStrictProps<IAccordionPropsStrict>
const a: IAccordionProps = {}
a.as = 'div'
a.whatever = 'works as well'
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.
Sure, as this is going to be used in all components, it would be good to be extracted as separate type. Thanks!
@@ -8,12 +8,59 @@ import AccordionContent from './AccordionContent' | |||
import { DefaultBehavior } from '../../lib/accessibility' | |||
import { Accessibility } from '../../lib/accessibility/interfaces' | |||
|
|||
export interface IAccordionPropsStrict { | |||
/** An element type to render as (string or function). */ | |||
as?: 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.
I would make a separate interface for as
. Then it could be used in getElementType()
}[] | ||
|
||
/** Accessibility behavior if overridden by the user. */ | ||
accessibility?: object | Function |
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.
accessibility
, styles
, variables
, className
are common for all components, shouldn't we extract them to separate interface. If so, then to how many?
Does the same apply to children
?
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 was thinking about the same thing. For the children, they should be provided even from React itself so I am not sure if we should specify them here at all. Not sure if the same applies for the className as well. For the rest, I would propose having the styles and variables in one interface, because for all themed components both would apply, and having the accessibility in other interface, because I am not sure if it is applicable to all components. We should think about the 'as' property as well. Having this said, I am kind a worry that we would end up with lot's of interfaces, which can become confusing, but at the same time I agree that it could be good for refactoring, if we need to add some common property or rename existing common property in the future for some reason. Any thoughts on this? @kuzhelov @levithomason
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.
agree with the points mentioned above. However, my vote would rather be to do it after strict rtpes will be introduced for all components, so that at this point we will have clear picture around what are the general parts and what are the exceptions/edge cases.
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.
Got it! Will wait then for final approve for this PR in order for it to be merged.
* @param {SyntheticEvent} event - React's original SyntheticEvent. | ||
* @param {object} data - All item props. | ||
*/ | ||
onTitleClick?: Function |
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.
We should be more specific with Function
types.
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.
Fixed
variables?: object | Function | ||
} | ||
|
||
export interface IAccordionProps extends IAccordionPropsStrict { |
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.
actually it can be done in more generic way
type Indexer<T> = { [key: string]: T }
interface IAccordionPropsStrict {
as?: string
...
}
interface IAccordionProps extends Indexer<any>, IAccordionPropsStrict {
}
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 like these approach as being more generic, but I think the NotStrictProps types defined as is is sufficient enough and is more explicit with it's name when defining the not strict props interfaces. I will change the definition if you think that we should go with the Indexer type.
accessibility?: object | Function | ||
|
||
/** Custom styles to be applied for component. */ | ||
styles?: object | Function |
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.
we can use ICSSInJSStyle
to get better typings (instead of object)
/** Custom styles to be applied for component. */
styles?: ICSSInJSStyle | Function
what do u think?
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.
Actually this would be the following form {root: () => ICSSInJSStyle, otherPart: () => ICSSInJSStyle...} so we cannot generalize to just ICSSInJSStyle
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.
Talking about styles, we may be able to define the variables and styles in the following way:
variables?: ComponentVariablesInput
styles?: IComponentPartStylesInput
as these are the types used in the renderComponent. @levithomason am I right about this?
variables?: object | Function | ||
} | ||
|
||
export interface IAccordionProps extends IAccordionPropsStrict { |
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.
can we add this as a prop to extend from in UIComponent.tsx
together with the other common props? (as
, styles
and variables
)?
something like :
export interface UIComponentProps {
[key: string]: any
/** An element type to render as (string or function). */
as?: any
/** Custom styles to be applied for component. */
styles?: ICSSInJSStyle | Function
/** Custom variables to be applied for component. */
variables?: object | Function
}
class UIComponent<P, S> extends React.Component<P & UIComponentProps, S> {
// ...
}
and then we remove these from the particular component interfaces
agreed to decide on where exactly |
Component Interfaces
This PR introduces a fix for
UIComponent
props
to make them work withReact
attributes