jbx 2.3.0 → 2.5.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/roll.js ADDED
@@ -0,0 +1,235 @@
1
+ import React, { Fragment } from 'react';
2
+
3
+ // import './style.css';
4
+
5
+ const SIZE = window.innerWidth > 1280 ? 16 : window.innerWidth > 640 ? 14 : 12;
6
+ const BASE_RADIUS = SIZE / 3;
7
+ const BASE_FONT_SIZE = SIZE;
8
+
9
+ function Component(className, styleSrc = {}, config = {}) {
10
+ const { element = `div`, styleProps } = config;
11
+
12
+ return function MakeComponent({ children, style = {}, ...props }) {
13
+ const passProps = styleProps
14
+ ? Object.keys(props)
15
+ .filter((e) => !styleProps.includes(e))
16
+ .reduce((acc, p) => {
17
+ acc[p] = props[p];
18
+ return acc;
19
+ }, {})
20
+ : props;
21
+
22
+ const calculatedStyle = typeof styleSrc === 'function' ? styleSrc(props) : styleSrc;
23
+
24
+ return React.createElement(
25
+ element,
26
+ {
27
+ className,
28
+ style: { ...style, ...calculatedStyle },
29
+ ...passProps
30
+ },
31
+ children
32
+ );
33
+ };
34
+ }
35
+
36
+ const Container = Component(`jbx-container`);
37
+
38
+ const Text = Component(`jbx-text`);
39
+
40
+ const SmallText = Component(`jbx-small-text`);
41
+
42
+ const Button = Component(`jbx-button`, {}, { element: 'button' });
43
+
44
+ const Input = Component(`jbx-input`, null, { element: 'input' });
45
+ const Range = Component(`jbx-range`, null, { element: 'input' });
46
+
47
+ const HeaderH1 = Component(`jbx-h${1}`, null, { element: 'h1' });
48
+ const HeaderH2 = Component(`jbx-h${2}`, null, { element: 'h2' });
49
+ const HeaderH3 = Component(`jbx-h${3}`, null, { element: 'h3' });
50
+ const HeaderH4 = Component(`jbx-h${4}`, null, { element: 'h4' });
51
+
52
+ const MainHeader = function MainHeader({ children, style }) {
53
+ const content = String(children).split(' ');
54
+
55
+ return React.createElement(
56
+ Fragment,
57
+ {},
58
+ content.map((word) =>
59
+ React.createElement(
60
+ HeaderH1,
61
+ {
62
+ key: word,
63
+ style: {
64
+ fontWeight: 900,
65
+ display: 'inline-block',
66
+ width: 'auto',
67
+ padding: '6px',
68
+ margin: 0,
69
+ backgroundColor: 'var(--accent-color)',
70
+ ...style
71
+ }
72
+ },
73
+ word
74
+ )
75
+ )
76
+ );
77
+ };
78
+
79
+ const A = Component(`jbx-a`, null, { element: 'a' });
80
+
81
+ const Space = Component(`jbx-space`, (props) => ({
82
+ display: props.inline ? 'inline-block' : 'block',
83
+ height: `${SIZE * props.h}px`,
84
+ width: `${SIZE * props.w}px`
85
+ }));
86
+
87
+ const Box = Component(`jbx-box`, ({ padding, hideOnSmall, flex, minWidth }) => {
88
+ return {
89
+ flex,
90
+ minWidth,
91
+ padding: padding
92
+ ? [padding]
93
+ .flat()
94
+ .map((paddingValue) => `${paddingValue * SIZE}px`)
95
+ .join(` `)
96
+ : null
97
+ };
98
+ });
99
+
100
+ const Inline = Component(`jbx-inline`, ({ v, h, gap }) => ({
101
+ marginLeft: `${h * SIZE}px`,
102
+ marginRight: `${h * SIZE}px`,
103
+ marginTop: `${v * SIZE}px`,
104
+ marginBottom: `${v * SIZE}px`,
105
+ gap: `${gap * SIZE}px`
106
+ }));
107
+
108
+ const Stack = Component(`jbx-stack`, ({ v, h, gap }) => ({
109
+ marginLeft: `${h * SIZE}px`,
110
+ marginRight: `${h * SIZE}px`,
111
+ marginTop: `${v * SIZE}px`,
112
+ marginBottom: `${v * SIZE}px`,
113
+ gap: `${gap * SIZE}px`
114
+ }));
115
+
116
+ // export const LinkButton = Styled.a({
117
+ // capHeight: BASE_FONT_SIZE,
118
+ // color: '#3498db',
119
+ // cursor: 'pointer',
120
+ // borderRadius: 5,
121
+ // borderTop: '1px solid #3498db10',
122
+ // borderBottom: '1px solid #0000',
123
+ // backgroundColor: '#3498db20',
124
+ // height: BASE_FONT_SIZE * 2,
125
+ // display: 'flex',
126
+ // alignItems: 'center',
127
+ // alignContent: 'center',
128
+ // justifyContent: 'center',
129
+ // padding: 0,
130
+ // '&:hover': {
131
+ // boxShadow: `rgba(0, 0, 0, 0.1) 0 1px 1px, rgba(0, 0, 0, 0.1) 0 3px 12px`
132
+ // }
133
+ // });
134
+
135
+ const Dropzone = Component(`jbx-dropzone`);
136
+
137
+ const Ul = Component(
138
+ `jbx-ul`,
139
+ {
140
+ margin: 0,
141
+ padding: `0 0 0 ${BASE_FONT_SIZE / 4}px`
142
+ },
143
+ { element: 'ul' }
144
+ );
145
+
146
+ const Li = Component(
147
+ `jbx-li`,
148
+ {
149
+ margin: `0 0 0 ${SIZE}px`,
150
+ padding: `${SIZE / 4}px 0`
151
+ },
152
+ { element: 'li' }
153
+ );
154
+
155
+ const Tabs = Component(`jbx-tabs`);
156
+
157
+ const Tab = Component(
158
+ `jbx-tabs--tab`,
159
+ ({ info, active }) => ({
160
+ userSelect: 'none',
161
+ cursor: 'pointer',
162
+ backgroundColor: active ? '#000' : info ? '#fff' : '#ecf0f1',
163
+ color: active ? '#fff' : '#000',
164
+ padding: SIZE / 2,
165
+ paddingLeft: info ? 0 : SIZE / 2
166
+ }),
167
+ { styleProps: ['info', 'active'] }
168
+ );
169
+
170
+ const CodeSnippet = Component(`jbx-code-snippet`, null, { element: 'pre' });
171
+ const CodeTextarea = Component(`jbx-code-area`, null, { element: 'textarea' });
172
+
173
+ const CheckboxHidden = Component(`jbx-checkbox-hidden`, ({ checked }) => {
174
+ return {
175
+ height: SIZE * 2 - 4,
176
+ width: SIZE * 2 - 4,
177
+ paddingTop: 2,
178
+ paddingLeft: 2,
179
+ backgroundColor: checked ? 'var(--accent-color)' : 'white',
180
+ borderRadius: BASE_RADIUS,
181
+ boxShadow: checked
182
+ ? 'inset rgba(0, 0, 0, 0.07) 0 0 0 1px'
183
+ : 'inset rgba(0, 0, 0, 0.33) 0 0 0 1.5px',
184
+ cursor: 'pointer'
185
+ };
186
+ });
187
+
188
+ const Checkbox = function Checkbox({ label, checked, onChange }) {
189
+ return React.createElement(
190
+ Inline,
191
+ {
192
+ onClick: () => {
193
+ if (onChange) {
194
+ onChange(!checked);
195
+ }
196
+ },
197
+ style: {
198
+ alignItems: 'center',
199
+ cursor: 'pointer'
200
+ }
201
+ },
202
+ [
203
+ React.createElement(
204
+ CheckboxHidden,
205
+ {
206
+ key: 0,
207
+ checked
208
+ },
209
+ React.createElement(
210
+ 'svg',
211
+ {
212
+ xmlns: 'http://www.w3.org/2000/svg',
213
+ width: SIZE * 2 - 8,
214
+ height: SIZE * 2 - 8,
215
+ fill: 'none',
216
+ stroke: 'currentColor',
217
+ strokeLinecap: 'round',
218
+ strokeLinejoin: 'round',
219
+ strokeWidth: '2',
220
+ className: 'feather feather-check',
221
+ viewBox: '0 0 24 24',
222
+ color: checked ? 'white' : '#ddd'
223
+ },
224
+ React.createElement('path', {
225
+ d: 'M20 6L9 17 4 12'
226
+ })
227
+ )
228
+ ),
229
+ React.createElement(Space, { key: 1, w: 0.5 }),
230
+ React.createElement(Text, { key: 2, style: { userSelect: 'none' } }, label)
231
+ ]
232
+ );
233
+ };
234
+
235
+ export { A, Box, Button, Checkbox, CheckboxHidden, CodeSnippet, CodeTextarea, Component, Container, Dropzone, HeaderH1, HeaderH2, HeaderH3, HeaderH4, Inline, Input, Li, MainHeader, Range, SmallText, Space, Stack, Tab, Tabs, Text, Ul };
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { classList, layoutPropsToStyles } from '../';
3
+
4
+ type Box = {
5
+ children?: React.ReactNode;
6
+ smallText?: true | false;
7
+ padding?: number;
8
+ flex?: number;
9
+ style: any;
10
+ };
11
+
12
+ export function Box({ children, smallText, padding, flex, style }: Box) {
13
+ const styles = {
14
+ flex,
15
+ ...layoutPropsToStyles({ padding }),
16
+ ...style
17
+ };
18
+
19
+ const className = classList({
20
+ 'jb-box': true,
21
+ 'jbx-small-text': smallText
22
+ });
23
+
24
+ return (
25
+ <div className={className} style={styles}>
26
+ {children}
27
+ </div>
28
+ );
29
+ }
@@ -0,0 +1,110 @@
1
+ // @ts-nocheck
2
+
3
+ import React, { Fragment } from 'react';
4
+ import { Text, Space, Ul, Li, Inline, Box, A } from '../index';
5
+
6
+ const PROJECT_DATA = [
7
+ {
8
+ name: 'PINTR',
9
+ description: 'Tool that turns your images into plotter-like line drawings',
10
+ url: 'https://javier.xyz/pintr/'
11
+ },
12
+ {
13
+ name: 'Visual Center',
14
+ description: 'Tool that help you visually center objects in a container',
15
+ url: 'https://javier.xyz/visual-center/'
16
+ },
17
+ {
18
+ name: 'Brutalita',
19
+ description:
20
+ 'Grid based font editor and font. Create fonts in the browser and export OpenType files',
21
+ url: 'https://brutalita.com/'
22
+ },
23
+ {
24
+ name: 'Morphin',
25
+ description:
26
+ 'Create animated CSS transitions. Add sprites and get the code ready to paste in your site',
27
+ url: 'https://javier.xyz/morphin/'
28
+ },
29
+ {
30
+ name: 'Droste Creator',
31
+ description: 'Create recursive images with the droste effect',
32
+ url: 'https://javier.xyz/droste-creator/'
33
+ },
34
+ {
35
+ name: 'Sombras.app',
36
+ description: 'Create art with shadows. Draw shadows and get 3D objects that project them.',
37
+ url: 'https://sombras.app/'
38
+ },
39
+ {
40
+ name: 'Cohesive Colors',
41
+ description: 'Tool that can help you to create cohesive color palettes',
42
+ url: 'https://javier.xyz/cohesive-colors/'
43
+ }
44
+ ] as const;
45
+
46
+ const projects = PROJECT_DATA.filter(
47
+ (project) => !project.url.includes(document.location.pathname)
48
+ );
49
+ const projectIndex = PROJECT_DATA.findIndex(
50
+ (project) => !project.url.includes(document.location.pathname)
51
+ );
52
+ const seed = Math.floor(new Date().getTime() / (60 * 60 * 1000)) + projectIndex;
53
+
54
+ export function MoreExperiments() {
55
+ const items = new Array(4).fill('').map((_0, idx) => {
56
+ const project = projects[(seed + idx) % projects.length];
57
+ return (
58
+ <Li key={project.url}>
59
+ <A href={project.url}>{project.name}</A>
60
+ {`, `}
61
+ {project.description}.
62
+ </Li>
63
+ );
64
+ });
65
+
66
+ return (
67
+ <Fragment>
68
+ <Text>More experiments</Text>
69
+ <Space h={1} />
70
+ <Ul>{items}</Ul>
71
+ </Fragment>
72
+ );
73
+ }
74
+
75
+ export function MoreExperimentsBlocks() {
76
+ const items = new Array(3).fill('').map((_0, idx) => {
77
+ const project = projects[(seed + idx) % projects.length];
78
+ return <MoreExperimentsBlock key={project.name} {...project} />;
79
+ });
80
+
81
+ return (
82
+ <Fragment>
83
+ <Text>More experiments</Text>
84
+ <Space h={1} />
85
+ <Inline wrap gap={1}>
86
+ {items}
87
+ </Inline>
88
+ </Fragment>
89
+ );
90
+ }
91
+
92
+ function MoreExperimentsBlock({
93
+ name,
94
+ description,
95
+ url
96
+ }: {
97
+ name: string;
98
+ description: string;
99
+ url: string;
100
+ }) {
101
+ return (
102
+ <Box smallText style={{ width: 300 }}>
103
+ <a className="jbx-a" href={url}>
104
+ {name}
105
+ </a>
106
+ <Space h={0.5} />
107
+ <Text>{description}.</Text>
108
+ </Box>
109
+ );
110
+ }
@@ -1,15 +1,45 @@
1
- import './style.css';
1
+ // @ts-nocheck
2
2
 
3
3
  import React, { Fragment } from 'react';
4
4
 
5
- const SIZE = window.innerWidth > 1280 ? 16 : window.innerWidth > 640 ? 14 : 12;
6
- const BASE_RADIUS = SIZE / 2;
5
+ const SIZE = getSettings().size;
6
+ const BASE_RADIUS = SIZE / 3;
7
7
  const BASE_FONT_SIZE = SIZE;
8
8
 
9
- export function Component(className, styleSrc, config = {}) {
9
+ export function getSettings() {
10
+ const sizeSrc = getComputedStyle(document.documentElement).getPropertyValue('--size');
11
+
12
+ return {
13
+ size: parseInt(sizeSrc)
14
+ };
15
+ }
16
+
17
+ export function classList(classes: any[] | Record<string, any>) {
18
+ if (Array.isArray(classes)) {
19
+ return classes.filter((e) => e).join(' ');
20
+ } else {
21
+ return Object.keys(classes)
22
+ .filter((e) => classes[e])
23
+ .join(' ');
24
+ }
25
+ }
26
+
27
+ export function layoutPropsToStyles({ padding }: { padding?: number }): { [prop: string]: string } {
28
+ let newStyles: { [prop: string]: string } = {};
29
+ if (padding) {
30
+ newStyles.padding = `${getSettings().size * padding}px`;
31
+ }
32
+ return newStyles;
33
+ }
34
+
35
+ export function Component(
36
+ className: string,
37
+ styleSrc = {},
38
+ config: { element?: string; styleProps?: any } = {}
39
+ ) {
10
40
  const { element = `div`, styleProps } = config;
11
41
 
12
- return function MakeComponent({ children, ...props }) {
42
+ return function MakeComponent({ children, style = {}, ...props }) {
13
43
  const passProps = styleProps
14
44
  ? Object.keys(props)
15
45
  .filter((e) => !styleProps.includes(e))
@@ -19,11 +49,13 @@ export function Component(className, styleSrc, config = {}) {
19
49
  }, {})
20
50
  : props;
21
51
 
52
+ const calculatedStyle = typeof styleSrc === 'function' ? styleSrc(props) : styleSrc;
53
+
22
54
  return React.createElement(
23
55
  element,
24
56
  {
25
57
  className,
26
- style: typeof styleSrc === 'function' ? styleSrc(props) : styleSrc,
58
+ style: { ...style, ...calculatedStyle },
27
59
  ...passProps
28
60
  },
29
61
  children
@@ -46,6 +78,7 @@ export const HeaderH1 = Component(`jbx-h${1}`, null, { element: 'h1' });
46
78
  export const HeaderH2 = Component(`jbx-h${2}`, null, { element: 'h2' });
47
79
  export const HeaderH3 = Component(`jbx-h${3}`, null, { element: 'h3' });
48
80
  export const HeaderH4 = Component(`jbx-h${4}`, null, { element: 'h4' });
81
+ export const HR = Component(`jbx-hr`, null, { element: 'hr' });
49
82
 
50
83
  export const MainHeader = function MainHeader({ children, style }) {
51
84
  const content = String(children).split(' ');
@@ -59,7 +92,6 @@ export const MainHeader = function MainHeader({ children, style }) {
59
92
  {
60
93
  key: word,
61
94
  style: {
62
- fontWeight: 900,
63
95
  display: 'inline-block',
64
96
  width: 'auto',
65
97
  padding: '6px',
@@ -82,25 +114,13 @@ export const Space = Component(`jbx-space`, (props) => ({
82
114
  width: `${SIZE * props.w}px`
83
115
  }));
84
116
 
85
- export const Box = Component(`jbx-box`, ({ padding, hideOnSmall, flex, minWidth }) => {
86
- return {
87
- flex,
88
- minWidth,
89
- padding: padding
90
- ? [padding]
91
- .flat()
92
- .map((paddingValue) => `${paddingValue * SIZE}px`)
93
- .join(` `)
94
- : null
95
- };
96
- });
97
-
98
- export const Inline = Component(`jbx-inline`, ({ v, h, gap }) => ({
117
+ export const Inline = Component(`jbx-inline`, ({ v, h, gap, wrap = false }) => ({
99
118
  marginLeft: `${h * SIZE}px`,
100
119
  marginRight: `${h * SIZE}px`,
101
120
  marginTop: `${v * SIZE}px`,
102
121
  marginBottom: `${v * SIZE}px`,
103
- gap: `${gap * SIZE}px`
122
+ gap: `${gap * SIZE}px`,
123
+ flexWrap: wrap ? 'wrap' : 'no-wrap'
104
124
  }));
105
125
 
106
126
  export const Stack = Component(`jbx-stack`, ({ v, h, gap }) => ({
@@ -111,25 +131,6 @@ export const Stack = Component(`jbx-stack`, ({ v, h, gap }) => ({
111
131
  gap: `${gap * SIZE}px`
112
132
  }));
113
133
 
114
- // export const LinkButton = Styled.a({
115
- // capHeight: BASE_FONT_SIZE,
116
- // color: '#3498db',
117
- // cursor: 'pointer',
118
- // borderRadius: 5,
119
- // borderTop: '1px solid #3498db10',
120
- // borderBottom: '1px solid #0000',
121
- // backgroundColor: '#3498db20',
122
- // height: BASE_FONT_SIZE * 2,
123
- // display: 'flex',
124
- // alignItems: 'center',
125
- // alignContent: 'center',
126
- // justifyContent: 'center',
127
- // padding: 0,
128
- // '&:hover': {
129
- // boxShadow: `rgba(0, 0, 0, 0.1) 0 1px 1px, rgba(0, 0, 0, 0.1) 0 3px 12px`
130
- // }
131
- // });
132
-
133
134
  export const Dropzone = Component(`jbx-dropzone`);
134
135
 
135
136
  export const Ul = Component(
@@ -170,8 +171,8 @@ export const CodeTextarea = Component(`jbx-code-area`, null, { element: 'textare
170
171
 
171
172
  export const CheckboxHidden = Component(`jbx-checkbox-hidden`, ({ checked }) => {
172
173
  return {
173
- height: BASE_SIZE * 2 - 4,
174
- width: BASE_SIZE * 2 - 4,
174
+ height: SIZE * 2 - 4,
175
+ width: SIZE * 2 - 4,
175
176
  paddingTop: 2,
176
177
  paddingLeft: 2,
177
178
  backgroundColor: checked ? 'var(--accent-color)' : 'white',
@@ -208,8 +209,8 @@ export const Checkbox = function Checkbox({ label, checked, onChange }) {
208
209
  'svg',
209
210
  {
210
211
  xmlns: 'http://www.w3.org/2000/svg',
211
- width: BASE_SIZE * 2 - 8,
212
- height: BASE_SIZE * 2 - 8,
212
+ width: SIZE * 2 - 8,
213
+ height: SIZE * 2 - 8,
213
214
  fill: 'none',
214
215
  stroke: 'currentColor',
215
216
  strokeLinecap: 'round',
@@ -229,3 +230,14 @@ export const Checkbox = function Checkbox({ label, checked, onChange }) {
229
230
  ]
230
231
  );
231
232
  };
233
+
234
+ export function Bullet({ value }: { value: string }) {
235
+ return (
236
+ <div className="jbx-bullet-container">
237
+ <div className="jbx-bullet">{value}</div>
238
+ </div>
239
+ );
240
+ }
241
+
242
+ export { Box } from './components/Layout';
243
+ export { MoreExperiments } from './components/MoreExperiments';