paris 0.11.0 → 0.12.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/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/stories/combobox/Combobox.tsx +4 -2
- package/src/stories/field/Field.tsx +87 -63
- package/src/stories/input/Input.module.scss +11 -3
- package/src/stories/input/Input.tsx +2 -0
- package/src/stories/select/Select.tsx +2 -0
- package/src/stories/textarea/TextArea.tsx +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# paris
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fc32202: Field: description position prop
|
|
8
|
+
|
|
9
|
+
## 0.11.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- ef55a9d: Combobox: fix displayValue rendering when allowCustomValue is false
|
|
14
|
+
|
|
3
15
|
## 0.11.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "paris",
|
|
3
3
|
"author": "Sanil Chawla <sanil@slingshot.fm> (https://sanil.co)",
|
|
4
4
|
"description": "Paris is Slingshot's React design system. It's a collection of reusable components, design tokens, and guidelines that help us build consistent, accessible, and performant user interfaces.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.12.0",
|
|
6
6
|
"homepage": "https://paris.slingshot.fm",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
@@ -112,7 +112,7 @@ export type ComboboxProps<T extends Record<string, any>> = {
|
|
|
112
112
|
/**
|
|
113
113
|
* A Combobox component is used to render a searchable select.
|
|
114
114
|
*
|
|
115
|
-
* When the selected option node is a
|
|
115
|
+
* When the selected option node is a string, the combobox will act like an input even when an option is selected, allowing users to edit the selected option directly in order to pick a new one. To circumvent this and make selected options non-editable, pass nodes that are `Text` components instead.
|
|
116
116
|
*
|
|
117
117
|
* When `allowCustomValue` is `true`, a custom value option will be added to the dropdown. This option's text can be customized by passing a value for `customValueString`, where `%v` within the string is the user's input. You can provide an entirely custom node through `renderCustomValueOption`. By default, `onChange` will be called for every input change when custom values are allowed.
|
|
118
118
|
*
|
|
@@ -134,6 +134,7 @@ export function Combobox<T extends Record<string, any> = Record<string, any>>({
|
|
|
134
134
|
hideLabel,
|
|
135
135
|
description,
|
|
136
136
|
hideDescription,
|
|
137
|
+
descriptionPosition,
|
|
137
138
|
placeholder,
|
|
138
139
|
startEnhancer,
|
|
139
140
|
endEnhancer,
|
|
@@ -166,6 +167,7 @@ export function Combobox<T extends Record<string, any> = Record<string, any>>({
|
|
|
166
167
|
hideLabel={hideLabel}
|
|
167
168
|
description={description}
|
|
168
169
|
hideDescription={hideDescription}
|
|
170
|
+
descriptionPosition={descriptionPosition}
|
|
169
171
|
disabled={disabled}
|
|
170
172
|
overrides={{
|
|
171
173
|
container: overrides?.container,
|
|
@@ -217,7 +219,7 @@ export function Combobox<T extends Record<string, any> = Record<string, any>>({
|
|
|
217
219
|
{...overrides?.input}
|
|
218
220
|
placeholder={placeholder}
|
|
219
221
|
// value={query}
|
|
220
|
-
displayValue={(
|
|
222
|
+
displayValue={() => value?.node as string}
|
|
221
223
|
onChange={(e) => {
|
|
222
224
|
setQuery(e.target.value);
|
|
223
225
|
if (onInputChange) onInputChange(e.target.value);
|
|
@@ -31,10 +31,16 @@ export type FieldProps = {
|
|
|
31
31
|
* Disables the field, disallowing user interaction.
|
|
32
32
|
*/
|
|
33
33
|
disabled?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Position of the description relative to the children/input.
|
|
36
|
+
* @default 'bottom'
|
|
37
|
+
*/
|
|
38
|
+
descriptionPosition?: 'top' | 'bottom';
|
|
34
39
|
overrides?: {
|
|
35
40
|
container?: ComponentPropsWithoutRef<'div'>;
|
|
36
41
|
label?: TextProps<'label'>;
|
|
37
42
|
description?: TextProps<'p'>;
|
|
43
|
+
labelContainer?: ComponentPropsWithoutRef<'div'>;
|
|
38
44
|
}
|
|
39
45
|
};
|
|
40
46
|
|
|
@@ -53,74 +59,92 @@ export type FieldProps = {
|
|
|
53
59
|
export const Field: FC<PropsWithChildren<FieldProps>> = ({
|
|
54
60
|
htmlFor,
|
|
55
61
|
disabled,
|
|
62
|
+
descriptionPosition = 'bottom',
|
|
56
63
|
children,
|
|
57
64
|
// className,
|
|
58
65
|
...props
|
|
59
|
-
}) =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
66
|
+
}) => {
|
|
67
|
+
const label = typeof props.label === 'string'
|
|
68
|
+
? (
|
|
69
|
+
<Text
|
|
70
|
+
{...props.overrides?.label}
|
|
71
|
+
as="label"
|
|
72
|
+
kind="paragraphSmall"
|
|
73
|
+
htmlFor={htmlFor}
|
|
74
|
+
className={clsx(
|
|
75
|
+
styles.label,
|
|
76
|
+
{ [styles.hidden]: props.hideLabel },
|
|
77
|
+
)}
|
|
78
|
+
>
|
|
79
|
+
{props.label}
|
|
80
|
+
</Text>
|
|
81
|
+
)
|
|
82
|
+
: (
|
|
83
|
+
<label htmlFor={htmlFor} className={clsx({ [styles.hidden]: props.hideLabel })}>
|
|
84
|
+
{props.label}
|
|
85
|
+
</label>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const description = typeof props.description === 'string'
|
|
89
|
+
? (
|
|
90
|
+
<Text
|
|
91
|
+
id={`${htmlFor}-description`}
|
|
92
|
+
{...props.overrides?.description}
|
|
93
|
+
as="p"
|
|
94
|
+
kind="paragraphXSmall"
|
|
95
|
+
className={clsx(
|
|
96
|
+
styles.description,
|
|
97
|
+
{ [styles.hidden]: !props.description || props.hideDescription },
|
|
98
|
+
props.overrides?.description?.className,
|
|
99
|
+
)}
|
|
100
|
+
>
|
|
101
|
+
{props.description}
|
|
102
|
+
</Text>
|
|
103
|
+
)
|
|
104
|
+
: (
|
|
105
|
+
<div
|
|
106
|
+
id={`${htmlFor}-description`}
|
|
107
|
+
className={clsx({ [styles.hidden]: !props.description || props.hideDescription })}
|
|
108
|
+
>
|
|
109
|
+
{props.description}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
// Disable a11y rules because the container doesn't need to be focusable for screen readers; the input itself should receive focus instead.
|
|
115
|
+
// The container is only made clickable for usability purposes.
|
|
116
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
117
|
+
<div
|
|
118
|
+
{...props.overrides?.container}
|
|
119
|
+
className={clsx(
|
|
120
|
+
props.overrides?.container?.className,
|
|
121
|
+
styles.container,
|
|
122
|
+
// className,
|
|
99
123
|
)}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
onClick={(e) => {
|
|
125
|
+
if (typeof window !== 'undefined' && htmlFor) {
|
|
126
|
+
const input = document.getElementById(htmlFor);
|
|
127
|
+
if (input && !disabled) {
|
|
128
|
+
if (input.tagName === 'BUTTON') input.click();
|
|
129
|
+
else input.focus();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
{descriptionPosition === 'top' ? (
|
|
135
|
+
<div
|
|
136
|
+
{...props.overrides?.labelContainer}
|
|
108
137
|
className={clsx(
|
|
109
|
-
styles.
|
|
110
|
-
|
|
111
|
-
props.overrides?.description?.className,
|
|
138
|
+
styles.labelContainer,
|
|
139
|
+
props.overrides?.labelContainer?.className,
|
|
112
140
|
)}
|
|
113
141
|
>
|
|
114
|
-
{
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
: (
|
|
118
|
-
<div
|
|
119
|
-
id={`${htmlFor}-description`}
|
|
120
|
-
className={clsx({ [styles.hidden]: !props.description || props.hideDescription })}
|
|
121
|
-
>
|
|
122
|
-
{props.description}
|
|
142
|
+
{label}
|
|
143
|
+
{description}
|
|
123
144
|
</div>
|
|
124
|
-
)}
|
|
125
|
-
|
|
126
|
-
|
|
145
|
+
) : label}
|
|
146
|
+
{children}
|
|
147
|
+
{descriptionPosition === 'bottom' ? description : <></>}
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
color: var(--pte-new-colors-contentDisabled);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
&[data-status="error"] {
|
|
111
111
|
color: var(--pte-new-colors-contentNegative);
|
|
112
112
|
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
color: var(--pte-new-colors-contentNegative);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
&[data-status="success"] {
|
|
119
119
|
color: var(--pte-new-colors-contentPositive);
|
|
120
120
|
|
|
@@ -158,6 +158,14 @@
|
|
|
158
158
|
gap: 8px;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
.labelContainer {
|
|
162
|
+
display: flex;
|
|
163
|
+
flex-direction: column;
|
|
164
|
+
gap: 2px;
|
|
165
|
+
align-items: flex-start;
|
|
166
|
+
justify-content: flex-start;
|
|
167
|
+
}
|
|
168
|
+
|
|
161
169
|
// Use double selector to ensure specificity is higher than the default styles
|
|
162
170
|
.label.label {
|
|
163
171
|
color: var(--pte-new-colors-contentPrimary);
|
|
@@ -177,4 +185,4 @@
|
|
|
177
185
|
&::-webkit-calendar-picker-indicator {
|
|
178
186
|
display: none;
|
|
179
187
|
}
|
|
180
|
-
}
|
|
188
|
+
}
|
|
@@ -71,6 +71,7 @@ export const Input: FC<InputProps & ComponentPropsWithoutRef<'input'>> = forward
|
|
|
71
71
|
hideLabel,
|
|
72
72
|
description,
|
|
73
73
|
hideDescription,
|
|
74
|
+
descriptionPosition,
|
|
74
75
|
startEnhancer,
|
|
75
76
|
endEnhancer,
|
|
76
77
|
disabled,
|
|
@@ -86,6 +87,7 @@ export const Input: FC<InputProps & ComponentPropsWithoutRef<'input'>> = forward
|
|
|
86
87
|
description={description}
|
|
87
88
|
hideDescription={hideDescription}
|
|
88
89
|
disabled={disabled}
|
|
90
|
+
descriptionPosition={descriptionPosition}
|
|
89
91
|
overrides={{
|
|
90
92
|
container: {
|
|
91
93
|
...overrides?.container,
|
|
@@ -98,6 +98,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
98
98
|
hideLabel,
|
|
99
99
|
description,
|
|
100
100
|
hideDescription,
|
|
101
|
+
descriptionPosition,
|
|
101
102
|
placeholder,
|
|
102
103
|
startEnhancer,
|
|
103
104
|
endEnhancer,
|
|
@@ -115,6 +116,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
115
116
|
hideLabel={hideLabel}
|
|
116
117
|
description={description}
|
|
117
118
|
hideDescription={hideDescription}
|
|
119
|
+
descriptionPosition={descriptionPosition}
|
|
118
120
|
disabled={disabled}
|
|
119
121
|
overrides={{
|
|
120
122
|
container: overrides?.container,
|
|
@@ -26,6 +26,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, InputProps & ComponentPr
|
|
|
26
26
|
hideLabel,
|
|
27
27
|
description,
|
|
28
28
|
hideDescription,
|
|
29
|
+
descriptionPosition,
|
|
29
30
|
startEnhancer,
|
|
30
31
|
endEnhancer,
|
|
31
32
|
disabled,
|
|
@@ -41,6 +42,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, InputProps & ComponentPr
|
|
|
41
42
|
hideLabel={hideLabel}
|
|
42
43
|
description={description}
|
|
43
44
|
hideDescription={hideDescription}
|
|
45
|
+
descriptionPosition={descriptionPosition}
|
|
44
46
|
disabled={disabled}
|
|
45
47
|
overrides={{
|
|
46
48
|
container: overrides?.container,
|