Skip to content

Instantly share code, notes, and snippets.

Avatar

Thomas Gossmann gossi

View GitHub Profile
@gossi
gossi / .explanation.md
Created Apr 11, 2021
SFC Glimmer Components
View .explanation.md

SFC Glimmer Components

High Level

Follow the concepts introduced with ember octane:

  1. html-first: create a .html .hbs file and start writing your html, that's all to get the rudimentary things going
  2. native classes: drop off all ember object shenanigan syntax and write native js

Apply these concepts:

@gossi
gossi / idea.md
Last active Mar 19, 2021
Ember: Universal a11y helpers
View idea.md

Universal a11y Helpers

Given the WAI ARIA authoring practices tell you quite good how a particular widget shall behave. What - in case you are developing such a widget as a glimmer component - if you want to write tests for them? What if there is an already ready library of tests to use for them? If you as a developer did a good job and have all the markup done properly, the tests can entirely work on the accessibility tree on top of your markup. If not, the tests will fail anyway.

What about having an ember addon, that provides this a11y test library? In case you are developing a new component, you take that library and throw their tests at your code, without ever writing them yourself and be assured your component is a11y compliant. That library would do a service to the whole ember community.

Example

Here is an example, I've just finished writing. It is the first iteration, I found it quite well and useful and lead me to writing this. Basically, I was

View index.html
Text w/ Date: <input type="text" inputmode="date">
Text w/ Numeric: <input type="text" inputmode="numeric">
Date: <input type="date">
View controllers.application\.js
import Controller from '@ember/controller';
import { action } from '@ember/object';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
@action
sayHello() {
console.log('hellooooooo');
}
View routes.application\.js
import Route from '@ember/routing/route';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class ApplicationRoute extends Route {
@tracked foo = 'foo';
get bar() {
return `${this.foo} bar`;
}
@gossi
gossi / invoke-modifier.ts
Created Dec 5, 2019
{{on "click" ...}} vs {{invoke ...}} in regards to a11y
View invoke-modifier.ts
import Modifier from 'ember-modifier';
import { action } from '@ember/object';
interface InvokeArgs {
positional: [() => void],
named: {}
}
/**
* Invoke modifier:
@gossi
gossi / idea.md
Last active Jun 10, 2019
Concept: Ember Pages vs Route/Controller
View idea.md

In response to: https://gos.si/blog/ember-2019-reduce-complexity/

The idea in short

  1. Keep routing as-is
  2. Delete Route and Controller
  3. Replace with Page
  4. Page extends a glimmer component with special sauce to handle transitions and (query) params

Imagine the following layout (yeah, I like MU):

View input-event-demo.ts
import { CompatibleInputEvent, IS_INPUT_SUPPORTED, normalizeInputEvent } from 'event-support';
// assuming `element` is a reference to an <input> elem
element.addEventListener('keydown', (event: KeyboardEvent) => {
const e = normalizeInputEvent(event);
if (!IS_INPUT_SUPPORTED || event.key.length > 1) {
handleEvent(e);
}
@gossi
gossi / normalize-input-event.ts
Created May 3, 2019
Event Support: normalize-input-event
View normalize-input-event.ts
export const normalizeInputEvent = function(event: KeyboardEvent | InputEvent): CompatibleInputEvent {
const e: CompatibleInputEvent = {
originalEvent: event
};
if (event instanceof KeyboardEvent) {
if (event.key === 'Backspace') {
e.inputType = 'deleteContentBackward';
e.navigationType = 'cursorLeft';
} else if (event.key === 'Delete') {
@gossi
gossi / compatible-input-event.ts
Created May 3, 2019
Event Support: CompatibleInputEvent
View compatible-input-event.ts
/**
* A normalized event from InputEvent and KeyboardEvent that works from ie11
* over modern browsers to android browsers (because that beast is worse than ie6)
*/
export interface CompatibleInputEvent {
data?: string;
inputType?: string;
navigationType?: string;
originalEvent: KeyboardEvent | InputEvent;
}