Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ dist
node_modules
build
tmp

vite.config.ts.timestamp*
2 changes: 1 addition & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
},
},
{
files: ['bin/*.js', '*.config.*'],
files: ['bin/*.ts', '*.config.*'],
rules: {
'import/no-extraneous-dependencies': [
'error',
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ build
coverage

*.tsbuildinfo
vite.config.ts.timestamp*
6 changes: 0 additions & 6 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,3 @@ MIT: https://github.com/seek-oss/capsize/blob/9d10414aa0597bb24101408b0b24c22d2e
@AndrewLeedham via https://github.com/seek-oss/capsize

https://github.com/seek-oss/capsize/issues/24#issuecomment-679998850

## open-props-scss

MIT: https://github.com/mayank99/open-props-scss/blob/ddd1275c3ee55a31a7759ddd5b88703174987d56/LICENSE

https://github.com/mayank99/open-props-scss
34 changes: 21 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,35 @@ SRCS = $(wildcard lib/**)
.DEFAULT_GOAL := all

.PHONY: all
all: build dist build/global.scss build/global.css
all: build dist build/global.scss build/global.css lib/generated/open-props-tokens.ts

node_modules: package.json pnpm-lock.yaml
pnpm install
touch $@

dist/bin/token.js: build bin/token.ts ${SRCS}
dist/bin/token.js: node_modules bin/token.ts build ${SRCS}
pnpm exec tsc -b

build/global.css: dist/bin/token.js
node dist/bin/token.js -t css > $@
dist/bin/open-props-tokens.js: node_modules bin/open-props-tokens.ts
pnpm exec tsc -b

lib/generated/open-props-tokens.ts: dist/bin/open-props-tokens.js
node $< > $@
pnpm exec prettier --write $@

build/global.scss: dist/bin/token.js
# SCSS
build/global.scss: node_modules dist/bin/token.js
node dist/bin/token.js -t scss > $@
pnpm exec prettier --write $@

tsconfig.json: tsconfig-vite.src.json
pnpm exec tsc -p tsconfig-vite.src.json --showConfig 1> $@
# CSS
build/global.css: node_modules dist/bin/token.js
node dist/bin/token.js -t css > $@
pnpm exec prettier --write $@

src/rds.module.scss: bin/token.js build
node $< > $@
prettier --write $@
tsconfig.json: node_modules tsconfig-vite.src.json
echo "// last updated: $(shell date)" > $@
pnpm exec tsc -p tsconfig-vite.src.json --showConfig 1>> $@

build: $(SRCS) node_modules vite.config.ts vite-env.d.ts
NODE_ENV=production pnpm exec vite build
Expand All @@ -41,7 +49,7 @@ dev-server: node_modules vite.config.ts

PHONY: typecheck
typecheck: node_modules tsconfig.json
pnpm exec tsc -w --preserveWatchOutput
pnpm exec tsc -w --preserveWatchOutput

.PHONY: dev
dev:
Expand All @@ -52,7 +60,7 @@ debug:
DEBUG_BUILD=1 $(MAKE)

dist: node_modules tsconfig.json
pnpm exec tsc
pnpm exec tsc -b

.PHONY: clean
clean: node_modules tsconfig.json
Expand All @@ -65,7 +73,7 @@ distclean: clean
rm -rf node_modules

.PHONY: test
test: lint dist build
test: node_modules lint dist build
DEBUG_BUILD=true pnpm vitest run
DEBUG_BUILD=true pnpm vitest run
pnpm exec bundlesize
Expand Down
61 changes: 61 additions & 0 deletions bin/open-props-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* eslint-disable no-restricted-syntax */
import { camelCase } from 'change-case';
import tokens from 'open-props/open-props.tokens.json' with { type: 'json' };
import { Project, VariableDeclarationKind } from 'ts-morph';

const project = new Project();
const sourceFile = project.createSourceFile('.fake.ts');

// so that blue1 comes before blue10
const collator = new Intl.Collator([], { numeric: true });

const groupedTokens = Object.groupBy(Object.entries(tokens), ([, token]) =>
'$type' in token ? token.$type : 'other',
);

sourceFile.addStatements([
`/**
* This file was auto generated by @block65/react-design-system
*
* Original tokens from the open-props project by @argyleink
* https://github.com/argyleink/open-props
*
* WARN: Do not edit directly.
*
* Generated on ${new Date().toISOString()} by ${JSON.stringify(process.env.USER)}
*
*/`,
]);

for (const [group, tokenGroup] of Object.entries(groupedTokens)) {
sourceFile.addStatements(['', `// Token Group: ${JSON.stringify(group)}`]);

if (tokenGroup) {
tokenGroup.sort(([a], [b]) => collator.compare(a, b));

for (const [cssVarName, token] of tokenGroup) {
sourceFile.addVariableStatement({
declarationKind: VariableDeclarationKind.Const,
isExported: true,
docs: [`Source CSS var: ${cssVarName}`],
declarations: [
{
name: camelCase(cssVarName, {
mergeAmbiguousCharacters: true,
}),
initializer: JSON.stringify(
typeof token.$value === 'string'
? token.$value.trim()
: token.$value,
null,
2,
),
},
],
});
}
}
}

sourceFile.formatText();
process.stdout.write(`${sourceFile.getFullText()}\n`);
10 changes: 6 additions & 4 deletions bin/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ import { PassThrough } from 'node:stream';
import { parseArgs } from 'node:util';
import { camelCase } from 'change-case';
import { leafNodeMapper, type PathStr, type VarFn, vargEx } from './utils.js';
import {
formControlTokens,
globalTokens,
panelTokens,
propsTokens,
} from '#defaults';
import {
badgeVars,
badgeVarsMapFnPrefix,
buttonVars,
buttonVarsMapFnPrefix,
formControlTokens,
formControlVarsMapFnPrefix,
globalTokens,
globalVars,
globalVarsMapFnPrefix,
panelTokens,
panelVars,
panelVarsMapFnPrefix,
propsTokens,
propsVars,
propsVarsMapFnPrefix,
} from '#vars';
Expand Down
4 changes: 2 additions & 2 deletions bundlesize.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
module.exports = {
files: [
{
path: 'build/*.js',
maxSize: '46 kB',
path: 'build/**/*.js',
maxSize: '40 kB',
compression: 'brotli',
},
{
Expand Down
134 changes: 134 additions & 0 deletions lib/defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import type { MapLeafNodes } from '@vanilla-extract/css';
import * as openPropsTokens from './generated/open-props-tokens.js';
import {
type formControlVars,
globalVars,
type panelVars,
propsVars,
type textLinkVars,
textVariantVars,
} from './vars.css.js';

// this is just a partial definition for the borders
export const globalTokens = {
border: {
radius: openPropsTokens.radius2,
width: openPropsTokens.borderSize2,
},
} satisfies MapLeafNodes<Pick<typeof globalVars, 'border'>, string>;

export const propsTokens = {
border: {
width: {
0: '0',
1: '0.05rem',
2: '0.15rem',
3: '0.2rem',
4: '0.3rem',
5: '0.5rem',
6: '0.75rem',
7: '1rem',
},
},
radius: {
// these are tuned to be distinguished at DPR3 but may not be different at
// lower densities they are rem so they dont scale with text size NOTE: we
// may need some `em` ones if we need fully curved buttons "pill" style
0: '0',
1: '0.125rem',
2: '0.25rem',
3: '0.5rem',
50: '50%',
},
space: {
'000': '-.5rem',
'00': '-.25rem',
'0': '0rem',
'1': '.125rem',
'2': '.25rem',
'3': '.375rem',
'4': '.5rem',
'5': '.625rem',
'6': '.75rem',
'7': '1rem',
'8': '1.25rem',
'9': '1.5rem',
'10': '1.75rem',
'11': '2rem',
'12': '3rem',
'13': '5rem',
'14': '7.5rem',
'15': '10rem',
'16': '15rem',
},
} satisfies MapLeafNodes<typeof propsVars, string>;

export const defaultTextTokens = {
fontWeight: {
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
} satisfies Record<keyof typeof textVariantVars.fontWeight, string>,
};

export const defaultTextLinkTokens = {
strong: {
fontWeight: textVariantVars.fontWeight.medium,
rest: {
fgColor: globalVars.color.accent,
textDecoration: 'underline',
},
hover: {
fgColor: globalVars.color.accent,
textDecoration: 'underline',
},
},
normal: {
fontWeight: textVariantVars.fontWeight.normal,
rest: {
fgColor: globalVars.color.accent,
textDecoration: 'none',
},
hover: {
fgColor: globalVars.color.accent,
textDecoration: 'underline',
},
},
weak: {
fontWeight: textVariantVars.fontWeight.normal,
rest: {
fgColor: globalVars.color.fgColor,
textDecoration: 'underline',
},
hover: {
fgColor: globalVars.color.accent,
textDecoration: 'underline',
},
},
none: {
fontWeight: 'inherit',
rest: {
fgColor: 'inherit',
textDecoration: 'none',
},
hover: {
fgColor: 'inherit',
textDecoration: 'none',
},
},
} satisfies MapLeafNodes<typeof textLinkVars, string>;

export const formControlTokens = {
outline: {
width: openPropsTokens.borderSize1,
},
} satisfies MapLeafNodes<typeof formControlVars, string>;

export const panelTokens = {
padding: {
inline: openPropsTokens.size3,
block: propsVars.space['4'],
},
} satisfies MapLeafNodes<typeof panelVars, string>;
6 changes: 3 additions & 3 deletions lib/fonts/inter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
@mixin vars {
font-family: 'Inter', sans-serif;
font-optical-sizing: auto;
line-height: var(--text-lineHeight-regular);
line-height: var(--text-lineHeight-normal);
font-style: normal;
font-variation-settings: 'slnt' 0;

--text-fontWeight-bold: 700;
--text-fontWeight-semibold: 600;
--text-fontWeight-medium: 500;
--text-fontWeight-regular: 400;
--text-fontWeight-normal: 400;
--text-fontWeight-light: 300;

--text-letterSpacing-tight: -0.05em;

--text-lineHeight-regular: initial;
--text-lineHeight-normal: initial;
--text-lineHeight-paragraph: 1.6;
--text-lineHeight-heading: 1.3;

Expand Down
8 changes: 6 additions & 2 deletions lib/forms.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import {
focusableClassName,
} from './focusable.css.js';
import { purposeVariantVars } from './purpose.css.js';
import { textVariantVars } from './typography.css.js';
import { formControlVars, propsVars, globalVars } from './vars.css.js';
import {
formControlVars,
globalVars,
propsVars,
textVariantVars,
} from './vars.css.js';

export const formInputPasswordIcon = style({
aspectRatio: '1/1',
Expand Down
Loading