`elm-mdl` is doing it that way because it is trying to follow how Google's material library works, and since there is no way to introspect into the virtualnode's to change how they act then it has to wrap things up in that pattern, I.E., VirtualNode limitations and Html.Attributes limitations require it to be this noisy. :-)
On Friday, August 19, 2016 at 12:08:14 PM UTC-6, suttlecommakevin wrote: > > Very interesting, thank you. Can you explain a bit more on the motives of > that architecture and API, please? > > https://debois.github.io/elm-mdl/#buttons > https://github.com/debois/elm-mdl/blob/master/demo/Demo/Buttons.elm > > > > On Friday, August 19, 2016 at 2:00:20 PM UTC-4, OvermindDL1 wrote: >> >> You could invert it to compose instead of extend, so something like this: >> >> ```elm >> -- Button with a Label >> MyButton.view [ MyButton.label "blah" ] >> >> -- Button with an Icon >> MyButton.view [ MyButton.icon "iconId" ] >> >> -- Button with both >> MyButton.view [ MyButton.label "blah", MyButton.icon "iconId" ] >> ``` >> >> You can easily enforce the icon to always render before the label is that >> is a requirement, regardless of position in the list, etc... etc... >> >> This is how the `elm-mdl` package works for example. >> >> >> On Friday, August 19, 2016 at 11:46:30 AM UTC-6, suttlecommakevin wrote: >>> >>> Apologies if this has been posted elsewhere, but I keep coming back to >>> it. >>> >>> Let's get basic. Like *super *basic. >>> >>> I get a spec from a designer for a button with 3 types of children. >>> >>> 1. A button with a label only >>> 2. A button with an icon only >>> 3. A button with an icon *and* a label >>> >>> >>> In a object-oriented programming environment, you could make a >>> ButtonBase class and extend it. >>> In React's bizarro world, they try to promote this Higher-order >>> Components technique, which is really just a function factory. >>> In Flow, you can at least start making types, and then, share and >>> intersect <https://flowtype.org/docs/functions.html#overloading> them. >>> >>> >>> *ButtonProps.js* >>> >>> // @flow >>> /* eslint-disable import/prefer-default-export */ >>> >>> export type ButtonProps = { >>> type?: 'button' | 'reset' | 'submit', >>> design: 'primary' | 'secondary', >>> className?: string, >>> children?: Array<HTMLElement>, >>> onClick?: () => void, >>> onFocus?: () => void, >>> onmouseover?: () => void, >>> onmouseout?: () => void, >>> } >>> >>> >>> *Button.jsx* >>> >>> // @flow >>> >>> import React from 'react'; >>> import type { ButtonProps } from './ButtonProps'; >>> import './Button.css'; >>> >>> /* eslint-disable flowtype/space-after-type-colon */ >>> const Button = ({ >>> design = 'primary', >>> className = 'btn', >>> type = 'button', >>> children } :ButtonProps) => >>> >>> <button className={[`${design} ${className}`]} type={type}> >>> {children} >>> </button>; >>> >>> export default Button; >>> >>> >>> *Icon.jsx* >>> >>> // @flow >>> >>> import React from 'react'; >>> import Button from './Button.jsx'; >>> import type { ButtonProps } from './ButtonProps'; >>> import Icon from '../Icons/Icon.jsx'; >>> import type { IconProps } from '../Icons/IconProps'; >>> >>> type IconButtonProps = ButtonProps & IconProps; >>> >>> const IconButton = (props: IconButtonProps) => >>> <Button >>> design={props.design} >>> onClick={props.onClick} >>> className={`iconBtn ${props.className}`} >>> > >>> <Icon glyph={props.glyph} /> >>> </Button>; >>> >>> export default IconButton; >>> >>> >>> Notice this line: type IconButtonProps = ButtonProps & IconProps; which >>> is just a fancy Object.assign() really. >>> It's easy to read, easy to understand, but many would claim it doesn't >>> follow "best practices". >>> >>> >>> My question is, how would Elm/FP handle this? >>> >>> >>> >>> Thanks, folks. >>> >> -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
