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

🚀 feat: add TS to helpers package #798

Merged
merged 7 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions packages/helpers/babel.config.js

This file was deleted.

19 changes: 15 additions & 4 deletions packages/helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"author": "ggdaltoso <[email protected]>",
"homepage": "https://gympass.github.io/yoga/",
"license": "MIT",
"main": "src/index.js",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
"access": "public",
"directory": "dist"
Expand All @@ -21,14 +22,24 @@
"url": "git+https://github.com/Gympass/yoga.git"
},
"scripts": {
"build": "yarn build:cjs && yarn build:esm",
"build:cjs": "NODE_ENV=cjs babel ./src --out-dir dist/cjs",
"build:esm": "NODE_ENV=esm babel ./src --out-dir dist/esm",
"build": "yarn build:types && yarn build:cjs && yarn build:esm",
"build:cjs": "tsup src !src/types.ts --outDir dist/cjs --format=cjs",
"build:esm": "tsup src !src/types.ts --format=esm --legacy-output",
"build:types": "tsup --outDir dist/typings --dts-only",
"prebuild": "rm -rf ./dist",
"prepublishOnly": "node ../../scripts/prepublish.js",
"test": "NODE_ENV=test jest --config=../../jest/config/helpers.js"
},
"bugs": {
"url": "https://github.com/Gympass/yoga/issues"
},
"tsup": {
"entry": [
"src/index.ts",
"src/**/*.(t|j)s",
"!src/**/*.test.(t|j)s"
],
"splitting": false,
"bundle": false
}
}
21 changes: 11 additions & 10 deletions packages/helpers/src/hide.js → packages/helpers/src/hide.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import tokens from '@gympass/yoga-tokens';
import { breakpoints, Breakpoints } from '../../tokens/src/global/breakpoints';

matheushdsbr marked this conversation as resolved.
Show resolved Hide resolved
import { css } from 'styled-components';

import { not } from './media';
import { Entries, Hide } from './types';

const { breakpoints } = tokens;
const availableBreakpoints = Object.entries(breakpoints);
const availableBreakpoints = Object.entries(
breakpoints
) as unknown as Entries<Breakpoints>;

const hide = isNot =>
const hide = (isNot = false) =>
availableBreakpoints.reduce((acc, [key, breakpoint], index) => {
if (index === 0) {
const [, secondBreakpoint] = availableBreakpoints[index + 1];
Expand Down Expand Up @@ -37,10 +41,7 @@ const hide = isNot =>
const [, nextBreakpoint] = availableBreakpoints[index + 1];

acc[key] = css`
@media ${not(
isNot,
)} (min-width: ${breakpoint.width}px) and (max-width: ${nextBreakpoint.width -
1}px) {
@media ${not(isNot)} (min-width: ${breakpoint.width}px) and (max-width: ${nextBreakpoint.width - 1}px) {
display: none !important;
}
`;
Expand All @@ -52,6 +53,6 @@ const hide = isNot =>
`;

return acc;
}, {});
}, {} as Hide);

export default hide;
export default hide;
File renamed without changes.
62 changes: 0 additions & 62 deletions packages/helpers/src/media.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-disable import/no-named-as-default-member */
import tokens from '@gympass/yoga-tokens';
import { BREAKPOINTS_KEYS, BreakpointType } from '../../tokens/src/global/breakpoints';

import media, { matcher, not } from './media';
import { Matcher } from './types';

const { breakpoints } = tokens;

Expand All @@ -10,49 +12,49 @@ const formatCss = style =>
? style.join().replace(/,|\s*/g, '')
: style.replace(/,|\s*/g, '');

const expectedStyle = (...args) => {
const expectedStyle: Matcher = (...args) => {
return formatCss(matcher(...args)`
padding: 10px;
`);
};

const expectedHideStyle = breakpoint =>
const expectedHideStyle: (breakpoint: string) => void = breakpoint =>
matheushdsbr marked this conversation as resolved.
Show resolved Hide resolved
formatCss(`@media (min-width: ${breakpoints[breakpoint].width}px) {
display: none !important;
}`);

describe('media', () => {
it.each(Object.keys(breakpoints))('.%s', breakpoint => {
it.each(BREAKPOINTS_KEYS)('.%s', breakpoint => {
const style = media[breakpoint]`
padding: 10px;
`;

expect(formatCss(style)).toBe(expectedStyle(breakpoint));
expect(formatCss(style)).toBe(expectedStyle(breakpoint as BreakpointType));
});

it.each(Object.keys(breakpoints))('.not.%s', breakpoint => {
it.each(BREAKPOINTS_KEYS)('.not.%s', breakpoint => {
const notStyle = media.not[breakpoint]`
padding: 10px;
`;

expect(formatCss(notStyle)).toBe(expectedStyle(breakpoint, true));
expect(formatCss(notStyle)).toBe(expectedStyle(breakpoint as BreakpointType, true));
});

describe('max', () => {
it.each(Object.keys(breakpoints))(".max('%s')", breakpoint => {
const style = media.max(breakpoint)`
it.each(BREAKPOINTS_KEYS)(".max('%s')", breakpoint => {
const style = media.max(breakpoint as BreakpointType)`
padding: 10px;
`;

expect(formatCss(style)).toBe(expectedStyle(breakpoint, false, 'max'));
expect(formatCss(style)).toBe(expectedStyle(breakpoint as BreakpointType, false, 'max'));
});

it.each(Object.keys(breakpoints))(".not.max('%s')", breakpoint => {
const style = media.not.max(breakpoint)`
const style = media.not.max(breakpoint as BreakpointType)`
padding: 10px;
`;

expect(formatCss(style)).toBe(expectedStyle(breakpoint, true, 'max'));
expect(formatCss(style)).toBe(expectedStyle(breakpoint as BreakpointType, true, 'max'));
});
});

Expand All @@ -71,19 +73,19 @@ describe('media', () => {
];

it.each(comparisons)(".between('%s', '%s')", (min, max) => {
const style = media.between(min, max)`
const style = media.between(min as BreakpointType, max as BreakpointType)`
padding: 10px;
`;

expect(formatCss(style)).toBe(expectedStyle([min, max], false));
expect(formatCss(style)).toBe(expectedStyle([min as BreakpointType, max as BreakpointType], false));
});

it.each(comparisons)(".not.between('%s', '%s')", (min, max) => {
const style = media.not.between(min, max)`
const style = media.not.between(min as BreakpointType, max as BreakpointType)`
padding: 10px;
`;

expect(formatCss(style)).toBe(expectedStyle([min, max], true));
expect(formatCss(style)).toBe(expectedStyle([min as BreakpointType, max as BreakpointType], true));
});
});
});
Expand Down
63 changes: 63 additions & 0 deletions packages/helpers/src/media.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BreakpointType, breakpoints } from '../../tokens/src/global/breakpoints';

import { css } from 'styled-components';

import hide from './hide';
import { Matcher, Media, Width } from './types';

const availableBreakpoints = Object.keys(breakpoints) as BreakpointType[];
matheushdsbr marked this conversation as resolved.
Show resolved Hide resolved

const media: Media = { not: {} } as Media;

export const not = (isNot?: boolean) => (isNot ? 'not all and ' : '');

const getRange = (width: Width, range: 'min' | 'max') => {
try {
if (Array.isArray(width)) {
const [min, max] = width;

const {
[min]: { width: minBreakpoint },
[max]: { width: maxBreakpoint }
} = breakpoints;

return `(min-width: ${minBreakpoint}px) and (max-width: ${maxBreakpoint}px)`;
}

return `(${range}-width: ${breakpoints[width].width}px)`;
} catch {
const msg = `Make sure you've entered the right breakpoints.
Your input: ${Array.isArray(width) ? width.join(', ') : width}
Available breakpoints: ${availableBreakpoints.join(', ')}`;

throw new Error(msg);
}
};

export const matcher: Matcher =
(width: Width, isNot = false, range: 'min' | 'max' = 'min') =>
(...style) => {
return css`
@media ${not(isNot)}${getRange(width, range)} {
${css(...style)}
}
`;
};

availableBreakpoints.forEach((breakpoint) => {
media[breakpoint] = matcher(breakpoint);
media.not[breakpoint] = matcher(breakpoint, true);
});

media.max = (width: Width) => matcher(width, false, 'max');
media.not.max = (width: Width) => matcher(width, true, 'max');

media.between = (min: BreakpointType, max: BreakpointType) =>
matcher([min, max], false, 'max');
media.not.between = (min: BreakpointType, max: BreakpointType) =>
matcher([min, max], true, 'max');

media.hide = hide();
media.not.hide = hide(true);

export default media;
51 changes: 51 additions & 0 deletions packages/helpers/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { BreakpointType } from '../../tokens/src/global/breakpoints';

import { CSSObject, FlattenSimpleInterpolation } from 'styled-components';
export type Width = BreakpointType | BreakpointType[];

export type Media = {
not: MediaProps;
} & MediaProps;

export type Matcher = (
width: Width,
isNot?: boolean,
range?: 'min' | 'max'
) => Match;

export type Hide = {
[key in BreakpointType | StartBreakPoints]?: FlattenSimpleInterpolation;
};

export type Entries<T> = {
[K in keyof T]: [K, T[K]];
}[keyof T][];

type StartBreakPoints =
| 'xxs-start'
| 'xs-start'
| 'sm-start'
| 'md-start'
| 'lg-start'
| 'xl-start'
| 'xxl-start'
| 'xxxl-start';

type MediaProps = {
hide: Hide;
max: Max;
between: Between;
} & MappedType;

type MappedType = {
[key in BreakpointType]: Match;
};

type Max = (width: Width) => Match;

export type Between = (min: BreakpointType, max: BreakpointType) => Match;

type Match = (
first: TemplateStringsArray | CSSObject,
...interpolations: any[]
) => FlattenSimpleInterpolation;
7 changes: 4 additions & 3 deletions packages/tokens/src/global/breakpoints.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type BreakpointType = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl';
export type BreakpointType = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl';

matheushdsbr marked this conversation as resolved.
Show resolved Hide resolved
interface Breakpoint {
width: number;
Expand All @@ -9,7 +9,7 @@ export type Breakpoints = {
[key in BreakpointType]: Breakpoint;
};

const breakpoints: Breakpoints = {
export const breakpoints: Breakpoints = {
xxs: {
width: 0,
margin: 20,
Expand Down Expand Up @@ -59,5 +59,6 @@ const breakpoints: Breakpoints = {
},
} as const;

export default breakpoints;
export const BREAKPOINTS_KEYS = Object.keys(breakpoints);

export default breakpoints;
Loading