Improve controlled experience
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -697,21 +697,21 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-SelectFieldRoot {
|
||||
.canon-Select {
|
||||
font-family: var(--canon-font-regular);
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectFieldLabel {
|
||||
.canon-Select--label {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-SelectFieldDescription {
|
||||
.canon-Select--description {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -719,7 +719,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectFieldError {
|
||||
.canon-Select--error {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -727,7 +727,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger {
|
||||
.canon-Select--trigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -745,38 +745,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger::placeholder {
|
||||
.canon-Select--trigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:hover {
|
||||
.canon-Select--trigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
.canon-Select--trigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-small, .canon-SelectItem--size-small {
|
||||
.canon-Select--trigger-size-small {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-medium, .canon-SelectItem--size-medium {
|
||||
.canon-Select--trigger-size-medium {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -785,11 +785,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-SelectPopup {
|
||||
.canon-Select--popup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -804,12 +804,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-SelectItem {
|
||||
.canon-Select--item {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -827,13 +827,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
.canon-Select--item[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -843,19 +843,26 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-disabled] {
|
||||
.canon-Select--item[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectItemIndicator {
|
||||
.canon-Select--item-indicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectItemText {
|
||||
.canon-Select--item-text {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
.canon-SelectFieldRoot {
|
||||
.canon-Select {
|
||||
font-family: var(--canon-font-regular);
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectFieldLabel {
|
||||
.canon-Select--label {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-SelectFieldDescription {
|
||||
.canon-Select--description {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -20,7 +20,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectFieldError {
|
||||
.canon-Select--error {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -28,7 +28,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger {
|
||||
.canon-Select--trigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -46,38 +46,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger::placeholder {
|
||||
.canon-Select--trigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:hover {
|
||||
.canon-Select--trigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
.canon-Select--trigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-small, .canon-SelectItem--size-small {
|
||||
.canon-Select--trigger-size-small {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-medium, .canon-SelectItem--size-medium {
|
||||
.canon-Select--trigger-size-medium {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -86,11 +86,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-SelectPopup {
|
||||
.canon-Select--popup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -105,12 +105,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-SelectItem {
|
||||
.canon-Select--item {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -128,13 +128,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
.canon-Select--item[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -144,19 +144,26 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-disabled] {
|
||||
.canon-Select--item[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectItemIndicator {
|
||||
.canon-Select--item-indicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectItemText {
|
||||
.canon-Select--item-text {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
@@ -9903,21 +9903,21 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-SelectFieldRoot {
|
||||
.canon-Select {
|
||||
font-family: var(--canon-font-regular);
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectFieldLabel {
|
||||
.canon-Select--label {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-SelectFieldDescription {
|
||||
.canon-Select--description {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -9925,7 +9925,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectFieldError {
|
||||
.canon-Select--error {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -9933,7 +9933,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger {
|
||||
.canon-Select--trigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -9951,38 +9951,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger::placeholder {
|
||||
.canon-Select--trigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:hover {
|
||||
.canon-Select--trigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
.canon-Select--trigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-small, .canon-SelectItem--size-small {
|
||||
.canon-Select--trigger-size-small {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger--size-medium, .canon-SelectItem--size-medium {
|
||||
.canon-Select--trigger-size-medium {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -9991,11 +9991,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-SelectPopup {
|
||||
.canon-Select--popup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -10010,12 +10010,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-SelectItem {
|
||||
.canon-Select--item {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -10033,13 +10033,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
.canon-Select--item[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -10049,19 +10049,26 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-SelectItem[data-disabled] {
|
||||
.canon-Select--item[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-SelectItemIndicator {
|
||||
.canon-Select--item-indicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-SelectItemText {
|
||||
.canon-Select--item-text {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
```ts
|
||||
import { Breakpoint as Breakpoint_2 } from '@backstage/canon';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { Context } from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { FocusEvent as FocusEvent_2 } from 'react';
|
||||
import { ForwardRefExoticComponent } from 'react';
|
||||
import { Menu as Menu_2 } from '@base-ui-components/react/menu';
|
||||
import { default as React_2 } from 'react';
|
||||
@@ -915,7 +917,7 @@ export const ScrollArea: {
|
||||
|
||||
// @public (undocumented)
|
||||
export const Select: React_2.ForwardRefExoticComponent<
|
||||
SelectProps & React_2.RefAttributes<HTMLSelectElement>
|
||||
SelectProps & React_2.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -924,8 +926,11 @@ export interface SelectProps {
|
||||
defaultValue?: string;
|
||||
description?: string;
|
||||
disabled?: boolean;
|
||||
error?: string;
|
||||
label?: string;
|
||||
name: string;
|
||||
onBlur?: (event: FocusEvent_2<HTMLSelectElement>) => void;
|
||||
onChange?: (event: ChangeEvent<HTMLSelectElement>) => void;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
onValueChange?: (value: string) => void;
|
||||
options?: Array<{
|
||||
|
||||
@@ -13,11 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Select } from './Select';
|
||||
import { Form } from '@base-ui-components/react/form';
|
||||
import { Button } from '../Button';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
const meta = {
|
||||
|
||||
@@ -34,7 +34,7 @@ type Inputs = {
|
||||
city: string;
|
||||
};
|
||||
|
||||
export const Default: Story = {
|
||||
export const Uncontrolled: Story = {
|
||||
render: () => {
|
||||
const {
|
||||
register,
|
||||
@@ -96,3 +96,101 @@ export const Default: Story = {
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const Controlled: Story = {
|
||||
render: () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useForm<Inputs>();
|
||||
|
||||
const [firstname, setFirstname] = React.useState('John');
|
||||
const [lastname, setLastname] = React.useState('Doe');
|
||||
const [city, setCity] = React.useState('london');
|
||||
|
||||
const onSubmit: SubmitHandler<Inputs> = data => {
|
||||
console.log('data', data);
|
||||
setFirstname(data.firstname);
|
||||
setLastname(data.lastname);
|
||||
setCity(data.city);
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
alignItems: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<Controller
|
||||
name="firstname"
|
||||
control={control}
|
||||
defaultValue={firstname}
|
||||
rules={{ required: 'First name is required' }}
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<TextField
|
||||
label="First Name"
|
||||
name={field.name}
|
||||
value={firstname}
|
||||
onChange={e => {
|
||||
field.onChange(e);
|
||||
setFirstname(e.target.value);
|
||||
}}
|
||||
error={errors.firstname?.message}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
name="lastname"
|
||||
control={control}
|
||||
defaultValue={lastname}
|
||||
rules={{ required: 'Last name is required' }}
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<TextField
|
||||
label="Last Name"
|
||||
name={field.name}
|
||||
value={lastname}
|
||||
onChange={e => {
|
||||
field.onChange(e);
|
||||
setLastname(e.target.value);
|
||||
}}
|
||||
error={errors.lastname?.message}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
name="city"
|
||||
control={control}
|
||||
defaultValue={city}
|
||||
rules={{ required: 'New city is required' }}
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<Select
|
||||
label="New City"
|
||||
options={[
|
||||
{ value: 'london', label: 'London' },
|
||||
{ value: 'paris', label: 'Paris' },
|
||||
{ value: 'new-york', label: 'New York' },
|
||||
]}
|
||||
name={field.name}
|
||||
value={city}
|
||||
onValueChange={field.onChange}
|
||||
error={errors.city?.message}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user