Skip to content
Shane Brinkman-Davis edited this page Feb 1, 2016 · 1 revision

ArtEngine Spans

Spans are an alternative to Elements in the AIM structure. Initially they are just a way to cluster a bunch of elements to be treated as-if the span's parent was the span children's direct parent. Essentially, a span is just an array.

Motivation: Often I use Elements for the sole purpose of clustering a bunch of children. Elements are heavy-handed for this task, and worse, they affect layout. As such, these grouping-Elements have to have some layout properties to mostly-neutralize their layout effects. However, those layout properties only apply to one context. If the context changes, you need other neutralizing layouts.

A span would be very light-weight and allow the clustered children to be laid out as-if they were direct children of the span's parent.

Motivation: I often find I want React Components to return a list of elements. For reasons I can't quite remember right now, it gets pretty ugly to support this directly in React.

Motivation: Currently your top-most element of a component cannot change its type. This is technically a bug, but I've found no elegant fix. If you wrap your element in a span, you could then change its type freely at the small cost of a span in between.

Span Properties

In the future, spans could have properties which are "applied" to all their children. This allows you to cluster common properties. When combined with inline text, we could cleanly express arbitrary text formatting much like HTML:

# Like HTML
# make the text 'awesomely cool' bold
Element 
  size: ww: 200, hch: 1
  "This is my"
  Span fontWeight: "bold", "awesomely cool"
  "text."

These spans wouldn't always work just like HTML. Unlike HTML, ArtEngine spans follow a single, simple rule:

  • Each property on a span is applied to any children (or children of nested spans) as-if that property was directly applied to that child.
# NOT like HTML
# Apply the same margin to a bunch of children,
# in this case, not even rendered in this component.
Element
  childrenLayout: "column"
  Span margin: 5
    ComponentReturningASpanWithManyChildren()

Handling Span Property Conflicts

If the same property is applied to a child more than once, the setting "closest" to the child gets priority. If the child has the property explicitly in its props, that gets priority. Otherwise, the closest enclosing span with that property gets priority.

Inline Text

I'd like to deprecate TextElement. Instead, you can just include text as a string directly in the children of an Element or Span. Essentially, you can think of the system automatically detecting it is a string and converting it to: TextElement text: theString. The difference, however, is then we could merge childrenLayout: 'flow' and TextElement flow layout into one thing.

# Example A and B would layout the same. 
# C would be different.

# Example A:
Element
  childrenLayout: 'flow'
  "The quick brown fox jumped over the lazy dog."
  "The quick brown fox jumped over the lazy dog."

# Example B:
Element
  childrenLayout: 'flow'
  "The quick brown fox jumped over the lazy dog.
  The quick brown fox jumped over the lazy dog."

# Example C:
Element
  childrenLayout: 'flow'
  TextElement text: "The quick brown fox jumped over the lazy dog."
  TextElement text: "The quick brown fox jumped over the lazy dog."

Formatting with Spans

With inline text, Spans would become the standard way to add formatting. See Spans above.

Replace TextElement with P

If TextElement is gone, we'd still need a way of expressing a paragraph break. My gut is we have a new special type of Span: P

Element
  childrenLayout: 'flow'
  P "The quick brown fox wanted his own paragraph"
  P "And the lazy dog just didn't care."

The P would be mostly like a Span except for two things:

  1. certain properties would effect the P and would not be passed to P's children. e.g. margin
  2. P has layout implications within a parent with childrenLayout: 'flow'

Animation Refactor

Instead of single-fire animations, attach animators which are triggered when one or more state changes. These animators then provide a smooth transition between the old and new states. Animators disable themselves when they are done. In this way animators can provide never-ending animations and animations which continually respond to user inputs as they animate.

Clone this wiki locally