tinywidgets 1.2.3 → 1.3.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinywidgets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"author": "jamesgpearce",
|
|
5
5
|
"repository": "github:tinyplex/tinywidgets",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
"lucide-react": "^0.511.0",
|
|
42
42
|
"react": "^19.1.0",
|
|
43
43
|
"react-dom": "^19.1.0",
|
|
44
|
-
"tinybase": "^6.
|
|
44
|
+
"tinybase": "^6.2.0-beta.1"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from './index.css.ts';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* The `Button` component displays
|
|
14
|
+
* The `Button` component displays a button, with a number of common variants.
|
|
15
15
|
*
|
|
16
16
|
* @param props The props for the component.
|
|
17
17
|
* @returns The Button component.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {style} from '@vanilla-extract/css';
|
|
2
|
+
import {colors} from '../../css/colors.css';
|
|
3
|
+
import {dimensions} from '../../css/dimensions.css';
|
|
4
|
+
|
|
5
|
+
export const select = style({
|
|
6
|
+
borderRadius: dimensions.radius,
|
|
7
|
+
padding: '0.5rem',
|
|
8
|
+
outlineOffset: '2px',
|
|
9
|
+
color: 'inherit',
|
|
10
|
+
transition: 'background-color 0.1s,border-color 0.1s',
|
|
11
|
+
boxShadow: colors.shadow,
|
|
12
|
+
border: colors.border,
|
|
13
|
+
backgroundColor: colors.background,
|
|
14
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {useCallback, useState} from 'react';
|
|
2
|
+
import {classNames} from '../../common/functions.tsx';
|
|
3
|
+
import {select} from './index.css.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `Select` component displays a managed select input with an existing
|
|
7
|
+
* value.
|
|
8
|
+
*
|
|
9
|
+
* @param props The props for the component.
|
|
10
|
+
* @returns The Select component.
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Select
|
|
14
|
+
* initialOption="CA"
|
|
15
|
+
* options={{ AL: 'Albania', BE: 'Belgium', CA: 'Canada' }}
|
|
16
|
+
* onChange={(option) => console.log(option)}
|
|
17
|
+
* />
|
|
18
|
+
* ```
|
|
19
|
+
* @icon Lucide.Combine
|
|
20
|
+
*/
|
|
21
|
+
export const Select = ({
|
|
22
|
+
options,
|
|
23
|
+
initialOption,
|
|
24
|
+
onChange,
|
|
25
|
+
alt,
|
|
26
|
+
className,
|
|
27
|
+
ref,
|
|
28
|
+
}: {
|
|
29
|
+
/**
|
|
30
|
+
* The options and labels to show in the select widget.
|
|
31
|
+
*/
|
|
32
|
+
readonly options: {[option: string]: string};
|
|
33
|
+
/**
|
|
34
|
+
* An optional initial option.
|
|
35
|
+
*/
|
|
36
|
+
readonly initialOption?: string;
|
|
37
|
+
/**
|
|
38
|
+
* A handler called when the option is changed.
|
|
39
|
+
*/
|
|
40
|
+
readonly onChange?: (option: string) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Alternative text shown when the user hovers over the input.
|
|
43
|
+
*/
|
|
44
|
+
readonly alt?: string;
|
|
45
|
+
/**
|
|
46
|
+
* An extra CSS class name for the component.
|
|
47
|
+
*/
|
|
48
|
+
readonly className?: string;
|
|
49
|
+
ref?: React.RefObject<HTMLSelectElement | null>;
|
|
50
|
+
}) => {
|
|
51
|
+
const [option, setOption] = useState(initialOption ?? '');
|
|
52
|
+
const handleChange = useCallback(
|
|
53
|
+
({target: {value}}: React.ChangeEvent<HTMLSelectElement>) => {
|
|
54
|
+
setOption(value);
|
|
55
|
+
onChange?.(value);
|
|
56
|
+
},
|
|
57
|
+
[onChange],
|
|
58
|
+
);
|
|
59
|
+
return (
|
|
60
|
+
<select
|
|
61
|
+
className={classNames(select, className)}
|
|
62
|
+
onChange={handleChange}
|
|
63
|
+
title={alt}
|
|
64
|
+
ref={ref}
|
|
65
|
+
>
|
|
66
|
+
{Object.entries(options).map(([eachOption, label]) => (
|
|
67
|
+
<option
|
|
68
|
+
key={eachOption}
|
|
69
|
+
value={eachOption}
|
|
70
|
+
{...(eachOption === option ? {selected: true} : {})}
|
|
71
|
+
>
|
|
72
|
+
{label}
|
|
73
|
+
</option>
|
|
74
|
+
))}
|
|
75
|
+
</select>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {style} from '@vanilla-extract/css';
|
|
2
|
+
import {colors} from '../../css/colors.css';
|
|
3
|
+
import {dimensions} from '../../css/dimensions.css';
|
|
4
|
+
|
|
5
|
+
export const wrapper = style({
|
|
6
|
+
flexShrink: 0,
|
|
7
|
+
alignSelf: 'center',
|
|
8
|
+
position: 'relative',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const wrapperWithIcon = style({});
|
|
12
|
+
|
|
13
|
+
export const input = style({
|
|
14
|
+
borderRadius: dimensions.radius,
|
|
15
|
+
padding: '0.5rem',
|
|
16
|
+
outlineOffset: '2px',
|
|
17
|
+
color: 'inherit',
|
|
18
|
+
transition: 'background-color 0.1s,border-color 0.1s',
|
|
19
|
+
boxShadow: colors.shadow + ' inset',
|
|
20
|
+
border: colors.border,
|
|
21
|
+
backgroundColor: colors.background,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const inputWithIcon = style({
|
|
25
|
+
textIndent: `calc(${dimensions.icon} * 1.3)`,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const icon = style({
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
left: `calc(${dimensions.icon} * .5)`,
|
|
31
|
+
top: `calc(${dimensions.icon} * .65)`,
|
|
32
|
+
color: colors.foregroundDim,
|
|
33
|
+
backgroundColor: colors.background,
|
|
34
|
+
borderRight: `calc(${dimensions.icon} * .25) solid ${colors.background}`,
|
|
35
|
+
boxSizing: 'content-box',
|
|
36
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {useCallback, useState, type ComponentType} from 'react';
|
|
2
|
+
import {classNames} from '../../common/functions.tsx';
|
|
3
|
+
import {iconSize} from '../../css/dimensions.css.ts';
|
|
4
|
+
import {
|
|
5
|
+
icon,
|
|
6
|
+
input,
|
|
7
|
+
inputWithIcon,
|
|
8
|
+
wrapper,
|
|
9
|
+
wrapperWithIcon,
|
|
10
|
+
} from './index.css.ts';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The `TextInput` component displays a managed text input with an existing
|
|
14
|
+
* value.
|
|
15
|
+
*
|
|
16
|
+
* @param props The props for the component.
|
|
17
|
+
* @returns The TextInput component.
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <TextInput
|
|
21
|
+
* initialText="42"
|
|
22
|
+
* onChange={(value) => console.log(value)}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
* This example shows the TextInput component.
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <TextInput icon={Lucide.Search} placeholder="Search..." />
|
|
29
|
+
* ```
|
|
30
|
+
* This example shows the TextInput component with an inset icon and
|
|
31
|
+
* placeholder.
|
|
32
|
+
* @icon Lucide.TextCursorInput
|
|
33
|
+
*/
|
|
34
|
+
export const TextInput = ({
|
|
35
|
+
initialText,
|
|
36
|
+
placeholder,
|
|
37
|
+
onChange,
|
|
38
|
+
icon: Icon,
|
|
39
|
+
alt,
|
|
40
|
+
className,
|
|
41
|
+
ref,
|
|
42
|
+
}: {
|
|
43
|
+
/**
|
|
44
|
+
* An optional initial text value.
|
|
45
|
+
*/
|
|
46
|
+
readonly initialText?: string;
|
|
47
|
+
/**
|
|
48
|
+
* An optional placeholder string.
|
|
49
|
+
*/
|
|
50
|
+
readonly placeholder?: string;
|
|
51
|
+
/**
|
|
52
|
+
* A handler called when the text is changed.
|
|
53
|
+
*/
|
|
54
|
+
readonly onChange?: (text: string) => void;
|
|
55
|
+
/**
|
|
56
|
+
* An optional component which renders an icon on the left of the input, and
|
|
57
|
+
* which must accept a className prop.
|
|
58
|
+
*/
|
|
59
|
+
readonly icon?: ComponentType<{className?: string}>;
|
|
60
|
+
/**
|
|
61
|
+
* Alternative text shown when the user hovers over the input.
|
|
62
|
+
*/
|
|
63
|
+
readonly alt?: string;
|
|
64
|
+
/**
|
|
65
|
+
* An extra CSS class name for the component.
|
|
66
|
+
*/
|
|
67
|
+
readonly className?: string;
|
|
68
|
+
ref?: React.RefObject<HTMLInputElement | null>;
|
|
69
|
+
}) => {
|
|
70
|
+
const [text, setText] = useState(initialText ?? '');
|
|
71
|
+
const handleChange = useCallback(
|
|
72
|
+
({target: {value}}: React.ChangeEvent<HTMLInputElement>) => {
|
|
73
|
+
setText(value);
|
|
74
|
+
onChange?.(value);
|
|
75
|
+
},
|
|
76
|
+
[onChange],
|
|
77
|
+
);
|
|
78
|
+
return (
|
|
79
|
+
<div className={classNames(wrapper, Icon && wrapperWithIcon)}>
|
|
80
|
+
{Icon ? <Icon className={classNames(iconSize, icon)} /> : null}
|
|
81
|
+
<input
|
|
82
|
+
value={text}
|
|
83
|
+
placeholder={placeholder}
|
|
84
|
+
className={classNames(input, Icon && inputWithIcon, className)}
|
|
85
|
+
onChange={handleChange}
|
|
86
|
+
title={alt}
|
|
87
|
+
ref={ref}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -8,8 +8,10 @@ export {Hr} from './components/Hr/index.tsx';
|
|
|
8
8
|
export {Image} from './components/Image/index.tsx';
|
|
9
9
|
export {Metric} from './components/Metric/index.tsx';
|
|
10
10
|
export {Row} from './components/Row/index.tsx';
|
|
11
|
+
export {Select} from './components/Select/index.tsx';
|
|
11
12
|
export {Summary} from './components/Summary/index.tsx';
|
|
12
13
|
export {Tag} from './components/Tag/index.tsx';
|
|
14
|
+
export {TextInput} from './components/TextInput/index.tsx';
|
|
13
15
|
|
|
14
16
|
export {classNames} from './common/functions.tsx';
|
|
15
17
|
export {useDark} from './stores/LocalStore.tsx';
|