tinywidgets 1.5.0 → 1.6.1

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.
Files changed (33) hide show
  1. package/package.json +14 -14
  2. package/src/components/App/index.css.ts +35 -26
  3. package/src/components/App/index.tsx +31 -6
  4. package/src/components/Axis/index.css.ts +1 -1
  5. package/src/components/Button/index.css.ts +37 -23
  6. package/src/components/Button/index.tsx +14 -0
  7. package/src/components/Card/index.css.ts +69 -3
  8. package/src/components/Card/index.tsx +86 -5
  9. package/src/components/Checkbox/index.css.ts +27 -8
  10. package/src/components/Checkbox/index.tsx +17 -2
  11. package/src/components/Code/index.css.ts +2 -2
  12. package/src/components/Collapsible/index.css.ts +6 -6
  13. package/src/components/Detail/index.css.ts +2 -2
  14. package/src/components/Flyout/index.css.ts +5 -5
  15. package/src/components/Hr/index.css.ts +1 -1
  16. package/src/components/Image/index.css.ts +12 -12
  17. package/src/components/Loading/index.css.ts +28 -28
  18. package/src/components/Row/index.css.ts +8 -8
  19. package/src/components/Select/index.css.ts +20 -9
  20. package/src/components/Select/index.tsx +22 -3
  21. package/src/components/Summary/index.css.ts +1 -1
  22. package/src/components/Table/index.css.ts +8 -8
  23. package/src/components/Tag/index.css.ts +8 -8
  24. package/src/components/TextInput/index.css.ts +48 -17
  25. package/src/components/TextInput/index.tsx +39 -5
  26. package/src/css/classes.css.ts +42 -0
  27. package/src/css/code.css.ts +18 -18
  28. package/src/css/colors.css.ts +17 -17
  29. package/src/css/dimensions.css.ts +2 -2
  30. package/src/css/global.css.ts +2 -2
  31. package/src/index.css.ts +1 -0
  32. package/src/index.ts +5 -1
  33. package/src/stores/RouteStore.tsx +52 -14
@@ -2,7 +2,7 @@ import {LucideCheck} from 'lucide-react';
2
2
  import {useCallback, useState} from 'react';
3
3
  import {classNames} from '../../common/functions.tsx';
4
4
  import {Button} from '../Button/index.tsx';
5
- import {checkbox} from './index.css.ts';
5
+ import {checkbox, checkboxVariants} from './index.css.ts';
6
6
 
7
7
  /**
8
8
  * The `Checkbox` component displays a managed checkbox with an optional default
@@ -23,6 +23,11 @@ import {checkbox} from './index.css.ts';
23
23
  * />
24
24
  * ```
25
25
  * This example shows the Checkbox component with a default checked state.
26
+ * @example
27
+ * ```tsx
28
+ * <Checkbox variant="small" />
29
+ * ```
30
+ * This example shows the `small` variant of the Checkbox component.
26
31
  * @icon Lucide.LucideCheckSquare
27
32
  */
28
33
  export const Checkbox = ({
@@ -30,6 +35,7 @@ export const Checkbox = ({
30
35
  onChange,
31
36
  alt,
32
37
  className,
38
+ variant = 'default',
33
39
  ref,
34
40
  }: {
35
41
  /**
@@ -48,6 +54,15 @@ export const Checkbox = ({
48
54
  * An extra CSS class name for the component.
49
55
  */
50
56
  readonly className?: string;
57
+ /**
58
+ * A variant of the checkbox, one of:
59
+ * - `default`
60
+ * - `small`
61
+ */
62
+ readonly variant?: keyof typeof checkboxVariants;
63
+ /**
64
+ * A ref to the underlying button element.
65
+ */
51
66
  ref?: React.RefObject<HTMLButtonElement | null>;
52
67
  }) => {
53
68
  const [checked, setChecked] = useState(initialChecked ?? false);
@@ -57,7 +72,7 @@ export const Checkbox = ({
57
72
  }, [checked, onChange]);
58
73
  return (
59
74
  <Button
60
- className={classNames(checkbox, className)}
75
+ className={classNames(checkbox, checkboxVariants[variant], className)}
61
76
  onClick={handleClick}
62
77
  alt={alt}
63
78
  ref={ref}
@@ -4,12 +4,12 @@ import {colors} from '../../css/colors.css';
4
4
  import {dimensions} from '../../css/dimensions.css';
5
5
 
6
6
  export const pre = style({
7
- padding: dimensions.padding,
8
- borderRadius: dimensions.radius,
9
7
  background: colors.background2,
10
8
  border: colors.border,
9
+ borderRadius: dimensions.radius,
11
10
  lineHeight: '1.25rem',
12
11
  overflowX: 'auto',
12
+ padding: dimensions.padding,
13
13
  });
14
14
 
15
15
  globalStyle('.token.comment, .token.prolog, .token.cdata', {
@@ -3,21 +3,21 @@ import {colors} from '../../css/colors.css';
3
3
  import {dimensions} from '../../css/dimensions.css';
4
4
 
5
5
  export const collapsible = style({
6
- width: '100%',
7
6
  alignSelf: 'start',
7
+ border: colors.border,
8
8
  borderRadius: dimensions.radius,
9
9
  boxShadow: colors.shadow,
10
- border: colors.border,
11
10
  display: 'grid',
12
11
  gridTemplateRows: 'max-content minmax(0, 0fr)',
13
- transition: '.2s grid-template-rows ease-in-out',
14
- overflow: 'hidden',
15
12
  marginBottom: dimensions.padding,
13
+ overflow: 'hidden',
16
14
  selectors: {
17
15
  '&:last-child': {
18
16
  marginBottom: 0,
19
17
  },
20
18
  },
19
+ transition: '.2s grid-template-rows ease-in-out',
20
+ width: '100%',
21
21
  });
22
22
 
23
23
  export const collapsibleOpen = style({
@@ -25,8 +25,8 @@ export const collapsibleOpen = style({
25
25
  });
26
26
 
27
27
  export const button = style({
28
- margin: '-1px',
29
28
  boxShadow: 'none',
29
+ margin: '-1px',
30
30
  });
31
31
 
32
32
  export const buttonOpen = style({
@@ -34,4 +34,4 @@ export const buttonOpen = style({
34
34
  borderBottomRightRadius: 0,
35
35
  });
36
36
 
37
- export const content = style({padding: dimensions.padding, overflow: 'hidden'});
37
+ export const content = style({overflow: 'hidden', padding: dimensions.padding});
@@ -2,9 +2,9 @@ import {style} from '@vanilla-extract/css';
2
2
  import {colors} from '../../css/colors.css';
3
3
 
4
4
  export const detailTable = style({
5
- width: '100%',
6
5
  borderCollapse: 'collapse',
7
6
  margin: '-.5rem 0',
7
+ width: '100%',
8
8
  });
9
9
 
10
10
  export const detailRow = style({
@@ -14,6 +14,6 @@ export const detailRow = style({
14
14
 
15
15
  export const detailCell = style({
16
16
  padding: '0.5rem 1rem',
17
- verticalAlign: 'top',
18
17
  selectors: {'&:is(th)': {textAlign: 'right', width: '30%'}},
18
+ verticalAlign: 'top',
19
19
  });
@@ -7,19 +7,19 @@ export const wrapper = style({
7
7
  });
8
8
 
9
9
  export const flyout = style({
10
- padding: dimensions.padding,
10
+ backgroundColor: colors.background,
11
+ border: colors.border,
11
12
  borderRadius: dimensions.radius,
12
13
  boxShadow: colors.shadow,
13
- border: colors.border,
14
14
  height: 'fit-content',
15
+ left: 0,
15
16
  overflow: 'auto',
16
- backgroundColor: colors.background,
17
+ padding: dimensions.padding,
17
18
  position: 'absolute',
18
19
  top: 'calc(2rem + 2px)',
19
- left: 0,
20
20
  });
21
21
 
22
22
  export const anchoredFlyout = style({
23
- top: 'anchor(bottom)',
24
23
  left: 'anchor(left)',
24
+ top: 'anchor(bottom)',
25
25
  });
@@ -5,7 +5,7 @@ import {dimensions} from '../../css/dimensions.css';
5
5
  export const hr = style({
6
6
  border: 'none',
7
7
  borderBottom: colors.border,
8
- margin: `${dimensions.padding} 0`,
9
8
  height: '1px',
9
+ margin: `${dimensions.padding} 0`,
10
10
  width: '100%',
11
11
  });
@@ -5,8 +5,8 @@ import {dimensions} from '../../css/dimensions.css';
5
5
  export const image = style({
6
6
  display: 'inline-block',
7
7
  flexShrink: 0,
8
- width: '100%',
9
8
  maxHeight: 'inherit',
9
+ width: '100%',
10
10
  });
11
11
 
12
12
  export const clickable = style({
@@ -19,24 +19,24 @@ export const clickable = style({
19
19
  });
20
20
 
21
21
  export const imageVariants = styleVariants({
22
- default: {
23
- borderRadius: dimensions.radius,
24
- boxShadow: colors.shadow,
25
- },
26
- logo: {
27
- width: dimensions.logo,
28
- height: dimensions.logo,
29
- },
30
22
  avatar: {
31
- borderRadius: '50%',
32
23
  border: colors.border,
33
- width: dimensions.avatar,
24
+ borderRadius: '50%',
25
+ boxShadow: colors.shadow,
34
26
  height: dimensions.avatar,
27
+ width: dimensions.avatar,
28
+ },
29
+ default: {
30
+ borderRadius: dimensions.radius,
35
31
  boxShadow: colors.shadow,
36
32
  },
37
33
  icon: {
38
34
  border: colors.border,
39
- width: dimensions.icon,
40
35
  height: dimensions.icon,
36
+ width: dimensions.icon,
37
+ },
38
+ logo: {
39
+ height: dimensions.logo,
40
+ width: dimensions.logo,
41
41
  },
42
42
  });
@@ -13,31 +13,31 @@ const shimmer = keyframes({
13
13
  });
14
14
 
15
15
  export const loading = style({
16
+ alignContent: 'start',
16
17
  display: 'grid',
17
- gridTemplateRows: 'auto minmax(0, 1fr)',
18
18
  gap: `calc(${dimensions.padding} / 1.5)`,
19
- alignContent: 'start',
19
+ gridTemplateRows: 'auto minmax(0, 1fr)',
20
20
  });
21
21
 
22
22
  export const header = style({
23
- display: 'flex',
24
23
  alignItems: 'center',
25
- gap: `calc(${dimensions.padding} / 2)`,
26
24
  color: colors.foregroundDim,
25
+ display: 'flex',
26
+ gap: `calc(${dimensions.padding} / 2)`,
27
27
  });
28
28
 
29
29
  export const spinner = style({
30
- width: dimensions.icon,
31
- height: dimensions.icon,
32
- borderRadius: '999px',
33
- border: `2px solid ${colors.backgroundHover}`,
34
- borderTopColor: colors.accent,
35
- animation: `${spin} .9s linear infinite`,
36
30
  '@media': {
37
31
  '(prefers-reduced-motion: reduce)': {
38
32
  animation: 'none',
39
33
  },
40
34
  },
35
+ animation: `${spin} .9s linear infinite`,
36
+ border: `2px solid ${colors.backgroundHover}`,
37
+ borderRadius: '999px',
38
+ borderTopColor: colors.accent,
39
+ height: dimensions.icon,
40
+ width: dimensions.icon,
41
41
  });
42
42
 
43
43
  export const label = style({
@@ -45,40 +45,40 @@ export const label = style({
45
45
  });
46
46
 
47
47
  export const rows = style({
48
- position: 'relative',
49
48
  display: 'grid',
50
49
  gap: `calc(${dimensions.padding} / 2)`,
51
50
  minHeight: 0,
52
51
  overflow: 'hidden',
52
+ position: 'relative',
53
53
  });
54
54
 
55
55
  export const row = style({
56
- position: 'relative',
57
- overflow: 'hidden',
58
- height: '.875rem',
59
- borderRadius: dimensions.radius,
56
+ '@media': {
57
+ '(prefers-reduced-motion: reduce)': {
58
+ selectors: {
59
+ '&::after': {
60
+ animation: 'none',
61
+ },
62
+ },
63
+ },
64
+ },
60
65
  background: colors.background2,
66
+ borderRadius: dimensions.radius,
67
+ height: '.875rem',
68
+ overflow: 'hidden',
69
+ position: 'relative',
61
70
  selectors: {
62
71
  '&::after': {
63
- content: '""',
64
- position: 'absolute',
65
- inset: 0,
72
+ animation: `${shimmer} 1.6s ease-in-out infinite`,
66
73
  background: `linear-gradient(
67
74
  90deg,
68
75
  transparent,
69
76
  ${colors.backgroundHover},
70
77
  transparent
71
78
  )`,
72
- animation: `${shimmer} 1.6s ease-in-out infinite`,
73
- },
74
- },
75
- '@media': {
76
- '(prefers-reduced-motion: reduce)': {
77
- selectors: {
78
- '&::after': {
79
- animation: 'none',
80
- },
81
- },
79
+ content: '""',
80
+ inset: 0,
81
+ position: 'absolute',
82
82
  },
83
83
  },
84
84
  });
@@ -4,27 +4,27 @@ import {dimensions} from '../../css/dimensions.css.ts';
4
4
 
5
5
  export const row = style({
6
6
  display: 'grid',
7
- width: '100%',
8
7
  gap: dimensions.padding,
8
+ width: '100%',
9
9
  ...notLarge({gridTemplateColumns: '1fr'}),
10
10
  });
11
11
 
12
12
  export const rowVariants = styleVariants({
13
13
  '1|1': {gridTemplateColumns: `calc((100% - ${dimensions.padding})/2) 1fr`},
14
- '1|2': {
15
- gridTemplateColumns: `calc((100% - ${dimensions.padding}*2)/3) 1fr`,
16
- },
17
- '2|1': {
18
- gridTemplateColumns: `1fr calc((100% - ${dimensions.padding}*2)/3)`,
19
- },
20
14
  '1|1|1': {
21
15
  gridTemplateColumns: `1fr 1fr 1fr`,
22
16
  },
17
+ '1|1|1|1': {gridTemplateColumns: '1fr 1fr 1fr 1fr'},
18
+ '1|2': {
19
+ gridTemplateColumns: `calc((100% - ${dimensions.padding}*2)/3) 1fr`,
20
+ },
23
21
  '1|3': {
24
22
  gridTemplateColumns: `calc((100% - ${dimensions.padding}*3)/4) 1fr`,
25
23
  },
24
+ '2|1': {
25
+ gridTemplateColumns: `1fr calc((100% - ${dimensions.padding}*2)/3)`,
26
+ },
26
27
  '3|1': {
27
28
  gridTemplateColumns: `1fr calc((100% - ${dimensions.padding}*3)/4)`,
28
29
  },
29
- '1|1|1|1': {gridTemplateColumns: '1fr 1fr 1fr 1fr'},
30
30
  });
@@ -1,17 +1,28 @@
1
- import {style} from '@vanilla-extract/css';
1
+ import {style, styleVariants} from '@vanilla-extract/css';
2
2
  import {colors} from '../../css/colors.css';
3
3
  import {dimensions} from '../../css/dimensions.css';
4
4
 
5
5
  export const select = style({
6
+ backgroundColor: colors.background,
7
+ border: colors.border,
6
8
  borderRadius: dimensions.radius,
7
- padding: '0.5rem',
8
- outlineOffset: '2px',
9
+ boxSizing: 'border-box',
10
+ boxShadow: colors.shadow,
9
11
  color: 'inherit',
10
- fontWeight: 'inherit',
11
12
  fontFamily: 'inherit',
12
- boxShadow: colors.shadow,
13
- border: colors.border,
14
- backgroundColor: colors.background,
15
- boxSizing: 'content-box',
16
- height: '1.5rem',
13
+ fontWeight: 'inherit',
14
+ outlineOffset: '2px',
15
+ });
16
+
17
+ export const selectVariants = styleVariants({
18
+ default: {
19
+ height: '2.5rem',
20
+ padding: '0.5rem',
21
+ },
22
+ small: {
23
+ fontSize: '0.75rem',
24
+ height: '1.5rem',
25
+ lineHeight: '0.875rem',
26
+ padding: '0.1875rem 0.375rem',
27
+ },
17
28
  });
@@ -1,6 +1,6 @@
1
1
  import {useCallback, useEffect, useState} from 'react';
2
2
  import {classNames} from '../../common/functions.tsx';
3
- import {select} from './index.css.ts';
3
+ import {select, selectVariants} from './index.css.ts';
4
4
 
5
5
  /**
6
6
  * The `Select` component displays a managed select input with an existing
@@ -16,6 +16,15 @@ import {select} from './index.css.ts';
16
16
  * onChange={(option) => console.log(option)}
17
17
  * />
18
18
  * ```
19
+ * @example
20
+ * ```tsx
21
+ * <Select
22
+ * initialOption="CA"
23
+ * options={{AL: 'Albania', BE: 'Belgium', CA: 'Canada'}}
24
+ * variant="small"
25
+ * />
26
+ * ```
27
+ * This example shows the `small` variant of the Select component.
19
28
  * @icon Lucide.Combine
20
29
  */
21
30
  export const Select = ({
@@ -24,6 +33,7 @@ export const Select = ({
24
33
  onChange,
25
34
  alt,
26
35
  className,
36
+ variant = 'default',
27
37
  ref,
28
38
  }: {
29
39
  /**
@@ -46,6 +56,15 @@ export const Select = ({
46
56
  * An extra CSS class name for the component.
47
57
  */
48
58
  readonly className?: string;
59
+ /**
60
+ * A variant of the select, one of:
61
+ * - `default`
62
+ * - `small`
63
+ */
64
+ readonly variant?: keyof typeof selectVariants;
65
+ /**
66
+ * A ref to the underlying select element.
67
+ */
49
68
  ref?: React.RefObject<HTMLSelectElement | null>;
50
69
  }) => {
51
70
  const [option, setOption] = useState(initialOption ?? '');
@@ -63,12 +82,12 @@ export const Select = ({
63
82
  [change],
64
83
  );
65
84
 
66
- useEffect(() => change(initialOption ?? ''), [change, initialOption]);
85
+ useEffect(() => setOption(initialOption ?? ''), [initialOption]);
67
86
 
68
87
  return (
69
88
  <select
70
89
  value={option}
71
- className={classNames(select, className)}
90
+ className={classNames(select, selectVariants[variant], className)}
72
91
  onChange={handleChange}
73
92
  title={alt}
74
93
  ref={ref}
@@ -4,9 +4,9 @@ import {dimensions} from '../../css/dimensions.css.ts';
4
4
 
5
5
  export const summary = style({
6
6
  display: 'grid',
7
- width: '100%',
8
7
  gap: dimensions.padding,
9
8
  gridTemplateColumns: `6rem 1fr`,
9
+ width: '100%',
10
10
  ...notLarge({gridTemplateColumns: '1fr'}),
11
11
  });
12
12
 
@@ -2,25 +2,25 @@ import {globalStyle, style} from '@vanilla-extract/css';
2
2
  import {colors} from '../../css/colors.css';
3
3
 
4
4
  export const table = style({
5
- width: '100%',
5
+ borderCollapse: 'collapse',
6
6
  height: '100%',
7
7
  padding: 0,
8
- borderCollapse: 'collapse',
9
8
  tableLayout: 'fixed',
9
+ width: '100%',
10
10
  });
11
11
 
12
12
  globalStyle(`${table} th, ${table} td`, {
13
+ borderColor: colors.borderColor,
14
+ borderStyle: 'solid',
15
+ borderWidth: '1px 0',
13
16
  overflow: 'hidden',
14
17
  padding: '0.25rem 1rem',
15
- whiteSpace: 'nowrap',
16
- textOverflow: 'ellipsis',
17
- borderWidth: '1px 0',
18
- borderStyle: 'solid',
19
- borderColor: colors.borderColor,
20
18
  textAlign: 'left',
19
+ textOverflow: 'ellipsis',
20
+ whiteSpace: 'nowrap',
21
21
  });
22
22
 
23
23
  globalStyle(`${table} th`, {
24
- fontWeight: 'inherit',
25
24
  backgroundColor: colors.backgroundHover,
25
+ fontWeight: 'inherit',
26
26
  });
@@ -2,26 +2,26 @@ import {style, styleVariants} from '@vanilla-extract/css';
2
2
  import {colors} from '../../css/colors.css';
3
3
 
4
4
  export const tag = style({
5
+ borderRadius: '0.25rem',
6
+ flexShrink: 0,
5
7
  fontSize: '0.625rem',
8
+ gap: '0.25rem',
6
9
  lineHeight: '0.625rem',
7
10
  padding: '0.1rem 0.25rem',
8
- borderRadius: '0.25rem',
9
- gap: '0.25rem',
10
- flexShrink: 0,
11
11
  });
12
12
 
13
13
  export const tagVariants = styleVariants({
14
- default: {
15
- backgroundColor: colors.backgroundHover,
16
- color: colors.foregroundDim,
17
- },
18
14
  accent: {
19
15
  backgroundColor: colors.accent,
20
16
  color: colors.accentContrast,
21
17
  },
18
+ default: {
19
+ backgroundColor: colors.backgroundHover,
20
+ color: colors.foregroundDim,
21
+ },
22
22
  });
23
23
 
24
24
  export const tagIcon = style({
25
- width: '0.7rem',
26
25
  height: '0.7rem',
26
+ width: '0.7rem',
27
27
  });
@@ -1,37 +1,68 @@
1
- import {style} from '@vanilla-extract/css';
1
+ import {style, styleVariants} from '@vanilla-extract/css';
2
2
  import {colors} from '../../css/colors.css';
3
3
  import {dimensions} from '../../css/dimensions.css';
4
4
 
5
5
  export const wrapper = style({
6
- flexShrink: 0,
7
- alignSelf: 'center',
6
+ alignSelf: 'stretch',
7
+ display: 'block',
8
+ flex: '1 1 auto',
9
+ minWidth: 0,
8
10
  position: 'relative',
9
- display: 'inline-block',
10
11
  });
11
12
 
12
13
  export const input = style({
14
+ backgroundColor: colors.background,
15
+ border: colors.border,
13
16
  borderRadius: dimensions.radius,
14
- padding: '0.5rem',
15
- outlineOffset: '2px',
17
+ boxSizing: 'border-box',
18
+ boxShadow: colors.shadow + ' inset',
16
19
  color: 'inherit',
17
- fontWeight: 'inherit',
18
20
  fontFamily: 'inherit',
19
- boxShadow: colors.shadow + ' inset',
20
- border: colors.border,
21
- backgroundColor: colors.background,
22
- lineHeight: '1.5rem',
21
+ fontWeight: 'inherit',
22
+ outlineOffset: '2px',
23
+ width: '100%',
24
+ });
25
+
26
+ export const inputVariants = styleVariants({
27
+ default: {
28
+ height: '2.5rem',
29
+ lineHeight: '1.5rem',
30
+ padding: '0.5rem',
31
+ },
32
+ small: {
33
+ fontSize: '0.75rem',
34
+ height: '1.5rem',
35
+ lineHeight: '0.875rem',
36
+ padding: '0.1875rem 0.375rem',
37
+ },
23
38
  });
24
39
 
25
- export const inputWithIcon = style({
26
- textIndent: `calc(${dimensions.icon} * 1.3)`,
40
+ export const inputWithIconVariants = styleVariants({
41
+ default: {
42
+ textIndent: `calc(${dimensions.icon} * 1.3)`,
43
+ },
44
+ small: {
45
+ textIndent: '1rem',
46
+ },
27
47
  });
28
48
 
29
49
  export const icon = style({
30
- position: 'absolute',
31
- left: `calc(${dimensions.icon} * .5)`,
32
- top: `calc(${dimensions.icon} * .8)`,
33
- color: colors.foregroundDim,
34
50
  backgroundColor: colors.background,
35
51
  borderRight: `calc(${dimensions.icon} * .25) solid ${colors.background}`,
36
52
  boxSizing: 'content-box',
53
+ color: colors.foregroundDim,
54
+ left: `calc(${dimensions.icon} * .5)`,
55
+ position: 'absolute',
56
+ top: `calc(${dimensions.icon} * .8)`,
57
+ });
58
+
59
+ export const iconVariants = styleVariants({
60
+ default: {},
61
+ small: {
62
+ borderRight: `calc(${dimensions.icon} * .2) solid ${colors.background}`,
63
+ height: '0.75rem',
64
+ left: '0.375rem',
65
+ top: '0.4375rem',
66
+ width: '0.75rem',
67
+ },
37
68
  });