Browse Source

Explicitly define available props for components

Add event handler props for components.
tags/0.3.0
TheoryOfNekomata 4 years ago
parent
commit
8ce5a80ba5
10 changed files with 95 additions and 41 deletions
  1. +1
    -1
      lib/components/Button/Button.test.tsx
  2. +29
    -10
      lib/components/Button/Button.tsx
  3. +21
    -2
      lib/components/Checkbox/Checkbox.tsx
  4. +1
    -6
      lib/components/Icon/Icon.tsx
  5. +22
    -6
      lib/components/RadioButton/RadioButton.tsx
  6. +1
    -6
      lib/components/Select/Select.tsx
  7. +7
    -0
      lib/components/Slider/Slider.tsx
  8. +1
    -1
      lib/components/TextInput/TextInput.test.tsx
  9. +1
    -6
      lib/components/TextInput/TextInput.tsx
  10. +11
    -3
      package.json

+ 1
- 1
lib/components/Button/Button.test.tsx View File

@@ -48,7 +48,7 @@ describe('on unknown kinds', () => {

it('should render null', () => {
fc.assert(
fc.property(fc.string().filter(s => !['button', 'a'].includes(s)), (element) => {
fc.property(fc.string().filter((s) => !['button', 'a'].includes(s)), (element) => {
const wrapper = Enzyme.shallow(<Button element={element as ButtonElement} />)

expect(wrapper.isEmptyRender()).toBe(true)


+ 29
- 10
lib/components/Button/Button.tsx View File

@@ -156,6 +156,18 @@ const propTypes = {
* Does the button display a border?
*/
border: PropTypes.bool,
/**
* Event handler triggered when the component is clicked.
*/
onClick: PropTypes.func,
/**
* Event handler triggered when the component receives focus.
*/
onFocus: PropTypes.func,
/**
* Event handler triggered when the component loses focus.
*/
onBlur: PropTypes.func,
}

type Props = PropTypes.InferProps<typeof propTypes>
@@ -173,7 +185,9 @@ const Button = React.forwardRef<HTMLAnchorElement | HTMLButtonElement | HTMLSpan
rel,
type = 'button',
border = false,
...etcProps
onClick,
onFocus,
onBlur,
},
ref,
) => {
@@ -184,12 +198,7 @@ const Button = React.forwardRef<HTMLAnchorElement | HTMLButtonElement | HTMLSpan
}
const buttonContent = (
<React.Fragment>
{
border
&& (
<Border />
)
}
{border && <Border />}
{stringify(children)}
</React.Fragment>
)
@@ -197,26 +206,36 @@ const Button = React.forwardRef<HTMLAnchorElement | HTMLButtonElement | HTMLSpan
switch (element) {
case 'button':
return (
<Base {...etcProps} type={type!} ref={ref as React.Ref<HTMLButtonElement>} disabled={disabled!} style={commonButtonStyles}>
<Base
onClick={onClick as React.EventHandler<React.SyntheticEvent>}
type={type!}
ref={ref as React.Ref<HTMLButtonElement>}
disabled={disabled!}
style={commonButtonStyles}
onFocus={onFocus as React.FocusEventHandler}
onBlur={onBlur as React.FocusEventHandler}
>
{buttonContent}
</Base>
)
case 'a':
if (disabled) {
return (
<DisabledLinkBase {...etcProps} ref={ref as React.Ref<HTMLSpanElement>} style={commonButtonStyles}>
<DisabledLinkBase ref={ref as React.Ref<HTMLSpanElement>} style={commonButtonStyles}>
{buttonContent}
</DisabledLinkBase>
)
}
return (
<LinkBase
{...etcProps}
onClick={onClick as React.EventHandler<React.SyntheticEvent>}
href={href!}
target={target!}
rel={rel!}
ref={ref as React.Ref<HTMLAnchorElement>}
style={commonButtonStyles}
onFocus={onFocus as React.FocusEventHandler}
onBlur={onBlur as React.FocusEventHandler}
>
{buttonContent}
</LinkBase>


+ 21
- 2
lib/components/Checkbox/Checkbox.tsx View File

@@ -123,6 +123,18 @@ const propTypes = {
* Name of the form field associated with this component.
*/
name: PropTypes.string,
/**
* Event handler triggered when the component is toggled.
*/
onChange: PropTypes.func,
/**
* Event handler triggered when the component receives focus.
*/
onFocus: PropTypes.func,
/**
* Event handler triggered when the component loses focus.
*/
onBlur: PropTypes.func,
}

type Props = PropTypes.InferProps<typeof propTypes>
@@ -133,10 +145,17 @@ type Props = PropTypes.InferProps<typeof propTypes>
* @see {@link RadioButton} for a similar component on selecting a single value among very few choices.
* @type {React.ComponentType<{readonly label?: string} & React.ClassAttributes<unknown>>}
*/
const Checkbox = React.forwardRef<HTMLInputElement, Props>(({ label = '', name, }, ref) => (
const Checkbox = React.forwardRef<HTMLInputElement, Props>(({ label = '', name, onChange, onFocus, onBlur }, ref) => (
<Base>
<CaptureArea>
<Input ref={ref} type="checkbox" name={name!} />
<Input
ref={ref}
type="checkbox"
name={name!}
onChange={onChange as React.ChangeEventHandler}
onFocus={onFocus as React.FocusEventHandler}
onBlur={onBlur as React.FocusEventHandler}
/>
<IndicatorWrapper>
<Border />
<Indicator>


+ 1
- 6
lib/components/Icon/Icon.tsx View File

@@ -43,12 +43,7 @@ const propTypes = {

type Props = PropTypes.InferProps<typeof propTypes>

const Icon: React.FC<Props> = ({
name,
weight = '0.125rem',
size = '1.5rem',
label = name,
}) => {
const Icon: React.FC<Props> = ({ name, weight = '0.125rem', size = '1.5rem', label = name }) => {
const iconName = pascalCase(name, { transform: pascalCaseTransformMerge })
const { [iconName as keyof typeof FeatherIcon]: TheIcon = null } = FeatherIcon
const { magnitude: sizeValue, unit: sizeUnit } = splitValueAndUnit(size)


+ 22
- 6
lib/components/RadioButton/RadioButton.tsx View File

@@ -121,6 +121,18 @@ const propTypes = {
* Short textual description indicating the nature of the component's value.
*/
label: PropTypes.any,
/**
* Event handler triggered when the component is selected.
*/
onChange: PropTypes.func,
/**
* Event handler triggered when the component receives focus.
*/
onFocus: PropTypes.func,
/**
* Event handler triggered when the component loses focus.
*/
onBlur: PropTypes.func,
}

type Props = PropTypes.InferProps<typeof propTypes>
@@ -132,13 +144,17 @@ type Props = PropTypes.InferProps<typeof propTypes>
* @type {React.ComponentType<{readonly label?: string, readonly name?: string} & React.ClassAttributes<unknown>>}
*/
const RadioButton = React.forwardRef<HTMLInputElement, Props>(
(
{ label = '', name, },
ref
) => (
({ label = '', name, onChange, onFocus, onBlur }, ref) => (
<Base>
<CaptureArea>
<Input ref={ref} name={name} type="radio" />
<Input
ref={ref}
name={name}
type="radio"
onChange={onChange as React.ChangeEventHandler}
onFocus={onFocus as React.FocusEventHandler}
onBlur={onBlur as React.FocusEventHandler}
/>
<IndicatorWrapper>
<Border />
<Indicator />
@@ -149,7 +165,7 @@ const RadioButton = React.forwardRef<HTMLInputElement, Props>(
</Label>
</CaptureArea>
</Base>
)
),
)

RadioButton.propTypes = propTypes


+ 1
- 6
lib/components/Select/Select.tsx View File

@@ -242,12 +242,7 @@ const Select = React.forwardRef<HTMLSelectElement, Props>(
opacity: disabled ? 0.5 : undefined,
}}
>
{
border
&& (
<Border />
)
}
{border && <Border />}
<CaptureArea>
<LabelWrapper
style={{


+ 7
- 0
lib/components/Slider/Slider.tsx View File

@@ -204,6 +204,10 @@ const propTypes = {
* Is the component active?
*/
disabled: PropTypes.bool,
/**
* Event handler triggered when the component changes value.
*/
onChange: PropTypes.func,
}

type Props = PropTypes.InferProps<typeof propTypes>
@@ -226,6 +230,7 @@ const Slider: React.FC<Props> = ({
label = '',
length = '16rem',
disabled = false,
onChange,
}) => {
const [isClient, setIsClient] = React.useState(false)

@@ -295,6 +300,7 @@ const Slider: React.FC<Props> = ({
padding: orientation === 'horizontal' ? '0.875rem 0.75rem' : '0.75rem 0.875rem',
cursor: disabled ? 'not-allowed' : undefined,
}}
onChange={onChange!}
>
<Track>
<Highlight
@@ -361,6 +367,7 @@ const Slider: React.FC<Props> = ({
width: length!,
}}
disabled={disabled!}
onChange={onChange!}
type="range"
/>
</ClickArea>


+ 1
- 1
lib/components/TextInput/TextInput.test.tsx View File

@@ -70,7 +70,7 @@ describe.each`
multiline | tag
${false} | ${'input'}
${true} | ${'textarea'}
`('on multiline (multiline=$multiline)', ({ tag: rawTag, multiline: rawMultiline, }) => {
`('on multiline (multiline=$multiline)', ({ tag: rawTag, multiline: rawMultiline }) => {
const tag = rawTag as string
const multiline = rawMultiline as boolean



+ 1
- 6
lib/components/TextInput/TextInput.tsx View File

@@ -279,12 +279,7 @@ const TextInput = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, Props
opacity: disabled ? 0.5 : undefined,
}}
>
{
border
&& (
<Border />
)
}
{border && <Border />}
<CaptureArea>
<LabelWrapper
style={{


+ 11
- 3
package.json View File

@@ -1,6 +1,6 @@
{
"name": "@tesseract-design/react-common",
"version": "0.1.1",
"version": "0.2.0",
"description": "Common front-end components for Web using the Tesseract design system, written in React.",
"directories": {
"lib": "dist"
@@ -37,7 +37,15 @@
"rollup-plugin-terser": "5.3.0",
"ts-jest": "^26.1.3",
"tslib": "^2.0.0",
"typescript": "^3.9.7"
"typescript": "^3.9.7",
"@reach/slider": "^0.10.5",
"docz": "^2.3.1",
"pascal-case": "3.1.1",
"prop-types": "15.7.2",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-feather": "2.0.3",
"styled-components": "5.1.0"
},
"scripts": {
"prepublishOnly": "NODE_ENV=production rm -rf dist/ && rollup -c",
@@ -46,7 +54,7 @@
"generate": "plop",
"docs": "docz"
},
"dependencies": {
"peerDependencies": {
"@reach/slider": "^0.10.5",
"docz": "^2.3.1",
"pascal-case": "3.1.1",


Loading…
Cancel
Save