atomic-layout icon indicating copy to clipboard operation
atomic-layout copied to clipboard

Replace useResponsiveValue by useResponsiveProps

Open kettanaito opened this issue 5 years ago • 2 comments

Please see the first comment under this issue for more accurate issue status.

What:

I suggest that useResponsiveValue hook respected the behavior system used in responsive props. This means that a breakpoint without an explicit behavior implies the default one (i.e. "up"). Breakpoints (properties) accept an explicit behavior that changes the way their values are applied.

import { useResponsiveValue } from 'atomic-layout'

const Component = () => {
  const data = useResponsiveValue({
    sm: 2,
    lg: 3,
  })

  return <p>{data}</p>
}

The example above would assign the following values:

xs - undefined
sm - 2
md - 2 (stretches, since "sm" has no behavior, which implies the default "up")
lg - 3 (explicit override)
xl - 3 (stretches similarly to "md")

Why:

Current implementation of useResponsiveValue treats all properties as with "only" behavior. This makes it hard for a value to persist between breakpoints and requires to repeat it.

import { useResponsiveValue } from 'atomic-layout'

const Component = () => {
  const data = useResponsiveValue({
    md: 2,
    lg: 2,
  })

  return <p>{data}</p>
}

Using the second parameter of defaultValue doesn't help, because it's assign on any matches outside of the given breakpoint names. It's generally meant for a different behavior.

kettanaito avatar Jan 04 '20 21:01 kettanaito

Alternatively, the syntax can become opposite, with you declaring multiple data pieces at once, similar to how you do with Responsive props:

const Component = () => {
  const { firstName, lastName } = useResponsiveValue({
    firstName: 'John',
    firstNameMd: 'Johnathan',
    lastNameLgDown: 'Brooks'
  })
}
  • Allows to declare multiple breakpoint-driven data
  • Complete 1-1 responsive props experience outside of actual props
  • Probably a possibility to reuse the logic that applies responsive props (to some extend)

This made me realize such syntax already exists and it's useResponsiveProps. Nobody forces to pass the direct props of a component, it can be arbitrary set of properties that follow Responsive props naming convention.

I think at this point we can safely deprecate and remove useResponsiveValue and suggest useResponsiveProps instead.

kettanaito avatar Jan 13 '20 21:01 kettanaito

One more approach can be to rework the call signature of useResponsiveValues:

  1. One data piece per one hook instance.
  2. Adopt the same breakpoint range declaration pattern used in the Only component.

Usage example

import { useResponsiveValue } from 'atomic-layout'

const Example = () => {
  const label = useResponsiveValue({ from: 'sm', to: 'lg' }, 'value', 'fallback')
}

The declaration above translates into the following table:

  • xs: 'fallback'
  • sm: 'value'
  • md: 'value'
  • lg: 'fallback' (is the closing breakpoint inclusive?)
  • xl: 'fallback'

kettanaito avatar Feb 19 '20 18:02 kettanaito