Skip to content

Instantly share code, notes, and snippets.

@lstrrs
Last active May 8, 2023 01:31
Show Gist options
  • Save lstrrs/fd1e2add58748aae3ffb1e2587cf0094 to your computer and use it in GitHub Desktop.
Save lstrrs/fd1e2add58748aae3ffb1e2587cf0094 to your computer and use it in GitHub Desktop.
ComponentSpacingLayout
import Component from '@glimmer/component';
// Need to support auto and 0 as params
function getClassName(type, edge, unit) {
if (unit === '0') {
return '';
}
return `${type}${edge}-${unit}`;
}
function getClassNames(type, spacing) {
const edges = spacing.split(' ');
const [a, b, c, d] = edges;
let top, right, bottom, left;
//
if (edges.length === 1) {
[top, right, bottom, left] = [a, a, a, a];
}
//
else if (edges.length === 2) {
[top, right, bottom, left] = [a, b, a, b];
}
//
else if (edges.length === 3) {
[top, right, bottom, left] = [a, b, c, b];
}
//
else if (edges.length === 4) {
[top, right, bottom, left] = [a, b, c, d];
}
const t = type === 'offset' ? 'm' : 'p';
const classNames = [
getClassName(t, 't', top),
getClassName(t, 'r', right),
getClassName(t, 'b', bottom),
getClassName(t, 'l', left),
];
return classNames.join(' ');
}
export default class extends Component {
get inset() {
const { inset: spacing } = this.args;
if (!spacing) {
return;
}
return getClassNames('inset', spacing);
}
get offset() {
const { offset: spacing } = this.args;
if (!spacing) {
return;
}
return getClassNames('offset', spacing);
}
get hasBorder() {
const { hasBorder } = this.args;
if (hasBorder === undefined) {
return true;
}
return hasBorder;
}
}
import Component from '@glimmer/component';
const ALIGN = {
start: 'button-bar--start',
center: 'button-bar--center',
end: 'button-bar--end',
stretch: 'button-bar--stretch',
flush: 'button-bar--flush',
'space-around': 'button-bar--space-around',
'space-between': 'button-bar--space-between',
'space-evenly': 'button-bar--space-evenly',
};
const SPACING = {
none: 'button-bar--spacing-none',
small: 'button-bar--spacing-small',
}
export default class extends Component {
get alignmentClass() {
return ALIGN[this.args.align];
}
get spacingClass() {
const { spacing = 'small' } = this.args;
return SPACING[spacing];
}
}
import Component from '@glimmer/component';
export default class extends Component {
}
import Component from '@glimmer/component';
export default class extends Component {
}
import Component from '@glimmer/component';
export default class extends Component {
}
import Component from '@glimmer/component';
export default class extends Component {
}
import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
}
/* Need to rename tokens to correct name */
:root {
--dimension-spacing-2xsmall: .4rem;
--dimension-spacing-xsmall: .8rem;
--dimension-spacing-small: 1.2rem;
--dimension-spacing-medium: 1.6rem;
--dimension-spacing-large: 2.4rem;
--dimension-spacing-xlarge: 3.2rem;
--dimension-spacing-2xlarge: 4.8rem;
--dimension-spacing-3xlarge: 6.4rem;
--dimension-spacing-4xlarge: 9.6rem;
--dimension-spacing-5xlarge: 12.8rem;
--color-text: rgba(0,0,0,0.2);
}
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
p {
font-size: 1.2rem;
margin: 0;
}
p + p {
margin-top: 2.4rem;
}
.block {
font-size: 1.2rem;
font-weight: normal;
background: #fff;
-ms-transform: scale(1);
transform: scale(1);
transition: all .2s,outline 0s,box-shadow 0s;
color: var(--color-text);
}
.block--has-border {
border: 1px dashed #444950 !important;
}
.media {
width: 100%;
height: 250px;
}
:root {
--dimension-spacing-key: ".4rem";
--dimension-spacing-key: ".8rem";
--dimension-spacing-key: "1.2rem";
--dimension-spacing-key: "1.6rem";
--dimension-spacing-key: "2.4rem";
--dimension-spacing-key: "3.2rem";
--dimension-spacing-key: "4.8rem";
--dimension-spacing-key: "6.4rem";
--dimension-spacing-key: "9.6rem";
--dimension-spacing-key: "12.8rem";
}:root {
--dimension-spacing-size: .4rem;
--dimension-spacing-size: .8rem;
--dimension-spacing-size: 1.2rem;
--dimension-spacing-size: 1.6rem;
--dimension-spacing-size: 2.4rem;
--dimension-spacing-size: 3.2rem;
--dimension-spacing-size: 4.8rem;
--dimension-spacing-size: 6.4rem;
--dimension-spacing-size: 9.6rem;
--dimension-spacing-size: 12.8rem;
}
.mt-2xsm {
margin-top: var(--dimension-spacing-2xsmall);
}
.pt-2xsm {
padding-top: var(--dimension-spacing-2xsmall);
}
.mr-2xsm {
margin-right: var(--dimension-spacing-2xsmall);
}
.pr-2xsm {
padding-right: var(--dimension-spacing-2xsmall);
}
.mb-2xsm {
margin-bottom: var(--dimension-spacing-2xsmall);
}
.pb-2xsm {
padding-bottom: var(--dimension-spacing-2xsmall);
}
.ml-2xsm {
margin-left: var(--dimension-spacing-2xsmall);
}
.pl-2xsm {
padding-left: var(--dimension-spacing-2xsmall);
}
.mt-xsm {
margin-top: var(--dimension-spacing-xsmall);
}
.pt-xsm {
padding-top: var(--dimension-spacing-xsmall);
}
.mr-xsm {
margin-right: var(--dimension-spacing-xsmall);
}
.pr-xsm {
padding-right: var(--dimension-spacing-xsmall);
}
.mb-xsm {
margin-bottom: var(--dimension-spacing-xsmall);
}
.pb-xsm {
padding-bottom: var(--dimension-spacing-xsmall);
}
.ml-xsm {
margin-left: var(--dimension-spacing-xsmall);
}
.pl-xsm {
padding-left: var(--dimension-spacing-xsmall);
}
.mt-sm {
margin-top: var(--dimension-spacing-small);
}
.pt-sm {
padding-top: var(--dimension-spacing-small);
}
.mr-sm {
margin-right: var(--dimension-spacing-small);
}
.pr-sm {
padding-right: var(--dimension-spacing-small);
}
.mb-sm {
margin-bottom: var(--dimension-spacing-small);
}
.pb-sm {
padding-bottom: var(--dimension-spacing-small);
}
.ml-sm {
margin-left: var(--dimension-spacing-small);
}
.pl-sm {
padding-left: var(--dimension-spacing-small);
}
.mt-md {
margin-top: var(--dimension-spacing-medium);
}
.pt-md {
padding-top: var(--dimension-spacing-medium);
}
.mr-md {
margin-right: var(--dimension-spacing-medium);
}
.pr-md {
padding-right: var(--dimension-spacing-medium);
}
.mb-md {
margin-bottom: var(--dimension-spacing-medium);
}
.pb-md {
padding-bottom: var(--dimension-spacing-medium);
}
.ml-md {
margin-left: var(--dimension-spacing-medium);
}
.pl-md {
padding-left: var(--dimension-spacing-medium);
}
.mt-lg {
margin-top: var(--dimension-spacing-large);
}
.pt-lg {
padding-top: var(--dimension-spacing-large);
}
.mr-lg {
margin-right: var(--dimension-spacing-large);
}
.pr-lg {
padding-right: var(--dimension-spacing-large);
}
.mb-lg {
margin-bottom: var(--dimension-spacing-large);
}
.pb-lg {
padding-bottom: var(--dimension-spacing-large);
}
.ml-lg {
margin-left: var(--dimension-spacing-large);
}
.pl-lg {
padding-left: var(--dimension-spacing-large);
}
.mt-xlg {
margin-top: var(--dimension-spacing-xlarge);
}
.pt-xlg {
padding-top: var(--dimension-spacing-xlarge);
}
.mr-xlg {
margin-right: var(--dimension-spacing-xlarge);
}
.pr-xlg {
padding-right: var(--dimension-spacing-xlarge);
}
.mb-xlg {
margin-bottom: var(--dimension-spacing-xlarge);
}
.pb-xlg {
padding-bottom: var(--dimension-spacing-xlarge);
}
.ml-xlg {
margin-left: var(--dimension-spacing-xlarge);
}
.pl-xlg {
padding-left: var(--dimension-spacing-xlarge);
}
.mt-2xlg {
margin-top: var(--dimension-spacing-2xlarge);
}
.pt-2xlg {
padding-top: var(--dimension-spacing-2xlarge);
}
.mr-2xlg {
margin-right: var(--dimension-spacing-2xlarge);
}
.pr-2xlg {
padding-right: var(--dimension-spacing-2xlarge);
}
.mb-2xlg {
margin-bottom: var(--dimension-spacing-2xlarge);
}
.pb-2xlg {
padding-bottom: var(--dimension-spacing-2xlarge);
}
.ml-2xlg {
margin-left: var(--dimension-spacing-2xlarge);
}
.pl-2xlg {
padding-left: var(--dimension-spacing-2xlarge);
}
.mt-3xlg {
margin-top: var(--dimension-spacing-3xlarge);
}
.pt-3xlg {
padding-top: var(--dimension-spacing-3xlarge);
}
.mr-3xlg {
margin-right: var(--dimension-spacing-3xlarge);
}
.pr-3xlg {
padding-right: var(--dimension-spacing-3xlarge);
}
.mb-3xlg {
margin-bottom: var(--dimension-spacing-3xlarge);
}
.pb-3xlg {
padding-bottom: var(--dimension-spacing-3xlarge);
}
.ml-3xlg {
margin-left: var(--dimension-spacing-3xlarge);
}
.pl-3xlg {
padding-left: var(--dimension-spacing-3xlarge);
}
.mt-4xlg {
margin-top: var(--dimension-spacing-4xlarge);
}
.pt-4xlg {
padding-top: var(--dimension-spacing-4xlarge);
}
.mr-4xlg {
margin-right: var(--dimension-spacing-4xlarge);
}
.pr-4xlg {
padding-right: var(--dimension-spacing-4xlarge);
}
.mb-4xlg {
margin-bottom: var(--dimension-spacing-4xlarge);
}
.pb-4xlg {
padding-bottom: var(--dimension-spacing-4xlarge);
}
.ml-4xlg {
margin-left: var(--dimension-spacing-4xlarge);
}
.pl-4xlg {
padding-left: var(--dimension-spacing-4xlarge);
}
.mt-5xlg {
margin-top: var(--dimension-spacing-5xlarge);
}
.pt-5xlg {
padding-top: var(--dimension-spacing-5xlarge);
}
.mr-5xlg {
margin-right: var(--dimension-spacing-5xlarge);
}
.pr-5xlg {
padding-right: var(--dimension-spacing-5xlarge);
}
.mb-5xlg {
margin-bottom: var(--dimension-spacing-5xlarge);
}
.pb-5xlg {
padding-bottom: var(--dimension-spacing-5xlarge);
}
.ml-5xlg {
margin-left: var(--dimension-spacing-5xlarge);
}
.pl-5xlg {
padding-left: var(--dimension-spacing-5xlarge);
}
.button {
display: inline-block;
font-weight: normal;
padding: 8px 12px;
color: var(--color-text);
border: none;
}
.button-bar {
display: flex;
justify-content: left;
}
.button-bar--spacing-none {
column-gap: 0;
}
.button-bar--spacing-small {
column-gap: 8px;
}
.button-bar--center {
justify-content: center;
}
.button-bar--end {
justify-content: right;
}
.button-bar--stretch .button {
flex-grow: 1;
border-radius: 0;
}
.button-bar--spacing-none .button + .button {
border-left: 0;
}
.entity-lockup {
display: flex;
flex-direction: column;
}
.entity-lockup__main {
display: flex;
justify-content: flex-start;
}
.entity-lockup__image {
width: 72px;
height: 72px;
border-radius: 50%;
}
.entity-lockup__content {
flex: 1;
margin-left: 16px;
margin-right: 16px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 8px;
}
.entity-lockup__actions {
}
.entity-lockup__extras {
display: flex;
flex-direction: column;
margin-left: 88px;
gap: 8px;
}
.flex {
display: flex;
}
.flex-column {
flex-direction: column;
}
.gap-14 {
gap: 14px;
}
<h1>Examples</h1>
<h2>Card using flex layout</h2>
{{!-- @class="flex flex-column gap-14" --}}
<Card>
{{!-- @offset="xsm" --}}
<EntityLockup>
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
</EntityLockup>
<Media />
{{!-- @offset="xsm" --}}
<ButtonBar @hasBorder={{false}} @align="end">
<Button>Action</Button>
<Button>Action</Button>
<Button>Action</Button>
</ButtonBar>
</Card>
<h2>Card using normal layout</h2>
<Card>
{{!-- @offset="xsm" --}}
<EntityLockup @offset="xsm">
<Block @inset="xsm">
Component
</Block>
<Block @inset="xsm">
Component
</Block>
<Block @inset="xsm">
Component
</Block>
</EntityLockup>
<Media />
{{!-- @offset="xsm" --}}
<ButtonBar @hasBorder={{false}} @align="end" @offset="xsm">
<Button>Action</Button>
<Button>Action</Button>
<Button>Action</Button>
</ButtonBar>
</Card>
<h2>Entity Lockup with components inside of it</h2>
<Card @inset="" @offset="">
<EntityLockup>
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
</EntityLockup>
<Media />
<ButtonBar @hasBorder={{false}} @align="end">
<Button>Action</Button>
<Button>Action</Button>
<Button>Action</Button>
</ButtonBar>
</Card>
<h2>Entity Lockup with components outside of it</h2>
<Card @inset="" @offset="">
<EntityLockup />
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
<Block @inset="xsm" @offset="">
Component
</Block>
<Media />
<ButtonBar @hasBorder={{false}} @align="end">
<Button>Action</Button>
<Button>Action</Button>
<Button>Action</Button>
</ButtonBar>
</Card>
{{!-- <Card @inset="4xlg" @offset="lg 3xlg xsm lg">
Card
</Card>
<Card @inset="lg" @offset="sm">
Card
</Card>
<Card @inset="sm 4xlg" @offset="0 lg">
Card
</Card> --}}
<div class="block {{if this.hasBorder 'block--has-border'}} {{this.inset}} {{this.offset}}" ...attributes>
{{yield}}
</div>
<Block @hasBorder={{@hasBorder}} @inset={{@inset}} @offset={{@offset}} class="button-bar {{this.alignmentClass}} {{this.spacingClass}} {{@class}}">
{{yield}}
</Block>
<button type="button" class="button block block--has-border">
{{yield}}
</button>
<Block @inset={{@inset}} @offset={{@offset}} class="card {{@class}}">
{{yield}}
</Block>
<Block @hasBorder={{false}} @inset={{@inset}} @offset={{@offset}} class="entity-lockup {{@class}}">
<Block @hasBorder={{false}} class="entity-lockup__main">
<Block class="entity-lockup__image">
</Block>
<Block @hasBorder={{false}} class="entity-lockup__content">
<Block @inset="2xsm" @offset="" style="width: 40%">
</Block>
<Block @inset="2xsm" @offset="" style="width: 60%">
</Block>
<Block @inset="2xsm" @offset="" style="width: 30%">
</Block>
</Block>
<Block @hasBorder={{false}} class="entity-lockup__actions">
<ButtonBar @hasBorder={{false}} @align="end">
<Button>Action</Button>
</ButtonBar>
</Block>
</Block>
<Block @hasBorder={{false}} class="entity-lockup__extras">
{{yield}}
</Block>
</Block>
<Block @inset={{@inset}} @offset={{@offset}} class="media">
{{yield}}
</Block>
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "3.18.1",
"ember-template-compiler": "3.18.1",
"ember-testing": "3.18.1"
},
"addons": {
"@glimmer/component": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment