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