Skip to content
Permalink
Browse files

feat: add Absolute component (#24)

* feat(absolute): add absolute package

* chore(button): use Absolute component

* fix: build

* fix: as="span"

* fix(ci): add eslint resolver /shrug
  • Loading branch information...
TheSisb committed Aug 7, 2019
1 parent 23d7385 commit ff2f1d90a4419dd312b6a4e48e0dab5b45941b29
@@ -28,10 +28,15 @@ jobs:
- run:
name: Run build
command: yarn build
- run:
name: Build monorepo package cache
command: yarn pre-test
- persist_to_workspace:
root: ~/
paths:
- repo/packages
- repo/tools/.cache

test:
executor: job-executor
steps:
@@ -0,0 +1,62 @@
const resolve = require('resolve');
const cachedPackages = require('../tools/.cache/packages.json');

exports.interfaceVersion = 2;

/**
* Holds information about every @paste package in our repo
* Our cache doesn't include the entry points in the location, so
* we loop over the packages, get the entry point from the 'main' field,
* and update the location property.
*
* Shape:
* {
* '@twilio-paste/button': {
* name: '@twilio-paste/button',
version: '0.1.2',
private: false,
location: '/Users/username/paste/packages/paste-core/components/button/dist/index.js'
}
* }
*/
const keyedPackages = cachedPackages.reduce((acc, currentPackage) => {
const packageJson = require(`${currentPackage.location}/package.json`);

// If there's no main entrypoint, don't update the location path.
// Note: the icons package doesn't have a main entrypoint
if (packageJson['main:dev'] == null && packageJson.main == null) {
acc[currentPackage.name] = currentPackage;
} else {
const mainEntrypoint = packageJson['main:dev'] || packageJson.main;
// Make sure to set the location to the dist/main entrypoint.
acc[currentPackage.name] = {
...currentPackage,
location: `${currentPackage.location}/${mainEntrypoint}`,
};
}
return acc;
}, {});

/**
* We're creating our own module resolver for eslint because it is having a
* very hard time finding our monorepo packages. When we import a `@twilio-paste`
* package we use our own module resolution, otherwise we use the default
* node one.
*
* https://github.com/benmosher/eslint-plugin-import/blob/master/resolvers/README.md
*/
exports.resolve = function customResolver(source, file, config) {
if (source.includes('@twilio-paste/') && keyedPackages[source] != null) {
return {found: true, path: keyedPackages[source].location};
}

if (resolve.isCore(source)) {
return {found: true, path: null};
}

try {
return {found: true, path: resolve.sync(source, opts(file, config))};
} catch (err) {
return {found: false};
}
};
@@ -1,3 +1,5 @@
const path = require('path');

// Based on https://github.com/iamturns/create-exposed-app/blob/master/.eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
@@ -72,6 +74,7 @@ module.exports = {
},
settings: {
'import/resolver': {
[path.resolve('./.eslint/resolver')]: {someConfig: ''},
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
},
@@ -26,12 +26,14 @@
"peerDependencies": {
"@emotion/core": "^10.0.10",
"@emotion/styled": "^10.0.10",
"@twilio-paste/absolute": "^0.0.1",
"@twilio-paste/spinner": "^0.1.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"styled-system": "^4.1.0"
},
"devDependencies": {
"@twilio-paste/absolute": "^0.0.1",
"@twilio-paste/spinner": "^0.1.4",
"rollup": "^1.16.2",
"rollup-plugin-babel": "^4.3.3",
@@ -66,7 +66,7 @@ const Button: React.FC<ButtonProps> = props => {
>
<ButtonChildren buttonState={buttonState}>{props.children}</ButtonChildren>
{showLoading ? (
<SpinnerWrapper>
<SpinnerWrapper as="span">
<Spinner size={20} title=". Loading, please wait." />
</SpinnerWrapper>
) : null}
@@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import {css, SerializedStyles} from '@emotion/core';
import {buttonStyle, themeGet} from 'styled-system';
import {Absolute} from '@twilio-paste/absolute';
import {ButtonWrapperProps, ButtonChildrenProps} from './types';

// TODO transitions - blocked on design
@@ -397,12 +398,7 @@ export const ButtonChildren = styled.span<ButtonChildrenProps>`
${childrenOpacityStyles}
`;

export const SpinnerWrapper = styled.span`
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
export const SpinnerWrapper = styled(Absolute)`
display: flex;
justify-content: center;
align-items: center;
@@ -8,6 +8,9 @@
"src/**/*"
],
"references": [
{
"path": "../../utilities/absolute"
},
{
"path": "../spinner"
}
@@ -0,0 +1,43 @@
{
"name": "@twilio-paste/absolute",
"version": "0.0.1",
"category": "layout",
"status": "alpha",
"description": "",
"author": "Twilio Inc.",
"license": "ISC",
"main:dev": "src/index.tsx",
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"files": [
"dist"
],
"scripts": {
"build": "yarn clean && yarn compile",
"build:dev": "yarn clean && yarn compile:dev",
"clean": "rm -rf ./dist && rm -rf tsconfig.build.tsbuildinfo && rm -rf .rpt2_cache",
"compile": "rollup -c --environment NODE_ENV:production",
"compile:dev": "rollup -c --environment NODE_ENV:development",
"prepublishOnly": "yarn build",
"type-check": "tsc --noEmit"
},
"peerDependencies": {
"@emotion/styled": "^10.0.10",
"@twilio-paste/box": "^0.2.4",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"styled-system": "^4.1.0"
},
"devDependencies": {
"@twilio-paste/box": "^0.2.4",
"rollup": "^1.16.2",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-node-resolve": "^5.1.0",
"rollup-plugin-terser": "^5.0.0",
"rollup-plugin-typescript2": "^0.21.2",
"typescript": "^3.5.2"
}
}
@@ -0,0 +1,34 @@
import typescript from 'rollup-plugin-typescript2';
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import {terser} from 'rollup-plugin-terser';
import pkg from './package.json';

export default {
input: pkg['main:dev'],
output: [
{
file: pkg.main,
format: 'cjs',
},
{
file: pkg.module,
format: 'es',
},
],
external: [...Object.keys(pkg.peerDependencies || {})],
plugins: [
resolve(),
commonjs(),
typescript({
clean: true,
typescript: require('typescript'),
tsconfig: './tsconfig.build.json',
}),
babel({
exclude: 'node_modules/**',
}),
process.env.NODE_ENV === 'production' ? terser() : null,
],
};
@@ -0,0 +1,122 @@
import styled from '@emotion/styled';
import {
top,
right,
bottom,
left,
zIndex,
TopProps,
BottomProps,
LeftProps,
RightProps,
ZIndexProps,
styleFn,
} from 'styled-system';
import {Box, BoxProps} from '@twilio-paste/box';

const LEFT_OPTIONS = [
'fill',
'left',
'left_top',
'left_bottom',
'left_fill',
'top_left',
'top_fill',
'bottom_left',
'bottom_fill',
];
const RIGHT_OPTIONS = [
'fill',
'right',
'right_top',
'right_bottom',
'right_fill',
'top_right',
'top_fill',
'bottom_right',
'bottom_fill',
];
const TOP_OPTIONS = [
'fill',
'top',
'top_right',
'top_left',
'top_fill',
'right_top',
'right_fill',
'left_top',
'left_fill',
];
const BOTTOM_OPTIONS = [
'fill',
'bottom',
'bottom_right',
'bottom_left',
'bottom_fill',
'right_bottom',
'right_fill',
'left_bottom',
'left_fill',
];

export type Presets =
| 'fill'
| 'top'
| 'top_left'
| 'top_right'
| 'top_fill'
| 'bottom'
| 'bottom_left'
| 'bottom_right'
| 'bottom_fill'
| 'left'
| 'left_top'
| 'left_bottom'
| 'left_fill'
| 'right'
| 'right_top'
| 'right_bottom'
| 'right_fill';

export interface AbsoluteProps extends TopProps, BottomProps, LeftProps, RightProps, ZIndexProps, BoxProps {
preset?: Presets;
}

interface PositionStyles {
top?: 0;
right?: 0;
bottom?: 0;
left?: 0;
}

const preset: styleFn = ({preset: _preset}) => {
const positionStyles: PositionStyles = {};

if (_preset == null) {
return positionStyles;
}

if (LEFT_OPTIONS.includes(_preset)) {
positionStyles.left = 0;
}
if (RIGHT_OPTIONS.includes(_preset)) {
positionStyles.right = 0;
}
if (TOP_OPTIONS.includes(_preset)) {
positionStyles.top = 0;
}
if (BOTTOM_OPTIONS.includes(_preset)) {
positionStyles.bottom = 0;
}
return positionStyles;
};

const Absolute = styled(Box)<AbsoluteProps>(preset, zIndex, top, right, bottom, left, {
position: 'absolute',
});

Absolute.defaultProps = {
preset: 'fill',
};

export {Absolute};

1 comment on commit ff2f1d9

@now

This comment has been minimized.

Copy link

now bot commented on ff2f1d9 Aug 7, 2019

Deployment failed with the following error:

The domain used as an alias twilio.design is not verified yet. Please verify it.
Please sign in to comment.
You can’t perform that action at this time.