Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prettier rules & support #63

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
packages/**/node_modules
packages/**/dist
packages/**/build
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"printWidth": 100
}
15 changes: 14 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,18 @@
"typescript.tsdk": "./node_modules/typescript/lib",
"editor.tabSize": 2,
"editor.detectIndentation": false,
"tslint.nodePath": "./node_modules"
"tslint.nodePath": "./node_modules",
"[typescript]": {
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.formatOnSave": true
},
"prettier.printWidth": 100,
"prettier.semi": false,
"prettier.singleQuote": true,
"prettier.typescriptEnable": [
"typescript",
"typescriptreact"
],
}
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
"build": "yarn workspace @grammarly/focal build",
"package": "yarn workspace @grammarly/focal pack",
"release": "yarn workspace @grammarly/focal release",
"test": "yarn workspace @grammarly/focal test && yarn workspace focal-todomvc build && yarn workspace focal-examples build && yarn workspace focal-manual-tests build",
"postinstall": "yarn build"
"test": "yarn workspace @grammarly/focal test && yarn workspace focal-todomvc build && yarn workspace focal-examples build && yarn workspace focal-manual-tests build && yarn prettier:check",
"postinstall": "yarn build",
"prettier:fix": "prettier --write './packages/**/*.ts?(x)'",
"prettier:check": "prettier --list-different './packages/**/*.ts?(x)'"
},
"devDependencies": {
"@grammarly/tslint-config": "0.5.1",
"tslint": "5.20.0",
"typescript": "3.6.4"
"typescript": "3.6.4",
"prettier": "1.18.2"
},
"workspaces": [
"packages/focal",
Expand All @@ -21,4 +24,4 @@
"resolutions": {
"@types/react": "16.9.11"
}
}
}
2 changes: 1 addition & 1 deletion packages/examples/all/custom_typings/css/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare module '*.css' {
const e: any
export = e;
export = e
}
13 changes: 5 additions & 8 deletions packages/examples/all/src/add-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@ const App = (props: { state: Atom<AppState> }) => {
return (
<div>
<div>
<F.input { ...bind({ value: props.state.lens('entry') }) } type='text' />
<input type='submit' value='Add' onClick={() => props.state.modify(addItem)} />
<F.input {...bind({ value: props.state.lens('entry') })} type="text" />
<input type="submit" value="Add" onClick={() => props.state.modify(addItem)} />
</div>
<F.ul>
{
reactiveList(
values.view(x => x.map((_, index) => index)),
index => <F.li>{values.view(x => x[index])}</F.li>
)
}
{reactiveList(values.view(x => x.map((_, index) => index)), index => (
<F.li>{values.view(x => x[index])}</F.li>
))}
</F.ul>
</div>
)
Expand Down
32 changes: 10 additions & 22 deletions packages/examples/all/src/animated-counter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import * as React from 'react'
import { F, Atom } from '@grammarly/focal'
import * as Model from './model'

const Counter = ({
counterState = Atom.create(Model.defaultCounterState)
}) => {
const Counter = ({ counterState = Atom.create(Model.defaultCounterState) }) => {
const count = counterState.view('count')
const absoluteCount = counterState.view('absoluteCount')

Expand All @@ -13,19 +11,13 @@ const Counter = ({
<F.span>
Count: {count}, abs = {absoluteCount}
</F.span>
<button onClick={() => Model.incrementCount(counterState)}>
+
</button>
<button onClick={() => Model.resetCounter(counterState)}>
reset
</button>
<button onClick={() => Model.incrementCount(counterState)}>+</button>
<button onClick={() => Model.resetCounter(counterState)}>reset</button>
</div>
)
}

const AnimatedDiv = ({
counterState = Atom.create(Model.defaultCounterState)
}) => {
const AnimatedDiv = ({ counterState = Atom.create(Model.defaultCounterState) }) => {
const displayState = counterState.lens('display')
const count = counterState.view('count')

Expand All @@ -36,7 +28,7 @@ const AnimatedDiv = ({
style={{
background: '#f00',
position: 'absolute',
opacity: count.view(x => Model.shouldHideCounter(x) ? 0.3 : 1.0),
opacity: count.view(x => (Model.shouldHideCounter(x) ? 0.3 : 1.0)),
left: count.view(x => x * 25),
transition: 'left 0.5s linear, opacity 1.5s linear'
}}
Expand All @@ -46,28 +38,24 @@ const AnimatedDiv = ({
}
}}
>
<Counter counterState={counterState}/>
<Counter counterState={counterState} />
</F.div>
)
} else {
return undefined
}
})

return (
<F.span>{animDiv}</F.span>
)
return <F.span>{animDiv}</F.span>
}

const App = ({
state = Atom.create(Model.defaultAppState)
}) => {
const App = ({ state = Atom.create(Model.defaultAppState) }) => {
const counterState = state.lens('counter')

return (
<div>
<Counter counterState={counterState}/>
<AnimatedDiv counterState={counterState}/>
<Counter counterState={counterState} />
<AnimatedDiv counterState={counterState} />
</div>
)
}
Expand Down
3 changes: 1 addition & 2 deletions packages/examples/all/src/animated-counter/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ export function shouldHideCounter(count: number) {

export function hideAfterFadeOut(counter: Atom<CounterState>) {
// check if we still should hide
if (shouldHideCounter(counter.get().count))
counter.lens('display').set(false)
if (shouldHideCounter(counter.get().count)) counter.lens('display').set(false)
}

export function resetCounter(counter: Atom<CounterState>) {
Expand Down
7 changes: 2 additions & 5 deletions packages/examples/all/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface ExampleComponent<S> {

declare const require: (path: string) => any

const examples: { name: string, example: ExampleComponent<any> }[] = [
const examples: { name: string; example: ExampleComponent<any> }[] = [
'counter',
'clock',
'checkbox',
Expand Down Expand Up @@ -45,10 +45,7 @@ examples.forEach(ex => {
defaultState[ex.name] = ex.example.defaultState
})

export const AppComponent = ({
state = Atom.create(defaultState)
}) => {

export const AppComponent = ({ state = Atom.create(defaultState) }) => {
return (
<main>
<h1>Focal examples</h1>
Expand Down
68 changes: 40 additions & 28 deletions packages/examples/all/src/big-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,67 @@
import { fromEvent } from 'rxjs'
import { startWith, distinctUntilChanged, map } from 'rxjs/operators'
import {
F, Atom, ReadOnlyAtom, bindElementProps, reactiveList
} from '@grammarly/focal'
import { F, Atom, ReadOnlyAtom, bindElementProps, reactiveList } from '@grammarly/focal'
import * as React from 'react'

const Window = {
innerWidth:
fromEvent(window, 'resize').pipe(
map(() => window.innerWidth),
distinctUntilChanged(),
startWith(0))
innerWidth: fromEvent(window, 'resize').pipe(
map(() => window.innerWidth),
distinctUntilChanged(),
startWith(0)
)
}

const defaultState = {
tableHeight: 250,
rowHeight: 30,
rowCount: 10000,
columns: [ 'ID', 'ID * 10', 'Random Number' ]
columns: ['ID', 'ID * 10', 'Random Number']
}

function getRowContent(id: number) {
return [ `${id}`, `${id * 10}`, `${Math.floor(Math.random() * 100)}` ]
return [`${id}`, `${id * 10}`, `${Math.floor(Math.random() * 100)}`]
}

function cellWidthStyle(columns: string[]) {
return Window.innerWidth.pipe(map(innerWidth =>
({ width: innerWidth / columns.length + 'px' })))
return Window.innerWidth.pipe(map(innerWidth => ({ width: innerWidth / columns.length + 'px' })))
}

function getVisibleRows(
tableHeight: number, rowHeight: number, rowCount: number, scrollTop: number
tableHeight: number,
rowHeight: number,
rowCount: number,
scrollTop: number
) {
return {
begin: Math.floor(scrollTop / rowHeight),
end: Math.min(rowCount, Math.ceil((scrollTop + tableHeight) / rowHeight))
}
}

const THead = (props: { columns: ReadOnlyAtom<string[]> }) =>
const THead = (props: { columns: ReadOnlyAtom<string[]> }) => (
<thead>
<F.tr>
{props.columns.view(cols =>
cols.map((col, i) =>
<F.th key={i} style={cellWidthStyle(cols)}>{col}</F.th>))}
cols.map((col, i) => (
<F.th key={i} style={cellWidthStyle(cols)}>
{col}
</F.th>
))
)}
</F.tr>
</thead>
)

const TBody = (props: {
state: Atom<typeof defaultState>,
state: Atom<typeof defaultState>
visibleRows: ReadOnlyAtom<{ begin: number; end: number }>
}) =>
}) => (
<F.tbody>
{reactiveList(
props.visibleRows.view(({ begin, end }) =>
Array.from(Array(end - begin), (_, i) => i + begin)),
i =>
Array.from(Array(end - begin), (_, i) => i + begin)
),
i => (
<F.tr
key={i}
style={{
Expand All @@ -65,19 +71,25 @@ const TBody = (props: {
}}
>
{props.state.view(({ columns }) =>
getRowContent(i).map((column, i) =>
<F.td style={cellWidthStyle(columns)} key={i}>{column}</F.td>))}
getRowContent(i).map((column, i) => (
<F.td style={cellWidthStyle(columns)} key={i}>
{column}
</F.td>
))
)}
</F.tr>
)
)}
</F.tbody>
)

const App = ({
state,
scrollTop = Atom.create(0)
}: {
state: Atom<typeof defaultState>,
state: Atom<typeof defaultState>
scrollTop: Atom<number>
}) =>
}) => (
<div>
<table
style={{
Expand All @@ -86,7 +98,7 @@ const App = ({
borderBottom: '1px solid black'
}}
>
<THead columns={state.view('columns')}/>
<THead columns={state.view('columns')} />
</table>
<F.div
{...bindElementProps({ forwardRef: 'onScroll', scrollTop })}
Expand All @@ -105,15 +117,15 @@ const App = ({
<TBody
{...{
state,
visibleRows: Atom.combine(
state, scrollTop,
(m, s) => getVisibleRows(m.tableHeight, m.rowHeight, m.rowCount, s)
visibleRows: Atom.combine(state, scrollTop, (m, s) =>
getVisibleRows(m.tableHeight, m.rowHeight, m.rowCount, s)
)
}}
/>
</F.table>
</F.div>
</div>
)

export default {
Component: App,
Expand Down
12 changes: 5 additions & 7 deletions packages/examples/all/src/bmi/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react'
import { Atom, F, bind } from '@grammarly/focal'

interface AppState {
weightKg: number,
weightKg: number
heightCm: number
}

Expand All @@ -15,7 +15,7 @@ namespace AppState {

function getBmi(weight: number, height: number) {
const heightMeters = height * 0.01
return Math.round(weight / (heightMeters ** 2))
return Math.round(weight / heightMeters ** 2)
}

const App = (props: { state: Atom<AppState> }) => {
Expand All @@ -25,14 +25,12 @@ const App = (props: { state: Atom<AppState> }) => {
return (
<div>
<div>
Weight (kg) <F.input {...bind({ value: weight })} type='range' min='40' max='140' />
Weight (kg) <F.input {...bind({ value: weight })} type="range" min="40" max="140" />
</div>
<div>
Height (cm) <F.input {...bind({ value: height })} type='range' min='140' max='210' />
Height (cm) <F.input {...bind({ value: height })} type="range" min="140" max="210" />
</div>
<F.h3>
BMI is {Atom.combine(weight, height, getBmi)}
</F.h3>
<F.h3>BMI is {Atom.combine(weight, height, getBmi)}</F.h3>
</div>
)
}
Expand Down