Progress
- Have introduced two packages:
store
and basic
- Packages are now in typescript 🎉
- Packages are now linted (with
eslint
)!
- Included testing for the store and evaluation scripts
- Move to a redux architecture that can include the evaluate middleware or not. (by default this will be included)
- Opinionated styles are starting to be removed (e.g. color, font)
- single file for each component
- Removed boiler-plate code for creating components, including fighting with typescript generics so new components don't have too!!!
- Performance improvements - only render the components that actually changed! 🚀
There are a few suggested breaking changes on name/value/bind
as well as transform
on the display component. I would be curious on hearing from @lrq3000 or @J2thearo on these changes to see if they make sense!
New Basic Components
Working with material web components to bring new components!
<ink-switch>
- material UI switch
<ink-checkbox>
- material UI checkbox
<ink-radio>
- material UI radio
<ink-select>
- material UI select box #9
<ink-input>
- material UI textarea
<ink-visible>
- Div that makes things invisible on demand
- [ ] var list? do we need this? Now that there is CSS control, maybe not?
Changes to Ink Article
- Now using
<article>
- Now using
<aside>
for both asides and callouts. <aside class="callout info">
- These are now just plain CSS - so should be easy for people to re-theme
<ink-code>
and <ink-demo>
have been moved over
<ink-equation>
is ported, and works a lot better on the rendering side (no more 1-frame lag)
- [x] Outline (to make @choldgraf happy) iooxa/ink-article#2
- [ ] Figure -->
<figure>
iooxa/ink-article#3
- [x] Helper functions to render math inline.
- [x] Quote iooxa/ink-article#4, byline iooxa/ink-article#5
- [x] Card --> not sure about this one?! iooxa/ink-article#7
- [ ] Some level of cross-referencing on the page (is this
<ink-ref>
)? And a numbered attribute? iooxa/ink-article#6
Charting
I would like to get this merged and then can move on to the chart library -- it is a different animal and needs some love.
Resume
Similar to charting, this should likely be mostly CSS? Different library, out of scope of this PR.
User-defined functions
- Execution is now in the main context and can access scripts defined there (see #12)
Runtime State
I have moved to a single redux store to manage the state. This is split up into {variables, components}
the low-level interface looks like:
const x = store.dispatch(ink.actions.createVariable('scope.x', 3));
const max = store.dispatch(ink.actions.createVariable('scope.max', 9));
const range = store.dispatch(ink.actions.createComponent(
'range', 'scope.myRange',
{ value: { func: 'x' }, min: { value: 1 }, max },
{ change: { func: '{x: value}' } },
));
// Can set/get the properties
x.get()
x.set(4)
const { min, max } = range.state;
A version of this will be exposed in the window as ink
so that you can get/set variables in other programs which is needed for more control: (e.g. see #12 #10).
Creating a new component
I have added a base-class BaseComponent
that does the generic registering and unregistering of the component as well as a class wrapper @withInk
that injects properties that you define in a ComponentSpec
and give the relevant setters/getters for properties and events as well as playing nice with lit-element. The basics of this new setup gets the boiler-plate from 74 --> 18 lines of code (~25% of the size). The @withInk
wrapper I think is also more accessible (to debug etc.) than what I had before.
export const InkDisplaySpec = {
name: 'display',
description: 'Inline display of values',
properties: {
value: { type: types.PropTypes.number, default: NaN },
format: { type: types.PropTypes.string, default: '.1f' },
},
events: {},
};
@withInk(InkDisplaySpec, { bind: { type: String, reflect: true } })
class InkDisplay extends BaseComponent<typeof InkDisplaySpec> {
updated(updated: PropertyValues) { onBindChange(updated, this); }
render() {
const { value, format } = this.ink!.state;
return html`${formatter(value, format)}`;
}
}
Breaking Changes
Name/Value/Bind
There are a couple of issues with the previous naming conventions. It was is not specific enough for multiple event types (hover, drag, click, etc.) and there is no option for being able to add named components. This could be very helpful to react to events when a component enters the screen, show the component.min
value, etc. The previous name
attribute was used to set :value="${name}"
and bind="{[name]: value}"
which amounted to two way binding in the component. This was a handy shortcut and I think it should stay, however, be renamed to bind
now that events are explicitly named.
name
for components will now be used for the actual name of the component (should be unique in that scope)
- introducing named
events
, which will allow components to have multiple types of events
bind
is used as the default event type on components that allow it.
Previous version:
When you eat <ink-dynamic name="cookies" min="2" max="100"> cookies</ink-dynamic>,
you consume <ink-display :value="cookies * 50" format=".0f"/></ink-display> calories.
Changes to:
When you eat <ink-dynamic bind="cookies" min="2" max="100"> cookies</ink-dynamic>,
you consume <ink-display :value="cookies * 50" format=".0f"/></ink-display> calories.
This is equivalent to:
When you eat <ink-dynamic :value="cookies" :change="{cookies: value}" min="2" max="100"> cookies</ink-dynamic>,
you consume <ink-display :value="cookies * 50" format=".0f"/></ink-display> calories.
Action / Button
The bind
syntax doesn't make sense for the ink-action
and ink-button
components, it should really be an event and there isn't a value to "bind" to. This should change to :click
to return an event transform object.
Transform
- I am not convinced that
transform
should remain on the display
component. This can be done in a single call in the :value
function: <ink-display :value="fullName.split(' ')[0]">
. I do think that it should remain in the dynamic
as the value
is different than how you might display the variable.
Questions
- [x] Should the
store
package be called runtime? Would be similar to svelte, observable, idyll, etc.
- [x] Move the repo to @iooxa (likely) probably leave the repo
ink-components
on github/npm for the main package. So packages are @iooxa/runtime
etc.
- [x] A lot of the
ink-article
work is really just CSS, these should probably be removed as WebComponents. e.g. ink-aside
--> aside
ink-article
--> article
as these are standard HTML components.
- [x] Is there an HTML equivalent for a
callout
? update: I think this should be an aside
with a class. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside
- [x] I am questioning things like
ink-p
and ink-a
, these are really common attributes and when parsing (e.g. SEO) have semantic meaning. The visible
attribute is the main use case for these so that they react to changes in ink
and the <ink-a>
might have to be different? There could be something that is added that looks at the dom and toggles these on/off based on the state?
- I really wanted to change to inherited components
<a is="ink-a">
, but that is not supported by Safari. 😞 (and because of that lit-element doesn't support it either). Update: This could be done by wrapping the <a>
in a custom component.
- [ ] Explore the visible attribute on children of an article
- [ ] Explore
ink-preview
- [ ] Should the setter on variable/component shortcuts return a promise? Right now it is sync, but that might not be the case if different evaluation middleware is used.
- [ ] Add an example of a named component that is referenced.
- [ ] Can you get access to the variable properties somehow? Sometimes nice for
format
so that you can define it once (right now this is set on bind
if it is defined in the spec).
Outstanding Work
- Adding in the other packages (CV, Chart, Article)
- Packaging and publishing
- Move the code I have left in
/src
into appropriate packages
- Documentation update.
See #11