Skip to content

Commit 10450e4

Browse files
nmergetmfranzke
andauthored
feat: add field-sizing for input and textarea (#4254)
* feat: add field-sizing for input and textarea * Update model.ts * feat: add showResizer to align with design * chore: update snapshots --------- Co-authored-by: Maximilian Franzke <787658+mfranzke@users.noreply.github.com>
1 parent 7548c2f commit 10450e4

File tree

18 files changed

+109
-10
lines changed

18 files changed

+109
-10
lines changed

packages/components/src/components/input/input.lite.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export default function DBInput(props: DBInputProps) {
207207
<input
208208
aria-invalid={props.validation === 'invalid'}
209209
data-custom-validity={props.validation}
210+
data-field-sizing={props.fieldSizing}
210211
ref={_ref}
211212
id={state._id}
212213
name={props.name}

packages/components/src/components/textarea/model.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export type DBTextareaDefaultProps = {
3434
* In most browsers, textareas are resizable — you'll notice the drag handle in the right-hand corner, you can control it with this
3535
*/
3636
resize?: TextareaResizeType;
37+
38+
/**
39+
* Show/Hides drag handle in the right-hand corner - default: true
40+
*/
41+
showResizer?: boolean | string;
42+
3743
/**
3844
* The number of visible text lines for the control. If it is specified, it must be a positive integer
3945
*/

packages/components/src/components/textarea/textarea.lite.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,11 @@ export default function DBTextarea(props: DBTextareaProps) {
176176
<textarea
177177
aria-invalid={props.validation === 'invalid'}
178178
data-custom-validity={props.validation}
179+
data-field-sizing={props.fieldSizing}
179180
ref={_ref}
180181
id={state._id}
181182
data-resize={props.resize}
183+
data-hide-resizer={getHideProp(props.showResizer ?? true)}
182184
disabled={getBoolean(props.disabled, 'disabled')}
183185
required={getBoolean(props.required, 'required')}
184186
readOnly={

packages/components/src/components/textarea/textarea.scss

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,27 @@
88
@use "../../styles/internal/scrollbar";
99

1010
%resize-textarea {
11-
&[data-resize="none"] {
11+
&[data-hide-resizer="true"] {
1212
resize: none;
1313
}
1414

15-
&[data-resize="both"] {
16-
resize: both;
17-
}
15+
// TODO: Consolidate data-hide-resizer and data-resize attributes in the future
16+
&:not([data-hide-resizer="true"]) {
17+
&[data-resize="none"] {
18+
resize: none;
19+
}
1820

19-
&[data-resize="horizontal"] {
20-
resize: horizontal;
21-
}
21+
&[data-resize="both"] {
22+
resize: both;
23+
}
2224

23-
&[data-resize="vertical"] {
24-
resize: vertical;
25+
&[data-resize="horizontal"] {
26+
resize: horizontal;
27+
}
28+
29+
&[data-resize="vertical"] {
30+
resize: vertical;
31+
}
2532
}
2633
}
2734

packages/components/src/shared/model.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ export type FormProps = CustomFormProps &
312312
ShowLabelProps &
313313
ValueProps;
314314

315+
export const FieldSizingList = ['fixed', 'content'] as const;
316+
export type FieldSizingType = (typeof FieldSizingList)[number];
317+
315318
export type FormTextProps = {
316319
/**
317320
* Maximum length (number of characters) of value
@@ -337,6 +340,12 @@ export type FormTextProps = {
337340
* The disabled attribute can be set to keep a user from edit on the form element
338341
*/
339342
readonly?: boolean | string;
343+
344+
/**
345+
* Adds shrinkwrap for input and textarea: https://developer.mozilla.org/en-US/docs/Web/CSS/field-sizing
346+
* Note: Only supported in Chromium browsers so far
347+
*/
348+
fieldSizing?: FieldSizingType;
340349
};
341350

342351
export type FormSizeProps = {

packages/components/src/styles/internal/_form-components.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,17 @@ $input-valid-types:
363363
background-color: colors.$db-adaptive-bg-basic-transparent-hovered;
364364
}
365365

366+
&:is(input, textarea) {
367+
/* see https://developer.mozilla.org/en-US/docs/Web/CSS/field-sizing */
368+
&[data-field-sizing="content"] {
369+
field-sizing: content;
370+
}
371+
372+
&[data-field-sizing="fixed"] {
373+
field-sizing: fixed;
374+
}
375+
}
376+
366377
&:is(input, textarea):not(:disabled):read-only {
367378
background-color: var(
368379
--db-textarea-read-only,

packages/components/src/styles/internal/_scrollbar.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
$scrollbar-width: helpers.px-to-rem(8);
88

99
%scrollbar {
10+
&[data-field-sizing="content"] {
11+
&:is([data-hide-resizer="true"], [data-resize="none"]) {
12+
@supports (field-sizing: content) {
13+
/* We don't show a scrollbar if we use field-sizing: content and no resizer is available */
14+
scrollbar-width: none;
15+
}
16+
}
17+
}
18+
1019
&::-webkit-scrollbar {
1120
@extend %default-transition;
1221

showcases/angular-showcase/src/app/components/textarea/textarea.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
[invalidMessage]="exampleProps?.invalidMessage"
2727
[validMessage]="exampleProps?.validMessage"
2828
[validation]="exampleProps?.validation"
29+
[showResizer]="exampleProps?.showResizer"
30+
[fieldSizing]="exampleProps?.fieldSizing"
2931
></db-textarea>
3032
</ng-template>
3133
</app-default-component>

showcases/react-showcase/src/components/form/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ const FormComponent = () => {
7272
<div className="form-container">
7373
<div>
7474
<form>
75+
<DBTextarea
76+
label="test"
77+
placeholder="fieldsizing"
78+
resize="none"
79+
fieldSizing="content"></DBTextarea>
80+
7581
<DBCustomSelect
7682
options={[{ value: 'Option 1' }, { value: 'Option 2' }]}
7783
label="Test"

showcases/react-showcase/src/components/textarea/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ const getTextarea = ({
2222
showMessage,
2323
validMessage,
2424
validation,
25-
invalidMessage
25+
invalidMessage,
26+
fieldSizing,
27+
showResizer
2628
}: DBTextareaProps) => {
2729
const [dynamicValue, setDynamicValue] = useState<string>(value);
2830
return (
@@ -45,6 +47,8 @@ const getTextarea = ({
4547
invalidMessage={invalidMessage}
4648
validMessage={validMessage}
4749
validation={validation}
50+
showResizer={showResizer}
51+
fieldSizing={fieldSizing}
4852
/>
4953
);
5054
};

showcases/shared/textarea.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,46 @@
210210
}
211211
]
212212
},
213+
{
214+
"name": "Show Resizer",
215+
"examples": [
216+
{
217+
"name": "(Default) True",
218+
"props": {
219+
"label": "Label",
220+
"showResizer": true
221+
}
222+
},
223+
{
224+
"name": "False",
225+
"props": {
226+
"label": "Label",
227+
"showResizer": false
228+
}
229+
}
230+
]
231+
},
232+
{
233+
"name": "Field Sizing",
234+
"examples": [
235+
{
236+
"name": "(Default) Fixed",
237+
"style": { "width": "300px" },
238+
"props": {
239+
"label": "Label",
240+
"fieldSizing": "fixed"
241+
}
242+
},
243+
{
244+
"name": "Content",
245+
"style": { "width": "300px" },
246+
"props": {
247+
"label": "Label",
248+
"fieldSizing": "content"
249+
}
250+
}
251+
]
252+
},
213253
{
214254
"name": "Examples Floating Label",
215255
"examples": [

showcases/vue-showcase/src/components/textarea/Textarea.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import { DBCheckbox, DBInput, DBTextarea } from "../../../../../output/vue/src";
2525
:invalidMessage="exampleProps?.invalidMessage"
2626
:validMessage="exampleProps?.validMessage"
2727
:validation="exampleProps?.validation"
28+
:showResizer="exampleProps?.showResizer"
29+
:fieldSizing="exampleProps?.fieldSizing"
2830
></DBTextarea>
2931
</template>
3032
</DefaultComponent>

0 commit comments

Comments
 (0)