jbx 2.12.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/dist/components/Input.d.ts +24 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +54 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/MoreExperiments.d.ts.map +1 -1
- package/dist/components/MoreExperiments.js +17 -8
- package/dist/components/MoreExperiments.js.map +1 -1
- package/dist/generated/css.d.ts +1 -1
- package/dist/generated/css.d.ts.map +1 -1
- package/dist/generated/css.js +1 -1
- package/dist/generated/css.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.css +40 -3
- package/dist/primitives.d.ts +0 -4
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +0 -1
- package/dist/primitives.js.map +1 -1
- package/dist/spacing.d.ts +1 -1
- package/dist/spacing.d.ts.map +1 -1
- package/package.json +14 -15
- package/src/components/Input.tsx +104 -0
- package/src/components/MoreExperiments.tsx +19 -8
- package/src/generated/css.ts +1 -1
- package/src/index.tsx +1 -0
- package/src/primitives.tsx +0 -6
- package/src/style.css +40 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ The little component toolkit behind the tools on [javier.xyz](https://javier.xyz
|
|
|
4
4
|
components with a class each, one stylesheet, no runtime dependencies.
|
|
5
5
|
|
|
6
6
|
```
|
|
7
|
-
|
|
7
|
+
pnpm add jbx
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Styles
|
|
@@ -69,7 +69,22 @@ const Sprite = Component(
|
|
|
69
69
|
## Develop
|
|
70
70
|
|
|
71
71
|
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
pnpm dev # rebuild on change
|
|
73
|
+
pnpm typecheck
|
|
74
|
+
pnpm test # renders every export, fails on any React warning
|
|
75
75
|
```
|
|
76
|
+
|
|
77
|
+
## Publish
|
|
78
|
+
|
|
79
|
+
New versions are published to npm automatically when they reach `main`. A push whose
|
|
80
|
+
version is already on npm succeeds without publishing again.
|
|
81
|
+
|
|
82
|
+
1. Add the release notes to `CHANGELOG.md`.
|
|
83
|
+
2. Run `pnpm version minor --no-git-tag-version` to update `package.json`.
|
|
84
|
+
3. Run `pnpm test`.
|
|
85
|
+
4. Commit the changes and push them to `main`.
|
|
86
|
+
5. Confirm the **Publish package** workflow succeeds, then check the version with
|
|
87
|
+
`pnpm view jbx version`.
|
|
88
|
+
|
|
89
|
+
Publishing uses npm trusted publishing through GitHub Actions. It does not require an
|
|
90
|
+
npm token in the repository.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> & {
|
|
3
|
+
value?: string | number | readonly string[];
|
|
4
|
+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
5
|
+
/**
|
|
6
|
+
* Opt in to number handling. `value` is a number, and this is called with a
|
|
7
|
+
* number -- but only once what was typed parses and lands inside `min`/`max`,
|
|
8
|
+
* so a half typed value stays on screen without ever reaching the caller.
|
|
9
|
+
* Implies `type="number"`.
|
|
10
|
+
*/
|
|
11
|
+
onValueChange?: (value: number) => void;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A text input, and -- with `onValueChange` -- a number input that only commits
|
|
15
|
+
* what parses:
|
|
16
|
+
*
|
|
17
|
+
* <Input value={seconds} onValueChange={secondsSet} min={0.2} max={60} />
|
|
18
|
+
*
|
|
19
|
+
* Without `onValueChange` this is a plain controlled input and the caller owns
|
|
20
|
+
* `value` and `onChange` as usual.
|
|
21
|
+
*/
|
|
22
|
+
export declare function Input({ value, onChange, onValueChange, onBlur, type, min, max, ...props }: InputProps): React.JSX.Element;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=Input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAC;AASxC,KAAK,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IAC1F,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACtD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,aAAa,EACb,MAAM,EACN,IAAI,EACJ,GAAG,EACH,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,qBA0DZ"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { Component } from '../primitives.js';
|
|
4
|
+
const InputBase = Component(`jbx-input`, {}, { element: 'input' });
|
|
5
|
+
function toNumber(value) {
|
|
6
|
+
return typeof value === 'number' ? value : Number(value);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A text input, and -- with `onValueChange` -- a number input that only commits
|
|
10
|
+
* what parses:
|
|
11
|
+
*
|
|
12
|
+
* <Input value={seconds} onValueChange={secondsSet} min={0.2} max={60} />
|
|
13
|
+
*
|
|
14
|
+
* Without `onValueChange` this is a plain controlled input and the caller owns
|
|
15
|
+
* `value` and `onChange` as usual.
|
|
16
|
+
*/
|
|
17
|
+
export function Input({ value, onChange, onValueChange, onBlur, type, min, max, ...props }) {
|
|
18
|
+
// Hooks run either way; only the returned tree branches.
|
|
19
|
+
const [draft, draftSet] = useState(() => String(value ?? ''));
|
|
20
|
+
const [lastValue, lastValueSet] = useState(value);
|
|
21
|
+
if (!onValueChange) {
|
|
22
|
+
return (React.createElement(InputBase, { ...props, type: type, min: min, max: max, value: value, onChange: onChange, onBlur: onBlur }));
|
|
23
|
+
}
|
|
24
|
+
if (value !== lastValue) {
|
|
25
|
+
lastValueSet(value);
|
|
26
|
+
// `2.50` parses to the value we already hold -- adopting `String(value)`
|
|
27
|
+
// here would eat the trailing zero out from under the caret mid-typing.
|
|
28
|
+
if (Number(draft) !== toNumber(value))
|
|
29
|
+
draftSet(String(value ?? ''));
|
|
30
|
+
}
|
|
31
|
+
function draftChange(event) {
|
|
32
|
+
const next = event.target.value;
|
|
33
|
+
draftSet(next);
|
|
34
|
+
onChange?.(event);
|
|
35
|
+
const parsed = Number(next);
|
|
36
|
+
if (next.trim() === '' || !Number.isFinite(parsed))
|
|
37
|
+
return;
|
|
38
|
+
if (min !== undefined && parsed < toNumber(min))
|
|
39
|
+
return;
|
|
40
|
+
if (max !== undefined && parsed > toNumber(max))
|
|
41
|
+
return;
|
|
42
|
+
onValueChange(parsed);
|
|
43
|
+
}
|
|
44
|
+
// Leaving a half typed value behind is how a field ends up showing something
|
|
45
|
+
// the rest of the page never agreed to. Snap back to the live value on the
|
|
46
|
+
// way out.
|
|
47
|
+
function draftBlur(event) {
|
|
48
|
+
if (Number(draft) !== toNumber(value))
|
|
49
|
+
draftSet(String(value ?? ''));
|
|
50
|
+
onBlur?.(event);
|
|
51
|
+
}
|
|
52
|
+
return (React.createElement(InputBase, { ...props, type: type ?? 'number', min: min, max: max, value: draft, onChange: draftChange, onBlur: draftBlur }));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=Input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,SAAS,GAAG,SAAS,CACzB,WAAW,EACX,EAAE,EACF,EAAE,OAAO,EAAE,OAAO,EAAE,CACrB,CAAC;AAcF,SAAS,QAAQ,CAAC,KAA0B;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,aAAa,EACb,MAAM,EACN,IAAI,EACJ,GAAG,EACH,GAAG,EACH,GAAG,KAAK,EACG;IACX,yDAAyD;IACzD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CACL,oBAAC,SAAS,OACJ,KAAK,EACT,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACd,CACH,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,SAAS,WAAW,CAAC,KAA0C;QAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QAElB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO;QAC3D,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO;QACxD,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO;QAExD,aAAc,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,WAAW;IACX,SAAS,SAAS,CAAC,KAAyC;QAC1D,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;QACrE,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CACL,oBAAC,SAAS,OACJ,KAAK,EACT,IAAI,EAAE,IAAI,IAAI,QAAQ,EACtB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,SAAS,GACjB,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MoreExperiments.d.ts","sourceRoot":"","sources":["../../src/components/MoreExperiments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MoreExperiments.d.ts","sourceRoot":"","sources":["../../src/components/MoreExperiments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AA6DxC,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,oBAAoB,qBAgChE"}
|
|
@@ -35,13 +35,17 @@ const PROJECT_DATA = [
|
|
|
35
35
|
name: 'Cohesive Colors',
|
|
36
36
|
description: 'Tool that can help you to create cohesive color palettes',
|
|
37
37
|
url: 'https://javier.xyz/cohesive-colors'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'img2css',
|
|
41
|
+
description: 'Tool that can convert any image into a pure CSS image',
|
|
42
|
+
url: 'https://javier.xyz/img2css'
|
|
38
43
|
}
|
|
39
44
|
];
|
|
40
45
|
const maxItems = 5;
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
// site always renders the same slice — no hydration mismatch, no build-to-build churn.
|
|
46
|
+
// Fallback offset for a site that isn't in PROJECT_DATA itself. Derived from the site's
|
|
47
|
+
// own name rather than randomized, so it always renders the same slice — no hydration
|
|
48
|
+
// mismatch, no build-to-build churn.
|
|
45
49
|
function seedFor(key) {
|
|
46
50
|
let hash = 0;
|
|
47
51
|
for (let idx = 0; idx < key.length; idx++) {
|
|
@@ -50,10 +54,15 @@ function seedFor(key) {
|
|
|
50
54
|
return Math.abs(hash);
|
|
51
55
|
}
|
|
52
56
|
export function MoreExperiments({ exclude }) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
+
// A site listed in PROJECT_DATA links to the maxItems entries that follow it. Since
|
|
58
|
+
// every site starts one step further along, each project ends up linked from the same
|
|
59
|
+
// number of sites, instead of the first maxItems entries being the only ones to show up.
|
|
60
|
+
const selfIdx = exclude
|
|
61
|
+
? PROJECT_DATA.findIndex((project) => project.url.includes(exclude))
|
|
62
|
+
: -1;
|
|
63
|
+
const projects = selfIdx === -1 ? PROJECT_DATA : PROJECT_DATA.filter((_0, idx) => idx !== selfIdx);
|
|
64
|
+
// Dropping self shifts the tail left by one, so this index is already the next project.
|
|
65
|
+
const seed = selfIdx === -1 ? (exclude ? seedFor(exclude) : 0) : selfIdx;
|
|
57
66
|
const items = new Array(Math.min(maxItems, projects.length)).fill('').map((_0, idx) => {
|
|
58
67
|
const project = projects[(seed + idx) % projects.length];
|
|
59
68
|
return (React.createElement(Li, { key: project.url },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MoreExperiments.js","sourceRoot":"","sources":["../../src/components/MoreExperiments.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,YAAY,GAAG;IACnB;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,6DAA6D;QAC1E,GAAG,EAAE,0BAA0B;KAChC;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,2DAA2D;QACxE,GAAG,EAAE,kCAAkC;KACxC;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,wFAAwF;QAC1F,GAAG,EAAE,uBAAuB;KAC7B;IACD;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EACT,2FAA2F;QAC7F,GAAG,EAAE,4BAA4B;KAClC;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,gDAAgD;QAC7D,GAAG,EAAE,mCAAmC;KACzC;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,6EAA6E;QAC1F,GAAG,EAAE,qBAAqB;KAC3B;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,0DAA0D;QACvE,GAAG,EAAE,oCAAoC;KAC1C;CACO,CAAC;AAEX,MAAM,QAAQ,GAAG,CAAC,CAAC;AAEnB,
|
|
1
|
+
{"version":3,"file":"MoreExperiments.js","sourceRoot":"","sources":["../../src/components/MoreExperiments.tsx"],"names":[],"mappings":"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"}
|
package/dist/generated/css.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height:
|
|
1
|
+
export declare const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n /* Every interactive control is this tall, so a button, an input and a range\n standing next to each other line up. */\n --control-height: calc(var(--size) * 2.5);\n /* What a control shrinks to inside a tab row, where it has to match the line\n box of the tab's text (`.jbx-text` is `line-height: 1.4`) rather than stand\n on its own -- a row holding one is then exactly as tall as one that doesn't. */\n --control-height-compact: calc(var(--font-size) * 1.4);\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea,\nbutton {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height: var(--control-height);\n transition: top 0.1s, left 0.1s, box-shadow 0.05s;\n}\n.jbx-button:active {\n top: 1px;\n left: 1px;\n box-shadow: 1px 1px 0 #ccc;\n}\n.jbx-button:disabled {\n cursor: default;\n color: #999;\n background-color: #f4f4f4;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n.jbx-button:disabled:active {\n top: 0;\n left: 0;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n\n/* LINKS */\n.jbx-a {\n cursor: pointer;\n color: #000;\n box-shadow: #0002 0 2px 0;\n font-weight: 500;\n text-decoration: none;\n}\n.jbx-a::after {\n content: '\u2197';\n color: #0004;\n font-size: var(--font-size-small);\n position: relative;\n top: -1px;\n right: -1px;\n transition: top 0.3s, right 0.3s, color 0.3s;\n}\n.jbx-a:hover,\n.jbx-block-link:hover .jbx-a {\n box-shadow: var(--accent-color) 0 2px 0;\n}\n.jbx-a:hover::after,\n.jbx-block-link:hover .jbx-a::after {\n top: -3px;\n right: -3px;\n color: var(--accent-color);\n}\n\n.jbx-block-link {\n min-width: 300px;\n flex: 1;\n text-decoration: none;\n color: #000;\n display: inline-block;\n padding: var(--size);\n}\na.jbx-a::before,\n.jbx-block-link::before {\n content: '';\n display: block;\n position: absolute;\n background-color: #ecf0f1;\n z-index: -1;\n transition: transform 0.2s, opacity 0.2s;\n transform: scale(0.98) translatey(4px);\n opacity: 0;\n top: -4px;\n left: -6px;\n right: -6px;\n bottom: -4px;\n}\n.jbx-block-link::before {\n border-radius: 16px;\n}\na.jbx-a::before {\n border-radius: 8px;\n}\na.jbx-a:hover::before,\n.jbx-block-link:hover::before {\n transform: scale(1) translatey(0);\n opacity: 1;\n}\n\n.jbx-a {\n display: inline-block;\n}\n\n/* /LINKS */\n\n.jbx-small-text {\n font-size: var(--font-size-small);\n}\n\n.jbx-container {\n max-width: 1080px;\n margin: 0 auto;\n padding: calc(var(--size) * 2.5) calc(var(--size) * 1.5) calc(var(--size) * 4);\n}\n\n.jbx-box {\n flex: 1;\n}\n\n.jbx-inline {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n}\n\n.jbx-stack {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: column;\n}\n\n.jbx-text {\n line-height: 1.4;\n}\n\n.jbx-input {\n color: #777;\n -webkit-text-fill-color: #777;\n opacity: 1;\n flex: 1;\n display: block;\n appearance: none;\n border: none;\n border-radius: var(--radius-small);\n height: var(--control-height);\n background-color: #eee;\n padding: 0 calc(var(--size) * 0.5);\n box-shadow: inset rgba(0, 0, 0, 0.04) 3px 3px 0, inset rgba(0, 0, 0, 0.03) 0.5px 0.5px 0;\n}\n\n/* Chrome hides the stepper until hover and takes its width out of the content\n box, so the value slides sideways as the pointer enters. Keep it painted. */\n.jbx-input[type='number']::-webkit-inner-spin-button,\n.jbx-input[type='number']::-webkit-outer-spin-button {\n opacity: 1;\n}\n\n/* A control inside a tab row sizes to the row, not to itself: it matches the\n line box of the text beside it, so a row holding a field is exactly as tall\n as one that only holds tabs. `flex: none` because `.jbx-input` stretches,\n which is right for a field that owns its row and wrong for one sitting\n between two bits of text. */\n.jbx-tabs .jbx-input,\n.jbx-tabs .jbx-button {\n flex: none;\n height: var(--control-height-compact);\n}\n\n.jbx-dropzone {\n height: 120px;\n flex: 1;\n display: flex;\n text-align: center;\n align-items: center;\n align-content: center;\n justify-content: center;\n flex-direction: column;\n border: 2px dashed #000;\n color: #000;\n padding: 0;\n cursor: pointer;\n}\n.jbx-dropzone:hover {\n border-color: #999;\n}\n.jbx-dropzone span {\n width: 100%;\n cursor: pointer;\n}\n.jbx-dropzone input {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n opacity: 0;\n cursor: pointer;\n}\n\n.jbx-range {\n flex: 1;\n width: 100%;\n appearance: none;\n background-color: #bdc3c780;\n height: var(--size);\n border-radius: 0;\n border-radius: var(--radius-small);\n}\n\n.jbx-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-moz-range-thumb {\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-webkit-slider-runnable-track {\n appearance: none;\n}\n.jbx-range:focus {\n outline: none;\n}\n\n.jbx-bullet-container {\n display: inline-block;\n margin: -8px 4px -8px 0;\n}\n\n.jbx-bullet {\n border: 1px solid #0001;\n color: #000;\n background-color: #0001;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: calc(var(--font-size-small) - 3px);\n height: calc(var(--size) * 1.25);\n width: calc(var(--size) * 1.25);\n border-radius: 100%;\n top: -2px;\n margin-right: 2px;\n}\n\n.jbx-hr {\n margin: calc(var(--size) * 2) auto;\n width: 38.2%;\n border-radius: 0;\n border: none;\n border-top: 2px solid #ecf0f1;\n}\n";
|
|
2
2
|
//# sourceMappingURL=css.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/generated/css.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/generated/css.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,GAAG,iiQAA4hQ,CAAC"}
|
package/dist/generated/css.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Generated by scripts/build-css.mjs from src/style.css. Do not edit.
|
|
2
|
-
export const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height:
|
|
2
|
+
export const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n /* Every interactive control is this tall, so a button, an input and a range\n standing next to each other line up. */\n --control-height: calc(var(--size) * 2.5);\n /* What a control shrinks to inside a tab row, where it has to match the line\n box of the tab's text (`.jbx-text` is `line-height: 1.4`) rather than stand\n on its own -- a row holding one is then exactly as tall as one that doesn't. */\n --control-height-compact: calc(var(--font-size) * 1.4);\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea,\nbutton {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height: var(--control-height);\n transition: top 0.1s, left 0.1s, box-shadow 0.05s;\n}\n.jbx-button:active {\n top: 1px;\n left: 1px;\n box-shadow: 1px 1px 0 #ccc;\n}\n.jbx-button:disabled {\n cursor: default;\n color: #999;\n background-color: #f4f4f4;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n.jbx-button:disabled:active {\n top: 0;\n left: 0;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n\n/* LINKS */\n.jbx-a {\n cursor: pointer;\n color: #000;\n box-shadow: #0002 0 2px 0;\n font-weight: 500;\n text-decoration: none;\n}\n.jbx-a::after {\n content: '↗';\n color: #0004;\n font-size: var(--font-size-small);\n position: relative;\n top: -1px;\n right: -1px;\n transition: top 0.3s, right 0.3s, color 0.3s;\n}\n.jbx-a:hover,\n.jbx-block-link:hover .jbx-a {\n box-shadow: var(--accent-color) 0 2px 0;\n}\n.jbx-a:hover::after,\n.jbx-block-link:hover .jbx-a::after {\n top: -3px;\n right: -3px;\n color: var(--accent-color);\n}\n\n.jbx-block-link {\n min-width: 300px;\n flex: 1;\n text-decoration: none;\n color: #000;\n display: inline-block;\n padding: var(--size);\n}\na.jbx-a::before,\n.jbx-block-link::before {\n content: '';\n display: block;\n position: absolute;\n background-color: #ecf0f1;\n z-index: -1;\n transition: transform 0.2s, opacity 0.2s;\n transform: scale(0.98) translatey(4px);\n opacity: 0;\n top: -4px;\n left: -6px;\n right: -6px;\n bottom: -4px;\n}\n.jbx-block-link::before {\n border-radius: 16px;\n}\na.jbx-a::before {\n border-radius: 8px;\n}\na.jbx-a:hover::before,\n.jbx-block-link:hover::before {\n transform: scale(1) translatey(0);\n opacity: 1;\n}\n\n.jbx-a {\n display: inline-block;\n}\n\n/* /LINKS */\n\n.jbx-small-text {\n font-size: var(--font-size-small);\n}\n\n.jbx-container {\n max-width: 1080px;\n margin: 0 auto;\n padding: calc(var(--size) * 2.5) calc(var(--size) * 1.5) calc(var(--size) * 4);\n}\n\n.jbx-box {\n flex: 1;\n}\n\n.jbx-inline {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n}\n\n.jbx-stack {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: column;\n}\n\n.jbx-text {\n line-height: 1.4;\n}\n\n.jbx-input {\n color: #777;\n -webkit-text-fill-color: #777;\n opacity: 1;\n flex: 1;\n display: block;\n appearance: none;\n border: none;\n border-radius: var(--radius-small);\n height: var(--control-height);\n background-color: #eee;\n padding: 0 calc(var(--size) * 0.5);\n box-shadow: inset rgba(0, 0, 0, 0.04) 3px 3px 0, inset rgba(0, 0, 0, 0.03) 0.5px 0.5px 0;\n}\n\n/* Chrome hides the stepper until hover and takes its width out of the content\n box, so the value slides sideways as the pointer enters. Keep it painted. */\n.jbx-input[type='number']::-webkit-inner-spin-button,\n.jbx-input[type='number']::-webkit-outer-spin-button {\n opacity: 1;\n}\n\n/* A control inside a tab row sizes to the row, not to itself: it matches the\n line box of the text beside it, so a row holding a field is exactly as tall\n as one that only holds tabs. `flex: none` because `.jbx-input` stretches,\n which is right for a field that owns its row and wrong for one sitting\n between two bits of text. */\n.jbx-tabs .jbx-input,\n.jbx-tabs .jbx-button {\n flex: none;\n height: var(--control-height-compact);\n}\n\n.jbx-dropzone {\n height: 120px;\n flex: 1;\n display: flex;\n text-align: center;\n align-items: center;\n align-content: center;\n justify-content: center;\n flex-direction: column;\n border: 2px dashed #000;\n color: #000;\n padding: 0;\n cursor: pointer;\n}\n.jbx-dropzone:hover {\n border-color: #999;\n}\n.jbx-dropzone span {\n width: 100%;\n cursor: pointer;\n}\n.jbx-dropzone input {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n opacity: 0;\n cursor: pointer;\n}\n\n.jbx-range {\n flex: 1;\n width: 100%;\n appearance: none;\n background-color: #bdc3c780;\n height: var(--size);\n border-radius: 0;\n border-radius: var(--radius-small);\n}\n\n.jbx-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-moz-range-thumb {\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-webkit-slider-runnable-track {\n appearance: none;\n}\n.jbx-range:focus {\n outline: none;\n}\n\n.jbx-bullet-container {\n display: inline-block;\n margin: -8px 4px -8px 0;\n}\n\n.jbx-bullet {\n border: 1px solid #0001;\n color: #000;\n background-color: #0001;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: calc(var(--font-size-small) - 3px);\n height: calc(var(--size) * 1.25);\n width: calc(var(--size) * 1.25);\n border-radius: 100%;\n top: -2px;\n margin-right: 2px;\n}\n\n.jbx-hr {\n margin: calc(var(--size) * 2) auto;\n width: 38.2%;\n border-radius: 0;\n border: none;\n border-top: 2px solid #ecf0f1;\n}\n";
|
|
3
3
|
//# sourceMappingURL=css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/generated/css.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,GAAG,GAAG
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/generated/css.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,GAAG,GAAG,yhQAAyhQ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export * from './primitives.js';
|
|
|
2
2
|
export { space } from './spacing.js';
|
|
3
3
|
export { JBX } from './JBX.js';
|
|
4
4
|
export { Box } from './components/Layout.js';
|
|
5
|
+
export { Input } from './components/Input.js';
|
|
5
6
|
export { MoreExperiments } from './components/MoreExperiments.js';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,5 +2,6 @@ export * from './primitives.js';
|
|
|
2
2
|
export { space } from './spacing.js';
|
|
3
3
|
export { JBX } from './JBX.js';
|
|
4
4
|
export { Box } from './components/Layout.js';
|
|
5
|
+
export { Input } from './components/Input.js';
|
|
5
6
|
export { MoreExperiments } from './components/MoreExperiments.js';
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/main.css
CHANGED
|
@@ -12,6 +12,13 @@ html {
|
|
|
12
12
|
--font-size: 16px;
|
|
13
13
|
--font-size-small: 17px;
|
|
14
14
|
--radius-small: 2px;
|
|
15
|
+
/* Every interactive control is this tall, so a button, an input and a range
|
|
16
|
+
standing next to each other line up. */
|
|
17
|
+
--control-height: calc(var(--size) * 2.5);
|
|
18
|
+
/* What a control shrinks to inside a tab row, where it has to match the line
|
|
19
|
+
box of the tab's text (`.jbx-text` is `line-height: 1.4`) rather than stand
|
|
20
|
+
on its own -- a row holding one is then exactly as tall as one that doesn't. */
|
|
21
|
+
--control-height-compact: calc(var(--font-size) * 1.4);
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
@media screen and (max-width: 1200px) {
|
|
@@ -41,7 +48,8 @@ body {
|
|
|
41
48
|
|
|
42
49
|
body,
|
|
43
50
|
input,
|
|
44
|
-
textarea
|
|
51
|
+
textarea,
|
|
52
|
+
button {
|
|
45
53
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
|
46
54
|
}
|
|
47
55
|
|
|
@@ -145,7 +153,7 @@ body,
|
|
|
145
153
|
box-shadow: 3px 3px 0 #ccc;
|
|
146
154
|
padding: 0 calc(var(--size) / 2);
|
|
147
155
|
border: none;
|
|
148
|
-
height:
|
|
156
|
+
height: var(--control-height);
|
|
149
157
|
transition: top 0.1s, left 0.1s, box-shadow 0.05s;
|
|
150
158
|
}
|
|
151
159
|
.jbx-button:active {
|
|
@@ -153,6 +161,17 @@ body,
|
|
|
153
161
|
left: 1px;
|
|
154
162
|
box-shadow: 1px 1px 0 #ccc;
|
|
155
163
|
}
|
|
164
|
+
.jbx-button:disabled {
|
|
165
|
+
cursor: default;
|
|
166
|
+
color: #999;
|
|
167
|
+
background-color: #f4f4f4;
|
|
168
|
+
box-shadow: 1px 1px 0 #e0e0e0;
|
|
169
|
+
}
|
|
170
|
+
.jbx-button:disabled:active {
|
|
171
|
+
top: 0;
|
|
172
|
+
left: 0;
|
|
173
|
+
box-shadow: 1px 1px 0 #e0e0e0;
|
|
174
|
+
}
|
|
156
175
|
|
|
157
176
|
/* LINKS */
|
|
158
177
|
.jbx-a {
|
|
@@ -264,12 +283,30 @@ a.jbx-a:hover::before,
|
|
|
264
283
|
appearance: none;
|
|
265
284
|
border: none;
|
|
266
285
|
border-radius: var(--radius-small);
|
|
267
|
-
height:
|
|
286
|
+
height: var(--control-height);
|
|
268
287
|
background-color: #eee;
|
|
269
288
|
padding: 0 calc(var(--size) * 0.5);
|
|
270
289
|
box-shadow: inset rgba(0, 0, 0, 0.04) 3px 3px 0, inset rgba(0, 0, 0, 0.03) 0.5px 0.5px 0;
|
|
271
290
|
}
|
|
272
291
|
|
|
292
|
+
/* Chrome hides the stepper until hover and takes its width out of the content
|
|
293
|
+
box, so the value slides sideways as the pointer enters. Keep it painted. */
|
|
294
|
+
.jbx-input[type='number']::-webkit-inner-spin-button,
|
|
295
|
+
.jbx-input[type='number']::-webkit-outer-spin-button {
|
|
296
|
+
opacity: 1;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* A control inside a tab row sizes to the row, not to itself: it matches the
|
|
300
|
+
line box of the text beside it, so a row holding a field is exactly as tall
|
|
301
|
+
as one that only holds tabs. `flex: none` because `.jbx-input` stretches,
|
|
302
|
+
which is right for a field that owns its row and wrong for one sitting
|
|
303
|
+
between two bits of text. */
|
|
304
|
+
.jbx-tabs .jbx-input,
|
|
305
|
+
.jbx-tabs .jbx-button {
|
|
306
|
+
flex: none;
|
|
307
|
+
height: var(--control-height-compact);
|
|
308
|
+
}
|
|
309
|
+
|
|
273
310
|
.jbx-dropzone {
|
|
274
311
|
height: 120px;
|
|
275
312
|
flex: 1;
|
package/dist/primitives.d.ts
CHANGED
|
@@ -33,10 +33,6 @@ export declare const Button: (props: React.ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
33
33
|
children?: ReactNode;
|
|
34
34
|
style?: CSSProperties;
|
|
35
35
|
}) => React.JSX.Element;
|
|
36
|
-
export declare const Input: (props: React.InputHTMLAttributes<HTMLInputElement> & {
|
|
37
|
-
children?: ReactNode;
|
|
38
|
-
style?: CSSProperties;
|
|
39
|
-
}) => React.JSX.Element;
|
|
40
36
|
export declare const Range: (props: React.InputHTMLAttributes<HTMLInputElement> & {
|
|
41
37
|
children?: ReactNode;
|
|
42
38
|
style?: CSSProperties;
|
package/dist/primitives.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvE,OAAO,EAA0D,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpG,KAAK,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAErD,KAAK,eAAe,GAAG;IACrB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,CAAC,CAAC;AAEpE,wBAAgB,SAAS,CAAC,CAAC,EACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,WAAW,CAAC,CAAC,CAAM,EAC7B,MAAM,GAAE,eAAoB,GAC3B,CAAC,KAAK,EAAE,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,CA8BnF;AAED,eAAO,MAAM,SAAS;eAhCM,SAAS;YAAU,aAAa;MAAO,KAAK,CAAC,GAAG,CAAC,OAgChB,CAAC;AAE9D,eAAO,MAAM,IAAI;eAlCW,SAAS;YAAU,aAAa;MAAO,KAAK,CAAC,GAAG,CAAC,OAkC1B,CAAC;AAEpD,eAAO,MAAM,SAAS;eApCM,SAAS;YAAU,aAAa;MAAO,KAAK,CAAC,GAAG,CAAC,OAoCf,CAAC;AAE/D,eAAO,MAAM,MAAM;eAtCS,SAAS;YAAU,aAAa;MAAO,KAAK,CAAC,GAAG,CAAC,OA0C5E,CAAC;AAEF,eAAO,MAAM,KAAK;eA5CU,SAAS;YAAU,aAAa;MAAO,KAAK,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":"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"}
|
package/dist/primitives.js
CHANGED
|
@@ -20,7 +20,6 @@ export const Container = Component(`jbx-container`);
|
|
|
20
20
|
export const Text = Component(`jbx-text`);
|
|
21
21
|
export const SmallText = Component(`jbx-small-text`);
|
|
22
22
|
export const Button = Component(`jbx-button`, {}, { element: 'button' });
|
|
23
|
-
export const Input = Component(`jbx-input`, {}, { element: 'input' });
|
|
24
23
|
export const Range = Component(`jbx-range`, {}, {
|
|
25
24
|
element: 'input',
|
|
26
25
|
props: {
|
package/dist/primitives.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAA4B,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,aAAa,EAAgB,MAAM,cAAc,CAAC;AAkBpG,MAAM,UAAU,SAAS,CACvB,SAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":"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"}
|
package/dist/spacing.d.ts
CHANGED
|
@@ -17,6 +17,6 @@ export type SpacingProps = {
|
|
|
17
17
|
padding?: number | number[];
|
|
18
18
|
};
|
|
19
19
|
/** Keys `spacingPropsToStyle` consumes, so they can be kept off the DOM. */
|
|
20
|
-
export declare const SPACING_PROPS: readonly [
|
|
20
|
+
export declare const SPACING_PROPS: readonly ['v', 'h', 'gap', 'padding'];
|
|
21
21
|
export declare function spacingPropsToStyle({ v, h, gap, padding }: SpacingProps): CSSProperties;
|
|
22
22
|
//# sourceMappingURL=spacing.d.ts.map
|
package/dist/spacing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spacing.d.ts","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG;IACzB,yCAAyC;IACzC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"spacing.d.ts","sourceRoot":"","sources":["../src/spacing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG;IACzB,yCAAyC;IACzC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,aAAa,YAAI,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,CAAU,CAAC;AAEnE,wBAAgB,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAevF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jbx",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"author": "hi@javier.xyz",
|
|
5
5
|
"license": "Unlicensed",
|
|
6
6
|
"repository": {
|
|
@@ -30,28 +30,27 @@
|
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=18"
|
|
32
32
|
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"css": "node ./scripts/build-css.mjs",
|
|
35
|
-
"prebuild": "npm run css",
|
|
36
|
-
"build": "tsc -p tsconfig.build.json",
|
|
37
|
-
"dev": "npm run css && tsc -p tsconfig.build.json --watch",
|
|
38
|
-
"pretypecheck": "npm run css",
|
|
39
|
-
"typecheck": "tsc --noEmit",
|
|
40
|
-
"pretest": "npm run build",
|
|
41
|
-
"test": "node ./scripts/smoke.mjs",
|
|
42
|
-
"prepublishOnly": "npm run typecheck && npm test"
|
|
43
|
-
},
|
|
44
33
|
"peerDependencies": {
|
|
45
34
|
"react": "^17 || ^18 || ^19"
|
|
46
35
|
},
|
|
47
36
|
"devDependencies": {
|
|
48
37
|
"@types/react": "^19.2.18",
|
|
49
|
-
"@types/react-dom": "^19.2.
|
|
38
|
+
"@types/react-dom": "^19.2.4",
|
|
50
39
|
"react": "^19.2.8",
|
|
51
40
|
"react-dom": "^19.2.8",
|
|
52
|
-
"typescript": "^
|
|
41
|
+
"typescript": "^7.0.2"
|
|
53
42
|
},
|
|
54
43
|
"publishConfig": {
|
|
55
44
|
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"css": "node ./scripts/build-css.mjs",
|
|
48
|
+
"prebuild": "pnpm run css",
|
|
49
|
+
"build": "tsc -p tsconfig.build.json",
|
|
50
|
+
"dev": "pnpm run css && tsc -p tsconfig.build.json --watch",
|
|
51
|
+
"pretypecheck": "pnpm run css",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"pretest": "pnpm run build",
|
|
54
|
+
"test": "node ./scripts/smoke.mjs"
|
|
56
55
|
}
|
|
57
|
-
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Component } from '../primitives.js';
|
|
5
|
+
|
|
6
|
+
const InputBase = Component<React.InputHTMLAttributes<HTMLInputElement>>(
|
|
7
|
+
`jbx-input`,
|
|
8
|
+
{},
|
|
9
|
+
{ element: 'input' }
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> & {
|
|
13
|
+
value?: string | number | readonly string[];
|
|
14
|
+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
15
|
+
/**
|
|
16
|
+
* Opt in to number handling. `value` is a number, and this is called with a
|
|
17
|
+
* number -- but only once what was typed parses and lands inside `min`/`max`,
|
|
18
|
+
* so a half typed value stays on screen without ever reaching the caller.
|
|
19
|
+
* Implies `type="number"`.
|
|
20
|
+
*/
|
|
21
|
+
onValueChange?: (value: number) => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function toNumber(value: InputProps['value']): number {
|
|
25
|
+
return typeof value === 'number' ? value : Number(value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A text input, and -- with `onValueChange` -- a number input that only commits
|
|
30
|
+
* what parses:
|
|
31
|
+
*
|
|
32
|
+
* <Input value={seconds} onValueChange={secondsSet} min={0.2} max={60} />
|
|
33
|
+
*
|
|
34
|
+
* Without `onValueChange` this is a plain controlled input and the caller owns
|
|
35
|
+
* `value` and `onChange` as usual.
|
|
36
|
+
*/
|
|
37
|
+
export function Input({
|
|
38
|
+
value,
|
|
39
|
+
onChange,
|
|
40
|
+
onValueChange,
|
|
41
|
+
onBlur,
|
|
42
|
+
type,
|
|
43
|
+
min,
|
|
44
|
+
max,
|
|
45
|
+
...props
|
|
46
|
+
}: InputProps) {
|
|
47
|
+
// Hooks run either way; only the returned tree branches.
|
|
48
|
+
const [draft, draftSet] = useState(() => String(value ?? ''));
|
|
49
|
+
const [lastValue, lastValueSet] = useState(value);
|
|
50
|
+
|
|
51
|
+
if (!onValueChange) {
|
|
52
|
+
return (
|
|
53
|
+
<InputBase
|
|
54
|
+
{...props}
|
|
55
|
+
type={type}
|
|
56
|
+
min={min}
|
|
57
|
+
max={max}
|
|
58
|
+
value={value}
|
|
59
|
+
onChange={onChange}
|
|
60
|
+
onBlur={onBlur}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (value !== lastValue) {
|
|
66
|
+
lastValueSet(value);
|
|
67
|
+
// `2.50` parses to the value we already hold -- adopting `String(value)`
|
|
68
|
+
// here would eat the trailing zero out from under the caret mid-typing.
|
|
69
|
+
if (Number(draft) !== toNumber(value)) draftSet(String(value ?? ''));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function draftChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
73
|
+
const next = event.target.value;
|
|
74
|
+
draftSet(next);
|
|
75
|
+
onChange?.(event);
|
|
76
|
+
|
|
77
|
+
const parsed = Number(next);
|
|
78
|
+
if (next.trim() === '' || !Number.isFinite(parsed)) return;
|
|
79
|
+
if (min !== undefined && parsed < toNumber(min)) return;
|
|
80
|
+
if (max !== undefined && parsed > toNumber(max)) return;
|
|
81
|
+
|
|
82
|
+
onValueChange!(parsed);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Leaving a half typed value behind is how a field ends up showing something
|
|
86
|
+
// the rest of the page never agreed to. Snap back to the live value on the
|
|
87
|
+
// way out.
|
|
88
|
+
function draftBlur(event: React.FocusEvent<HTMLInputElement>) {
|
|
89
|
+
if (Number(draft) !== toNumber(value)) draftSet(String(value ?? ''));
|
|
90
|
+
onBlur?.(event);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<InputBase
|
|
95
|
+
{...props}
|
|
96
|
+
type={type ?? 'number'}
|
|
97
|
+
min={min}
|
|
98
|
+
max={max}
|
|
99
|
+
value={draft}
|
|
100
|
+
onChange={draftChange}
|
|
101
|
+
onBlur={draftBlur}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
@@ -38,15 +38,19 @@ const PROJECT_DATA = [
|
|
|
38
38
|
name: 'Cohesive Colors',
|
|
39
39
|
description: 'Tool that can help you to create cohesive color palettes',
|
|
40
40
|
url: 'https://javier.xyz/cohesive-colors'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'img2css',
|
|
44
|
+
description: 'Tool that can convert any image into a pure CSS image',
|
|
45
|
+
url: 'https://javier.xyz/img2css'
|
|
41
46
|
}
|
|
42
47
|
] as const;
|
|
43
48
|
|
|
44
49
|
const maxItems = 5;
|
|
45
50
|
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// site always renders the same slice — no hydration mismatch, no build-to-build churn.
|
|
51
|
+
// Fallback offset for a site that isn't in PROJECT_DATA itself. Derived from the site's
|
|
52
|
+
// own name rather than randomized, so it always renders the same slice — no hydration
|
|
53
|
+
// mismatch, no build-to-build churn.
|
|
50
54
|
function seedFor(key: string) {
|
|
51
55
|
let hash = 0;
|
|
52
56
|
for (let idx = 0; idx < key.length; idx++) {
|
|
@@ -60,11 +64,18 @@ type MoreExperimentsProps = {
|
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
export function MoreExperiments({ exclude }: MoreExperimentsProps) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
// A site listed in PROJECT_DATA links to the maxItems entries that follow it. Since
|
|
68
|
+
// every site starts one step further along, each project ends up linked from the same
|
|
69
|
+
// number of sites, instead of the first maxItems entries being the only ones to show up.
|
|
70
|
+
const selfIdx = exclude
|
|
71
|
+
? PROJECT_DATA.findIndex((project) => project.url.includes(exclude))
|
|
72
|
+
: -1;
|
|
73
|
+
|
|
74
|
+
const projects =
|
|
75
|
+
selfIdx === -1 ? PROJECT_DATA : PROJECT_DATA.filter((_0, idx) => idx !== selfIdx);
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
// Dropping self shifts the tail left by one, so this index is already the next project.
|
|
78
|
+
const seed = selfIdx === -1 ? (exclude ? seedFor(exclude) : 0) : selfIdx;
|
|
68
79
|
|
|
69
80
|
const items = new Array(Math.min(maxItems, projects.length)).fill('').map((_0, idx) => {
|
|
70
81
|
const project = projects[(seed + idx) % projects.length];
|
package/src/generated/css.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by scripts/build-css.mjs from src/style.css. Do not edit.
|
|
2
|
-
export const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height:
|
|
2
|
+
export const CSS = "html {\n box-sizing: border-box;\n}\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\n:root {\n --size: 16px;\n --font-size: 16px;\n --font-size-small: 17px;\n --radius-small: 2px;\n /* Every interactive control is this tall, so a button, an input and a range\n standing next to each other line up. */\n --control-height: calc(var(--size) * 2.5);\n /* What a control shrinks to inside a tab row, where it has to match the line\n box of the tab's text (`.jbx-text` is `line-height: 1.4`) rather than stand\n on its own -- a row holding one is then exactly as tall as one that doesn't. */\n --control-height-compact: calc(var(--font-size) * 1.4);\n}\n\n@media screen and (max-width: 1200px) {\n :root {\n --font-size: 18px;\n --font-size-small: 16px;\n --size: 14px;\n }\n}\n\n@media screen and (max-width: 600px) {\n :root {\n --font-size: 16px;\n --font-size-small: 14px;\n }\n}\n\n* {\n padding: 0;\n margin: 0;\n position: relative;\n}\n\nbody {\n touch-action: pan-y;\n}\n\nbody,\ninput,\ntextarea,\nbutton {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n}\n\nbody {\n background: #fcfcfd;\n color: #000;\n}\n\nh1,\nh2,\nh3,\nh4 {\n line-height: 1;\n padding: 0;\n font-variation-settings: 'wght' 600;\n font-weight: 600;\n color: var(--base-font-color-bright);\n}\nh1 {\n font-variation-settings: 'wdth' 107, 'wght' 650;\n font-weight: 650;\n}\n\nstrong,\nb {\n font-weight: 500;\n}\n\n.jbx-main-h1 {\n display: inline-block;\n background-color: var(--accent-color);\n font-size: calc(var(--font-size) * 2);\n padding: 8px;\n}\n\n.jbx-h1 {\n font-size: calc(var(--font-size) * 2);\n font-weight: 700;\n}\n.jbx-h2 {\n font-size: calc(var(--font-size) * 1.25);\n}\n.jbx-h3 {\n font-size: calc(var(--font-size) * 1.125);\n}\n.jbx-h4 {\n font-size: var(--font-size-small);\n text-transform: uppercase;\n}\n\n/* base text */\nhtml,\nbody,\n.jbx-button,\n.jbx-input {\n font-size: var(--font-size);\n line-height: 1;\n}\n\n.jbx-code-snippet {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n}\n.jbx-code-snippet:focus {\n outline: none;\n}\n\n.jbx-code-area {\n border-radius: var(--size);\n font-family: monaco, monospace;\n border: none;\n width: 100%;\n font-size: calc(var(--size) - 3px);\n line-height: 1.33;\n padding: var(--size) calc(var(--size) * 1.2);\n background: #ecf0f1;\n color: #34495e;\n resize: none;\n min-height: 120px;\n}\n.jbx-code-area:focus {\n outline: none;\n}\n\n.jbx-button {\n color: #000;\n border-radius: var(--radius-small);\n appearance: none;\n user-select: none;\n cursor: pointer;\n display: inline-block;\n background-color: #eee;\n box-shadow: 3px 3px 0 #ccc;\n padding: 0 calc(var(--size) / 2);\n border: none;\n height: var(--control-height);\n transition: top 0.1s, left 0.1s, box-shadow 0.05s;\n}\n.jbx-button:active {\n top: 1px;\n left: 1px;\n box-shadow: 1px 1px 0 #ccc;\n}\n.jbx-button:disabled {\n cursor: default;\n color: #999;\n background-color: #f4f4f4;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n.jbx-button:disabled:active {\n top: 0;\n left: 0;\n box-shadow: 1px 1px 0 #e0e0e0;\n}\n\n/* LINKS */\n.jbx-a {\n cursor: pointer;\n color: #000;\n box-shadow: #0002 0 2px 0;\n font-weight: 500;\n text-decoration: none;\n}\n.jbx-a::after {\n content: '↗';\n color: #0004;\n font-size: var(--font-size-small);\n position: relative;\n top: -1px;\n right: -1px;\n transition: top 0.3s, right 0.3s, color 0.3s;\n}\n.jbx-a:hover,\n.jbx-block-link:hover .jbx-a {\n box-shadow: var(--accent-color) 0 2px 0;\n}\n.jbx-a:hover::after,\n.jbx-block-link:hover .jbx-a::after {\n top: -3px;\n right: -3px;\n color: var(--accent-color);\n}\n\n.jbx-block-link {\n min-width: 300px;\n flex: 1;\n text-decoration: none;\n color: #000;\n display: inline-block;\n padding: var(--size);\n}\na.jbx-a::before,\n.jbx-block-link::before {\n content: '';\n display: block;\n position: absolute;\n background-color: #ecf0f1;\n z-index: -1;\n transition: transform 0.2s, opacity 0.2s;\n transform: scale(0.98) translatey(4px);\n opacity: 0;\n top: -4px;\n left: -6px;\n right: -6px;\n bottom: -4px;\n}\n.jbx-block-link::before {\n border-radius: 16px;\n}\na.jbx-a::before {\n border-radius: 8px;\n}\na.jbx-a:hover::before,\n.jbx-block-link:hover::before {\n transform: scale(1) translatey(0);\n opacity: 1;\n}\n\n.jbx-a {\n display: inline-block;\n}\n\n/* /LINKS */\n\n.jbx-small-text {\n font-size: var(--font-size-small);\n}\n\n.jbx-container {\n max-width: 1080px;\n margin: 0 auto;\n padding: calc(var(--size) * 2.5) calc(var(--size) * 1.5) calc(var(--size) * 4);\n}\n\n.jbx-box {\n flex: 1;\n}\n\n.jbx-inline {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n}\n\n.jbx-stack {\n flex: 1;\n display: flex;\n flex-wrap: wrap;\n flex-direction: column;\n}\n\n.jbx-text {\n line-height: 1.4;\n}\n\n.jbx-input {\n color: #777;\n -webkit-text-fill-color: #777;\n opacity: 1;\n flex: 1;\n display: block;\n appearance: none;\n border: none;\n border-radius: var(--radius-small);\n height: var(--control-height);\n background-color: #eee;\n padding: 0 calc(var(--size) * 0.5);\n box-shadow: inset rgba(0, 0, 0, 0.04) 3px 3px 0, inset rgba(0, 0, 0, 0.03) 0.5px 0.5px 0;\n}\n\n/* Chrome hides the stepper until hover and takes its width out of the content\n box, so the value slides sideways as the pointer enters. Keep it painted. */\n.jbx-input[type='number']::-webkit-inner-spin-button,\n.jbx-input[type='number']::-webkit-outer-spin-button {\n opacity: 1;\n}\n\n/* A control inside a tab row sizes to the row, not to itself: it matches the\n line box of the text beside it, so a row holding a field is exactly as tall\n as one that only holds tabs. `flex: none` because `.jbx-input` stretches,\n which is right for a field that owns its row and wrong for one sitting\n between two bits of text. */\n.jbx-tabs .jbx-input,\n.jbx-tabs .jbx-button {\n flex: none;\n height: var(--control-height-compact);\n}\n\n.jbx-dropzone {\n height: 120px;\n flex: 1;\n display: flex;\n text-align: center;\n align-items: center;\n align-content: center;\n justify-content: center;\n flex-direction: column;\n border: 2px dashed #000;\n color: #000;\n padding: 0;\n cursor: pointer;\n}\n.jbx-dropzone:hover {\n border-color: #999;\n}\n.jbx-dropzone span {\n width: 100%;\n cursor: pointer;\n}\n.jbx-dropzone input {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n opacity: 0;\n cursor: pointer;\n}\n\n.jbx-range {\n flex: 1;\n width: 100%;\n appearance: none;\n background-color: #bdc3c780;\n height: var(--size);\n border-radius: 0;\n border-radius: var(--radius-small);\n}\n\n.jbx-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-moz-range-thumb {\n appearance: none;\n box-shadow: none;\n border-radius: 0;\n height: calc(var(--size) * 2);\n width: var(--size);\n background-color: #000;\n border: none;\n border-radius: var(--radius-small);\n}\n.jbx-range::-webkit-slider-runnable-track {\n appearance: none;\n}\n.jbx-range:focus {\n outline: none;\n}\n\n.jbx-bullet-container {\n display: inline-block;\n margin: -8px 4px -8px 0;\n}\n\n.jbx-bullet {\n border: 1px solid #0001;\n color: #000;\n background-color: #0001;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: calc(var(--font-size-small) - 3px);\n height: calc(var(--size) * 1.25);\n width: calc(var(--size) * 1.25);\n border-radius: 100%;\n top: -2px;\n margin-right: 2px;\n}\n\n.jbx-hr {\n margin: calc(var(--size) * 2) auto;\n width: 38.2%;\n border-radius: 0;\n border: none;\n border-top: 2px solid #ecf0f1;\n}\n";
|
package/src/index.tsx
CHANGED
package/src/primitives.tsx
CHANGED
|
@@ -65,12 +65,6 @@ export const Button = Component<React.ButtonHTMLAttributes<HTMLButtonElement>>(
|
|
|
65
65
|
{ element: 'button' }
|
|
66
66
|
);
|
|
67
67
|
|
|
68
|
-
export const Input = Component<React.InputHTMLAttributes<HTMLInputElement>>(
|
|
69
|
-
`jbx-input`,
|
|
70
|
-
{},
|
|
71
|
-
{ element: 'input' }
|
|
72
|
-
);
|
|
73
|
-
|
|
74
68
|
export const Range = Component<React.InputHTMLAttributes<HTMLInputElement>>(
|
|
75
69
|
`jbx-range`,
|
|
76
70
|
{},
|
package/src/style.css
CHANGED
|
@@ -12,6 +12,13 @@ html {
|
|
|
12
12
|
--font-size: 16px;
|
|
13
13
|
--font-size-small: 17px;
|
|
14
14
|
--radius-small: 2px;
|
|
15
|
+
/* Every interactive control is this tall, so a button, an input and a range
|
|
16
|
+
standing next to each other line up. */
|
|
17
|
+
--control-height: calc(var(--size) * 2.5);
|
|
18
|
+
/* What a control shrinks to inside a tab row, where it has to match the line
|
|
19
|
+
box of the tab's text (`.jbx-text` is `line-height: 1.4`) rather than stand
|
|
20
|
+
on its own -- a row holding one is then exactly as tall as one that doesn't. */
|
|
21
|
+
--control-height-compact: calc(var(--font-size) * 1.4);
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
@media screen and (max-width: 1200px) {
|
|
@@ -41,7 +48,8 @@ body {
|
|
|
41
48
|
|
|
42
49
|
body,
|
|
43
50
|
input,
|
|
44
|
-
textarea
|
|
51
|
+
textarea,
|
|
52
|
+
button {
|
|
45
53
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
|
46
54
|
}
|
|
47
55
|
|
|
@@ -145,7 +153,7 @@ body,
|
|
|
145
153
|
box-shadow: 3px 3px 0 #ccc;
|
|
146
154
|
padding: 0 calc(var(--size) / 2);
|
|
147
155
|
border: none;
|
|
148
|
-
height:
|
|
156
|
+
height: var(--control-height);
|
|
149
157
|
transition: top 0.1s, left 0.1s, box-shadow 0.05s;
|
|
150
158
|
}
|
|
151
159
|
.jbx-button:active {
|
|
@@ -153,6 +161,17 @@ body,
|
|
|
153
161
|
left: 1px;
|
|
154
162
|
box-shadow: 1px 1px 0 #ccc;
|
|
155
163
|
}
|
|
164
|
+
.jbx-button:disabled {
|
|
165
|
+
cursor: default;
|
|
166
|
+
color: #999;
|
|
167
|
+
background-color: #f4f4f4;
|
|
168
|
+
box-shadow: 1px 1px 0 #e0e0e0;
|
|
169
|
+
}
|
|
170
|
+
.jbx-button:disabled:active {
|
|
171
|
+
top: 0;
|
|
172
|
+
left: 0;
|
|
173
|
+
box-shadow: 1px 1px 0 #e0e0e0;
|
|
174
|
+
}
|
|
156
175
|
|
|
157
176
|
/* LINKS */
|
|
158
177
|
.jbx-a {
|
|
@@ -264,12 +283,30 @@ a.jbx-a:hover::before,
|
|
|
264
283
|
appearance: none;
|
|
265
284
|
border: none;
|
|
266
285
|
border-radius: var(--radius-small);
|
|
267
|
-
height:
|
|
286
|
+
height: var(--control-height);
|
|
268
287
|
background-color: #eee;
|
|
269
288
|
padding: 0 calc(var(--size) * 0.5);
|
|
270
289
|
box-shadow: inset rgba(0, 0, 0, 0.04) 3px 3px 0, inset rgba(0, 0, 0, 0.03) 0.5px 0.5px 0;
|
|
271
290
|
}
|
|
272
291
|
|
|
292
|
+
/* Chrome hides the stepper until hover and takes its width out of the content
|
|
293
|
+
box, so the value slides sideways as the pointer enters. Keep it painted. */
|
|
294
|
+
.jbx-input[type='number']::-webkit-inner-spin-button,
|
|
295
|
+
.jbx-input[type='number']::-webkit-outer-spin-button {
|
|
296
|
+
opacity: 1;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* A control inside a tab row sizes to the row, not to itself: it matches the
|
|
300
|
+
line box of the text beside it, so a row holding a field is exactly as tall
|
|
301
|
+
as one that only holds tabs. `flex: none` because `.jbx-input` stretches,
|
|
302
|
+
which is right for a field that owns its row and wrong for one sitting
|
|
303
|
+
between two bits of text. */
|
|
304
|
+
.jbx-tabs .jbx-input,
|
|
305
|
+
.jbx-tabs .jbx-button {
|
|
306
|
+
flex: none;
|
|
307
|
+
height: var(--control-height-compact);
|
|
308
|
+
}
|
|
309
|
+
|
|
273
310
|
.jbx-dropzone {
|
|
274
311
|
height: 120px;
|
|
275
312
|
flex: 1;
|