fix: special requests
This commit is contained in:
@@ -46,3 +46,26 @@ input:placeholder-shown:active ~ .label {
|
||||
input:disabled ~ .label {
|
||||
color: var(--Main-Grey-40);
|
||||
}
|
||||
|
||||
textarea:active ~ .label,
|
||||
textarea:not(:placeholder-shown) ~ .label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
textarea:focus ~ .label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
textarea:placeholder-shown ~ .label {
|
||||
grid-row: 1/-1;
|
||||
}
|
||||
|
||||
textarea:placeholder-shown:focus ~ .label,
|
||||
textarea:placeholder-shown:active ~ .label {
|
||||
margin-bottom: var(--Spacing-x-half);
|
||||
}
|
||||
|
||||
textarea:disabled ~ .label {
|
||||
color: var(--Main-Grey-40);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import ReactAriaSelect from "@/components/TempDesignSystem/Select"
|
||||
import type { SelectProps } from "./select"
|
||||
|
||||
export default function Select({
|
||||
className,
|
||||
items,
|
||||
label,
|
||||
name,
|
||||
@@ -21,6 +22,7 @@ export default function Select({
|
||||
|
||||
return (
|
||||
<ReactAriaSelect
|
||||
className={className}
|
||||
defaultSelectedKey={field.value}
|
||||
disabled={field.disabled}
|
||||
items={items}
|
||||
|
||||
90
components/TempDesignSystem/Form/TextArea/index.tsx
Normal file
90
components/TempDesignSystem/Form/TextArea/index.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
"use client"
|
||||
import {
|
||||
Label as AriaLabel,
|
||||
Text,
|
||||
TextArea as AriaTextArea,
|
||||
TextField,
|
||||
} from "react-aria-components"
|
||||
import { Controller, useFormContext } from "react-hook-form"
|
||||
|
||||
import { CheckIcon, InfoCircleIcon } from "@/components/Icons"
|
||||
import Label from "@/components/TempDesignSystem/Form/Label"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
|
||||
import Body from "../../Text/Body"
|
||||
|
||||
import styles from "./textarea.module.css"
|
||||
|
||||
import type { HTMLAttributes, WheelEvent } from "react"
|
||||
|
||||
import type { TextAreaProps } from "./input"
|
||||
|
||||
export default function TextArea({
|
||||
"aria-label": ariaLabel,
|
||||
className = "",
|
||||
disabled = false,
|
||||
helpText = "",
|
||||
label,
|
||||
name,
|
||||
placeholder = "",
|
||||
readOnly = false,
|
||||
registerOptions = {},
|
||||
type = "text",
|
||||
}: TextAreaProps) {
|
||||
const { control } = useFormContext()
|
||||
let numberAttributes: HTMLAttributes<HTMLTextAreaElement> = {}
|
||||
if (type === "number") {
|
||||
numberAttributes.onWheel = function (evt: WheelEvent<HTMLTextAreaElement>) {
|
||||
evt.currentTarget.blur()
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Controller
|
||||
disabled={disabled}
|
||||
control={control}
|
||||
name={name}
|
||||
rules={registerOptions}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
aria-label={ariaLabel}
|
||||
className={className}
|
||||
isDisabled={field.disabled}
|
||||
isRequired={!!registerOptions.required}
|
||||
onBlur={field.onBlur}
|
||||
onChange={field.onChange}
|
||||
validationBehavior="aria"
|
||||
value={field.value}
|
||||
>
|
||||
<AriaLabel className={styles.container} htmlFor={name}>
|
||||
<Body asChild fontOnly>
|
||||
<AriaTextArea
|
||||
{...field}
|
||||
aria-labelledby={field.name}
|
||||
id={name}
|
||||
placeholder={placeholder}
|
||||
readOnly={readOnly}
|
||||
required={!!registerOptions.required}
|
||||
className={styles.textarea}
|
||||
/>
|
||||
</Body>
|
||||
<Label required={!!registerOptions.required}>{label}</Label>
|
||||
</AriaLabel>
|
||||
{helpText && !fieldState.error ? (
|
||||
<Caption asChild color="black">
|
||||
<Text className={styles.helpText} slot="description">
|
||||
<CheckIcon height={20} width={30} />
|
||||
{helpText}
|
||||
</Text>
|
||||
</Caption>
|
||||
) : null}
|
||||
{fieldState.error ? (
|
||||
<Caption className={styles.error} fontOnly>
|
||||
<InfoCircleIcon color="red" />
|
||||
{fieldState.error.message}
|
||||
</Caption>
|
||||
) : null}
|
||||
</TextField>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
9
components/TempDesignSystem/Form/TextArea/input.ts
Normal file
9
components/TempDesignSystem/Form/TextArea/input.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export interface TextAreaProps
|
||||
extends React.InputHTMLAttributes<HTMLTextAreaElement> {
|
||||
helpText?: string
|
||||
label: string
|
||||
name: string
|
||||
registerOptions?: RegisterOptions
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
.helpText {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
}
|
||||
|
||||
.error {
|
||||
align-items: center;
|
||||
color: var(--Scandic-Red-60);
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
margin: var(--Spacing-x1) 0 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: var(--Main-Grey-White);
|
||||
border-color: var(--Scandic-Beige-40);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
display: grid;
|
||||
min-width: 0; /* allow shrinkage */
|
||||
grid-template-rows: auto 1fr;
|
||||
height: 138px;
|
||||
padding: var(--Spacing-x3) var(--Spacing-x2) 0 var(--Spacing-x2);
|
||||
transition: border-color 200ms ease;
|
||||
}
|
||||
|
||||
.container:has(.textarea:active, .textarea:focus) {
|
||||
border-color: var(--Scandic-Blue-90);
|
||||
}
|
||||
|
||||
.container:has(.textarea:disabled) {
|
||||
background-color: var(--Main-Grey-10);
|
||||
border: none;
|
||||
color: var(--Main-Grey-40);
|
||||
}
|
||||
|
||||
.container:has(.textarea[data-invalid="true"], .textarea[aria-invalid="true"]) {
|
||||
border-color: var(--Scandic-Red-60);
|
||||
}
|
||||
|
||||
.textarea {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--Main-Grey-100);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
order: 2;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.textarea:not(:active, :focus):placeholder-shown {
|
||||
height: 88px;
|
||||
transition: height 150ms ease;
|
||||
}
|
||||
|
||||
.textarea:focus,
|
||||
.textarea:focus:placeholder-shown,
|
||||
.textarea:active,
|
||||
.textarea:active:placeholder-shown {
|
||||
height: 94px;
|
||||
transition: height 150ms ease;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.textarea:disabled {
|
||||
color: var(--Main-Grey-40);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import type {
|
||||
} from "./select"
|
||||
|
||||
export default function Select({
|
||||
className = "",
|
||||
"aria-label": ariaLabel,
|
||||
defaultSelectedKey,
|
||||
items,
|
||||
@@ -54,7 +55,7 @@ export default function Select({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container} ref={setRef}>
|
||||
<div className={`${styles.container} ${className}`} ref={setRef}>
|
||||
<ReactAriaSelect
|
||||
aria-label={ariaLabel}
|
||||
className={`${styles.select} ${discreet && styles.discreet}`}
|
||||
@@ -68,11 +69,26 @@ export default function Select({
|
||||
<Body asChild fontOnly>
|
||||
<Button className={styles.input} data-testid={name}>
|
||||
<span className={styles.inputContentWrapper} tabIndex={tabIndex}>
|
||||
<Label required={required} size={discreet ? "discreet" : "small"}>
|
||||
{label}
|
||||
{discreet && `:`}
|
||||
</Label>
|
||||
<SelectValue />
|
||||
<SelectValue>
|
||||
{({ isPlaceholder, selectedText }) => (
|
||||
<>
|
||||
<Label
|
||||
required={required}
|
||||
size={discreet ? "discreet" : "small"}
|
||||
>
|
||||
{label}
|
||||
{discreet && `:`}
|
||||
</Label>
|
||||
{isPlaceholder ? (
|
||||
placeholder ? (
|
||||
<Body color="uiTextPlaceholder"> {placeholder}</Body>
|
||||
) : null
|
||||
) : (
|
||||
selectedText
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</SelectValue>
|
||||
</span>
|
||||
<SelectChevron
|
||||
{...(discreet ? { color: "baseButtonTextOnFillNormal" } : {})}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Key, SelectProps as AriaSelectProps } from "react-aria-components"
|
||||
import type { Key } from "react-aria-components"
|
||||
|
||||
export interface SelectProps
|
||||
extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "onSelect"> {
|
||||
|
||||
Reference in New Issue
Block a user