LazyLionLeo / PSToolKit

Yet another redux implementation with TypeScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WireText VSCode

WireText is a text format that allows you to rapidly create low fidelity user interfaces mockups. This VSCode extensions gives you a live preview of the mockups.

Screenshot

Features:

  • A HTML/CSS templating language (inspired by PugJS) with a very lean syntax.
  • A library of common user-interface components, using a hand-drawn style so that nobody mistakes your wireframes for polished layout mockups.
  • As-you-type previews and error feedback.
  • Automatic scrolling of the preview panel.

Installation

WireText is not offered in the VSCode market place yet. You can install it by downloading this file and installing it in VSCode by clicking ··· in the top-right of the extensions panel, and then selecting Install from VSIX...

The components library

This section is autogenerated from the component-examples.wt example file. If you want to get started with WireText quickly, we recommend you install the extension and open that file. Contrary to this Markdown document, that will provide you with syntax highlighting and an easy way to play around.


include components-v1

A Phone is a type of screen. It must have an id, which can be used to link to it from other screens.

Phone id=login title="Welcome to Thingies"
	Input label=Email value="test@example.com"
	Input label=Password value=123456 type=password
	Button content="Sign in" link=home

Screens will often have some associated notes.

Phone id=login title="Welcome to Thingies" notes="""
	These are the notes for this screen.
	- Notes are written in *Markdown*.
	- They can be used to describe **behavior** associated with the screen.
"""
	Input label=Email value="test@example.com"
	Input label=Password value=123456 type=password
	Button content="Sign in" link=home

Let's define a template layout for a logged in view of our app, that'll we be able to reuse for most of our screens. Icons are provided by Remix Icons. You can look the names up here: https://remixicon.com/

define LoggedInPhone(id,title,content,up?)
	Phone id={id} title={title} up={up} content={content}
		bar_right =
			Icon icon=settings link=settings
			Icon icon=user link=profiled
		panel =
			Button link=home content="Home" icon=home
			Button link=favs content="Favourites" icon=heart
			Button link=about content="About" icon=info
			hr
			Button content="Nederlands" icon=flag
			Button content="English" icon=flag
			Button content="Deutsch" icon=flag

Use this template to create a page with an empty list and an add button.

LoggedInPhone id=home title="Home"
	ActionButton link="add"
		RemixIcon icon=add
	.wt-empty-page "No items"

A screen with some tabs and a view inputs.

LoggedInPhone id=add title="Add an item" up=home
	Tabs
		Tab title=Movie selected={true}
			Input label=Title value=Memento
			Input label="Release year" value=2000
			Button link=home_populated content=Add
		Tab title=Song
		Tab title=Book
		Tab title="..."

A populated list.

LoggedInPhone id=home_populated title="Home" 
	ActionButton link="add"
		RemixIcon icon=add
	List
		ListItem text="Fight Club" subtext="Movie, 1999" thumbnail=image
		ListItem text=Memento subtext="Movie, 2000" thumbnail="https://tinyurl.com/2p87xwuj" link=edit_thing
		ListItem text="The Matrix" subtext="Movie, 1999" thumbnail=code

Some more input elements, and columns.

LoggedInPhone id=edit_thing title="Memento" up=home
	img src="https://tinyurl.com/2p87xwuj"
	.wt-columns
		CheckBox label=Favourite
		CheckBox label=Owned checked=true
	FieldSet legend="Thingy type"
		RadioButton label=Movie name=thing_type checked={true}
		RadioButton label=Book name=thing_type
		RadioButton label=Other name=thing_type
	TextArea label=Synopsis value="""
		A man with short-term memory loss attempts to track
		down his wife's murderer."""
	Select label=Rating options="All | PG-13 | PG-16"
	Button content=Save link=home_populated

Insert some html formatting.

LoggedInPhone id=about title="About..." up=home
	html """
	Lorem ipsum dolor sit <strong>amet</strong>, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Platea dictumst quisque sagittis purus sit amet volutpat consequat. Integer feugiat scelerisque varius morbi enim nunc faucibus.
	<em>Quis auctor</em> elit sed vulputate mi sit amet mauris. Tincidunt tortor aliquam nulla facilisi cras fermentum odio. Sit amet nisl suscipit adipiscing bibendum est. Auctor urna nunc id cursus metus aliquam eleifend mi. Rhoncus dolor purus non enim praesent elementum facilisis leo. Sed lectus vestibulum mattis ullamcorper.
	Dui ut ornare lectus sit amet est. Eros in cursus turpis massa tincidunt dui ut. Ultrices neque ornare aenean euismod elementum nisi quis eleifend. Purus non enim praesent elementum facilisis leo vel. Accumsan sit amet nulla facilisi morbi tempus iaculis urna id.
	Egestas egestas fringilla phasellus faucibus scelerisque eleifend. Amet nisl purus in mollis nunc sed id semper risus. Varius duis at consectetur lorem. Amet purus gravida quis blandit. Pretium nibh ipsum consequat nisl vel pretium.
	"""

The Computer template.

Computer id=wintest title=Test notes="""
The name of the last-opened file is stored, and if the file still exists when the application starts again, it should automatically be opened.
"""
	MenuBar
		MenuCategory category="File"
			Button icon=file content=Load
			Button icon=save content=Save
			Button icon=close content=Exit
		MenuCategory category="Edit"
		MenuCategory category="Tools"
		MenuCategory category="Help"
	.wt-empty-page "Start by opening a file..."

The WireText templating language

This section is autogenerated from the language-tutorial.wt example file. If you want to get started with WireText quickly, we recommend you install the extension and open that file. Contrary to this Markdown document, that will provide you with syntax highlighting and an easy way to play around.


The WireText language is an HTML templating language (inspired by PugJS). The following will create a <section> containing an <h3> with some text and a <ul> with two list items (the second one being a link):

section
	h3
		"Title text"
	ul
		li
			"Item one."
		li
			a
				"Item two."
		# This is a comment.

When the content block for an element has only one item, it can be added to the same line, like this:

section
	h3 "Title text"
	ul
		li "Item one."
		li a "Item two."

HTML attributes can be provided using key=value pairs immediately after the tag name. Keys and values that contain 'strange' characters need to be "quoted" as a string.

section class=intro
	h3 id=my_title style="color: red;" "Title text"
	ul
		li "Item one."
		li a target=_blank href="https://example.com/two" "Item two."

As the class attribute is quite common, there's a shortcut for setting it:

section.intro "Intro"
section.intro.summary "Intro summary"

When the tag name is left out, 'div' is assumed:

.some_class "I'm a <DIV>"

Multi-line strings are supported using """triple double quotes""":

pre style="""
  background-color: #222;
  color: #fde;
""" title="Shell script"
	"""
	  #!/bin/sh
	  files=`ls ~ | wc -l`
	  echo You have $files files in your home directory.
	"""

For styling, we recommend the use of CSS instead of 'style' attributes. WireText offers a convenient syntax for defining CSS inline:

css
	.special
		background-color="#cce"
		padding="8px"
	.special > h3
		color=red
	.special li a
		color=green
section class=special
	h3 id=my_title "Title text"
	ul
		li "Item one."
		li a target=_blank href="https://example.com/two" "Item two."

CSS selectors can be nested, and property=value pairs can optionally be put on the same line as the selector, allowing the above CSS to be written like this:

css .special background-color="#eee" padding="8px"
	> h3 color=red
	li a color=green

WireText allows you to define reusable components. Component names must start with a Capital Letter.

define YourName
	fieldset
		legend "Who are you?"
		input placeholder="First name"
		input placeholder="Last name"

To show a component, you can use its name as if it were an HTML tag:

YourName
.special
	YourName

Components can have parameters, defined between (parenthesis) after the tag name. They must be provided when instantiating the component the same way that HTML attributes are provided. They can be used in most contexts (including within strings) by surrounding their names with {curly brackets}.

define AnyName(title, pronoun)
	fieldset
		legend {title}
		input placeholder="{pronoun} first name"
		input placeholder="{pronoun} last name"
AnyName title="Who is the king of pop?" pronoun=His
AnyName title="Who am I?" pronoun=My

Parameters are required, unless they get a default value, provided by a '=' and the value after the definition.

define AnyName(title = "Who are you?", pronoun = Your)
	fieldset
		legend {title}
		input placeholder="{pronoun} first name"
		input placeholder="{pronoun} last name"
AnyName
AnyName pronoun=Thy

Expression between {curly brackets} cannot just be parameter names, but are actually JavaScript expressions, in a context where all parameters have been defined as local variables

define AnyName(title = "Who are you?", pronoun = Your)
	fieldset
		legend {title.toUpperCase()}
		input placeholder="{pronoun.replace(/o/, '😁')} first name"
		input placeholder="{pronoun} last name"
AnyName

Component attributes names must be valid JavaScript variable names. In case you want to use a JavaScript keyword, such as class or inm as an attribute, you can suffix it with and underscore in the definition and in your JavaScript expressions.

define InClass(class_, in_)
	input value={in_} class={class_}
InClass in=test class=intro

WireText supports the spread operator, to receive all attributes that have not been defined as parameters into an object. This object can be passed expanded to attributes for a DOM element or another component.

define SpreadComponent(a, b, ...rest)
	p "a = {a}"
	p "b = {b}"
	p "rest has {Object.keys(rest).length} properties"
	input ...rest
SpreadComponent a=Almond b=Banana style="color: red;" value="My input value" type=password

WireText offers if/else if/else blocks, where the condition is provided by a JavaScript expression. Also note how the '?' suffix in the parameter list can be used for optional parameters (defaulting to an empty string).

define AnyName(title = "Who are you?", checkbox?)
	fieldset
		legend {title}
		input placeholder="First name"
		input placeholder="Last name"
		if {checkbox}
			label
				input type=checkbox
				{checkbox}
AnyName
AnyName checkbox="I agree!"

Similarly, there are for blocks.

for person in {"he she Frank".split(" ")}
	AnyName title="Who is {person}?"

JavaScript can also be used in event handlers, allowing you to hack a little bit of interactivity into your wireframes. NOTE: Expect this feature to change at any time. I'm not really happy with it yet.

button onclick={e => e.target.innerText += "!"} "Hello"

You may also run a bit of JavaScript while your page is initially constructed using a run statement. Its this variable will refer to the parent DOM element. NOTE: Expect this feature to change at any time. I'm not really happy with it yet.

css .angry color=red text-transform=uppercase font-weight=bold
section
	"Test"
	run {setInterval(() => this.classList.toggle('angry'), 500)}

(Multi-line) JavaScript containing {curly brackets} can be wrapped in {{{triple curly brackets}}}. While in {regular form} only a single JavaScript expression is expected, which will be used as a value by WireText, {{{triple form}}} doesn't deliver a value by default, but you can return one if you want.

section
	"Test"
	run {{{
		let element = this;
		function toggleAngry() {
			element.classList.toggle('angry');
		}
		setInterval(toggleAngry, 500);
	}}}

Components can also receive a block of WireText as a parameter. The default block (which resembles the content of a DOM element) is called 'content'.

define FancyFrame(content)
	div style="border: 4px solid #c0c;"
		div style="border: 4px solid #0cc;"
			div style="border: 4px solid #cc0; padding: 4px;"
				{content}
FancyFrame
	"Type something: "
	input
FancyFrame "test"

You can also pass multiple blocks as parameters, or pass a block to a parameter not named 'content' using this form:

css header display=flex background-color="#ccc" align-items=center
	> h3 flex=1 text-align=center
define TitleBar(title, left, right)
	header
		.left {left}
		h3 {title}
		.right {right}
TitleBar title="Hello world!"
	left=
		a href="#" "Go back"
	right=
		input type=checkbox
		"Dark mode"
FancyFrame
	content = select
		option "moon"
		option "mars"

WireText allows you to include files. The path should be given as a string and relative to the path of the current file.

include "language-tutorial-include.wt"
IncludeHello

WireText standard libraries (currently only components-v1) can be included by giving the name as an identifier:

include components-v1
Phone id=test title="My app" up=home
	content=
		Input label=Name
		CheckBox label="Sure!"
	bar_right=
		 RemixIcon icon=settings

About

Yet another redux implementation with TypeScript

License:MIT License


Languages

Language:JavaScript 97.8%Language:CSS 2.2%