Skip to content

Instantly share code, notes, and snippets.

Making Yapp better all the time and likely working on some Ember.js OSS

Luke Melia lukemelia

Making Yapp better all the time and likely working on some Ember.js OSS
View GitHub Profile
lukemelia /
Last active Jul 2, 2020
Simple component theming with broccoli.js

My team and I have been working on a new internal component library to share across a few Ember apps. The library is an Ember addon in a private github repo. So far, so good. The off-the-beaten-path part of our requirements is that the components need to be themeable. Specifically, we support a color and a "light" or "dark" aesthetic.

We want a great developer experience for creating and updating these components, so we used ember-freestyle as a devDependency of the library to create a living style guide. We added some UI to allow theme switching and even a checkbox to switch themes every second (thanks ember-concurrency!).

The thing that gave us the biggest challenge was figuring out how to author and apply the styles that were necessarily dynamic. Specifically, the css rules that used the dynamic color.

We decided to organize our styles like so:

lukemelia / circle.yml
Created Feb 2, 2017
Circle CI example deploying with ember-cli-deploy
View circle.yml
version: 5
- git submodule sync
- git submodule update --init
View uuid.js
export function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r, v;
r = Math.random() * 16 | 0;
v = c === 'x' ? r : r & 3 | 8;
return v.toString(16);
View components.component-that-updates.js
import Ember from 'ember';
const { computed } = Ember;
export default Ember.Component.extend({
backgroundColor: computed('model.backgroundColor', {
get() {
return this.get('model.backgroundColor');
set(key, val) {
if (val && !/^#/.test(val) && val !== 'transparent') {
View components.non-yielding-component.js
import Ember from 'ember';
const { computed } = Ember;
const { readOnly } = computed;
export default Ember.Component.extend({
cost: readOnly('delayedCalculation.cost'),
tax: readOnly(''),
total: computed('cost', 'tax', function() {
return this.get('cost') + this.get('tax');
lukemelia / main.js
Created Jun 3, 2016
letsencrypt with node and heroku
View main.js
var LE = require('letsencrypt');
var pem = require('pem');
var RSVP = require('rsvp');
var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var domains, herokuAppName, duplicate;
if (process.env.YAPP_ENV === 'qa') {
domains = ['', '', '', '' ];
lukemelia / ember-cli-build.js
Created Feb 19, 2016
Using an older ember-data with ember-cli-shims 0.1.0: ember-cli-shims 0.1.0 no longer shims ember-data because ember-data 2.3 is module-native. If you want to use an older version of ember-data though, you can shim it yourself
View ember-cli-build.js
lukemelia / app_transitions_concurrent.js
Created Jan 2, 2016
composing transitions in liquid-fire
View app_transitions_concurrent.js
import { Promise } from 'liquid-fire';
import { animationFor } from '../utils/transition-helpers';
// `concurrent` is not, by itself, an animation. It exists to run two or more
// transitions concurrently.
export default function concurrent(...transitions) {
return Promise.all( => {
return runAnimation(this, transition);
lukemelia / config_deploy.js
Created Dec 22, 2015
Sketch of ember-cli-deploy for Tom's fastboot deploy
View config_deploy.js
module.exports = function(deployTarget) {
var ENV = {};
if (deployTarget === 'production') {
ENV.plugins = [
'build', // perform the browser build
's3:browser-s3', // upload the browser build to S3
'gzip', // gzip the browser build assets
'manifest', // avoid redundant uploads
'fastboot', // perform the fastboot build, and merge in browser build details, zip and fingerprint the results
's3:fastboot-s3', // upload the fastboot build to S3
lukemelia / socketio-mirage-bridge.js
Created Nov 13, 2015
Bridge to mock an API being delivered via websockets using and hook it up to ember-cli-mirage
View socketio-mirage-bridge.js
// Shared under MIT License by Collectrium
import _ from 'lodash/lodash';
export default {
setup(config = {}) {
This method replaces with a mock Socket.IO client
interface which translates socket API requests to XHR requests
that will be intercepted by Mirage. When the XHR request returns
we process the result and send it back through the fake Socket.IO