@a-type/ui 6.0.8 → 6.0.10
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/dist/components/icon/Icon.stories.d.ts +1 -1
- package/dist/components/icon/generated/IconSpritesheet.js +1 -1
- package/dist/components/icon/generated/IconSpritesheet.js.map +1 -1
- package/dist/components/icon/generated/iconNames.d.ts +1 -1
- package/dist/components/icon/generated/iconNames.js +1 -0
- package/dist/components/icon/generated/iconNames.js.map +1 -1
- package/dist/components/liveUpdateTextField/LiveUpdateTextField.d.ts +2 -1
- package/dist/components/liveUpdateTextField/LiveUpdateTextField.js.map +1 -1
- package/dist/components/typography/typography.d.ts +4 -1
- package/dist/components/typography/typography.js +8 -1
- package/dist/components/typography/typography.js.map +1 -1
- package/dist/components/typography/typography.module.css +6 -0
- package/package.json +1 -1
- package/src/components/icon/generated/IconSpritesheet.tsx +17 -11
- package/src/components/icon/generated/iconNames.ts +1 -0
- package/src/components/liveUpdateTextField/LiveUpdateTextField.tsx +135 -133
- package/src/components/typography/typography.module.css +6 -0
- package/src/components/typography/typography.tsx +12 -0
|
@@ -1,133 +1,135 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { debounce } from '@a-type/utils';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { debounce } from '@a-type/utils';
|
|
4
|
+
import {
|
|
5
|
+
CSSProperties,
|
|
6
|
+
FocusEvent,
|
|
7
|
+
KeyboardEventHandler,
|
|
8
|
+
MouseEventHandler,
|
|
9
|
+
Ref,
|
|
10
|
+
useCallback,
|
|
11
|
+
useEffect,
|
|
12
|
+
useMemo,
|
|
13
|
+
useRef,
|
|
14
|
+
useState,
|
|
15
|
+
} from 'react';
|
|
16
|
+
import { Input, InputProps } from '../input/Input.js';
|
|
17
|
+
import { TextArea } from '../textArea/TextArea.js';
|
|
18
|
+
|
|
19
|
+
export type LiveUpdateTextFieldProps = {
|
|
20
|
+
value: string;
|
|
21
|
+
debounceMs?: number;
|
|
22
|
+
onChange: (value: string) => void;
|
|
23
|
+
textArea?: boolean;
|
|
24
|
+
className?: string;
|
|
25
|
+
style?: CSSProperties;
|
|
26
|
+
onFocus?: (ev: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
27
|
+
onBlur?: (ev: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
28
|
+
autoComplete?: InputProps['autoComplete'];
|
|
29
|
+
autoFocus?: InputProps['autoFocus'];
|
|
30
|
+
autoSelect?: InputProps['autoSelect'];
|
|
31
|
+
required?: boolean;
|
|
32
|
+
placeholder?: string;
|
|
33
|
+
type?: InputProps['type'];
|
|
34
|
+
id?: string;
|
|
35
|
+
onKeyDown?: KeyboardEventHandler;
|
|
36
|
+
onKeyUp?: KeyboardEventHandler;
|
|
37
|
+
onClick?: MouseEventHandler;
|
|
38
|
+
ref?: Ref<HTMLInputElement | HTMLTextAreaElement>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* An extension of TextField which keeps a local realtime value in state and
|
|
43
|
+
* periodically reports changes to the parent. Use this to connect
|
|
44
|
+
* to the API and update a value from the field directly.
|
|
45
|
+
*
|
|
46
|
+
* This component is optimistic and will not respond to external changes while focused.
|
|
47
|
+
*/
|
|
48
|
+
export const LiveUpdateTextField = function LiveUpdateTextField({
|
|
49
|
+
ref,
|
|
50
|
+
value,
|
|
51
|
+
onChange,
|
|
52
|
+
debounceMs = 500,
|
|
53
|
+
onFocus,
|
|
54
|
+
onBlur,
|
|
55
|
+
textArea,
|
|
56
|
+
type,
|
|
57
|
+
...rest
|
|
58
|
+
}: LiveUpdateTextFieldProps) {
|
|
59
|
+
const [displayValue, setDisplayValue] = useState(value || '');
|
|
60
|
+
const ignoreUpdates = useRef(false);
|
|
61
|
+
const didChange = useRef(false);
|
|
62
|
+
|
|
63
|
+
const handleFocus = useCallback(
|
|
64
|
+
(ev: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
65
|
+
onFocus?.(ev);
|
|
66
|
+
ignoreUpdates.current = true;
|
|
67
|
+
},
|
|
68
|
+
[onFocus],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const handleBlur = useCallback(
|
|
72
|
+
(ev: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
73
|
+
onBlur?.(ev);
|
|
74
|
+
ignoreUpdates.current = false;
|
|
75
|
+
// immediately send update if the user typed anything.
|
|
76
|
+
// otherwise pull the latest remote value
|
|
77
|
+
if (didChange.current) {
|
|
78
|
+
onChange?.(displayValue);
|
|
79
|
+
} else {
|
|
80
|
+
setDisplayValue(value || '');
|
|
81
|
+
}
|
|
82
|
+
didChange.current = false;
|
|
83
|
+
},
|
|
84
|
+
[onBlur, displayValue, onChange, value],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (ignoreUpdates.current) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
setDisplayValue(value || '');
|
|
92
|
+
}, [value]);
|
|
93
|
+
|
|
94
|
+
// every once in a while, send an update to parent
|
|
95
|
+
const debouncedOnChange = useMemo(
|
|
96
|
+
() => debounce(onChange || (() => {}), debounceMs),
|
|
97
|
+
[onChange, debounceMs],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// update local state instantly and parent eventually
|
|
101
|
+
const handleValueChange = useCallback(
|
|
102
|
+
(value: string) => {
|
|
103
|
+
setDisplayValue(value);
|
|
104
|
+
debouncedOnChange(value);
|
|
105
|
+
didChange.current = true;
|
|
106
|
+
},
|
|
107
|
+
[debouncedOnChange],
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
if (textArea) {
|
|
111
|
+
return (
|
|
112
|
+
<TextArea
|
|
113
|
+
ref={ref as any}
|
|
114
|
+
onFocus={handleFocus}
|
|
115
|
+
onBlur={handleBlur}
|
|
116
|
+
value={displayValue}
|
|
117
|
+
onValueChange={handleValueChange}
|
|
118
|
+
autoSize
|
|
119
|
+
{...rest}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
} else {
|
|
123
|
+
return (
|
|
124
|
+
<Input
|
|
125
|
+
ref={ref as any}
|
|
126
|
+
onFocus={handleFocus}
|
|
127
|
+
onBlur={handleBlur}
|
|
128
|
+
value={displayValue}
|
|
129
|
+
onValueChange={handleValueChange}
|
|
130
|
+
type={type}
|
|
131
|
+
{...rest}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
@@ -9,6 +9,8 @@ export interface TypographyProps extends useRender.ComponentProps<'span'> {
|
|
|
9
9
|
italic?: boolean;
|
|
10
10
|
underline?: boolean;
|
|
11
11
|
strikethrough?: boolean;
|
|
12
|
+
bold?: boolean;
|
|
13
|
+
thin?: boolean;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export function Text({
|
|
@@ -18,6 +20,8 @@ export function Text({
|
|
|
18
20
|
strikethrough,
|
|
19
21
|
render,
|
|
20
22
|
className,
|
|
23
|
+
bold,
|
|
24
|
+
thin,
|
|
21
25
|
...rest
|
|
22
26
|
}: TypographyProps) {
|
|
23
27
|
return useRender({
|
|
@@ -32,6 +36,8 @@ export function Text({
|
|
|
32
36
|
italic: italic ? true : undefined,
|
|
33
37
|
underline: underline ? true : undefined,
|
|
34
38
|
strikethrough: strikethrough ? true : undefined,
|
|
39
|
+
bold: bold ? true : undefined,
|
|
40
|
+
thin: thin ? true : undefined,
|
|
35
41
|
},
|
|
36
42
|
});
|
|
37
43
|
}
|
|
@@ -75,3 +81,9 @@ export const H5 = withProps(Heading, {
|
|
|
75
81
|
render: <h5 />,
|
|
76
82
|
emphasis: 'ambient',
|
|
77
83
|
});
|
|
84
|
+
|
|
85
|
+
export const TextLink = withProps(Text, {
|
|
86
|
+
render: <a />,
|
|
87
|
+
bold: true,
|
|
88
|
+
underline: true,
|
|
89
|
+
});
|