diff --git a/packages/css/checkbox.css b/packages/css/checkbox.css index 5dc9595f57..705cdde3b5 100644 --- a/packages/css/checkbox.css +++ b/packages/css/checkbox.css @@ -59,24 +59,18 @@ grid-column: 2; } - .fds-checkbox--disabled > .fds-checkbox__input, - .fds-checkbox--disabled > .fds-checkbox__label, - .fds-checkbox--disabled > .fds-checkbox__input::before { - cursor: not-allowed; - } - - .fds-checkbox--disabled > .fds-checkbox__label, - .fds-checkbox--disabled > .fds-checkbox__input, - .fds-checkbox--disabled > .fds-checkbox__description { - opacity: var(--fds-opacity-disabled); - } - .fds-checkbox--readonly > .fds-checkbox__label, .fds-checkbox--readonly > .fds-checkbox__input, .fds-checkbox--readonly > .fds-checkbox__input::before { cursor: default; } + .fds-checkbox__input:disabled, + .fds-checkbox__input:disabled ~ .fds-checkbox__label, + .fds-checkbox__input:disabled::before { + cursor: not-allowed; + } + .fds-checkbox__input:focus-visible { outline-offset: 0; outline: var(--fds-checkbox-focus-border-width) solid var(--fds-semantic-border-focus-outline); @@ -103,6 +97,12 @@ --fds-checkbox-background: var(--fds-semantic-surface-neutral-subtle); } + .fds-checkbox__input:disabled, + .fds-checkbox__input:disabled ~ .fds-checkbox__label, + .fds-checkbox__input:disabled ~ .fds-checkbox__description { + opacity: var(--fds-opacity-disabled); + } + .fds-checkbox__input:checked:not(:focus-visible) { box-shadow: inset 0 0 0 2px var(--fds-checkbox-border-color); } @@ -125,12 +125,12 @@ /* Only use hover for non-touch devices to prevent sticky-hovering "input:not(:read-only)" does not work so using ".container:not(.readonly) >" instead */ @media (hover: hover) and (pointer: fine) { - .fds-checkbox:not(.fds-checkbox--readonly, .fds-checkbox--disabled) > .fds-checkbox__label:hover, - .fds-checkbox:not(.fds-checkbox--readonly, .fds-checkbox--disabled) > .fds-checkbox__input:hover + .fds-checkbox__label { + .fds-checkbox:not(.fds-checkbox--readonly) .fds-checkbox__input:not(:disabled) ~ .fds-checkbox__label:hover, + .fds-checkbox:not(.fds-checkbox--readonly) .fds-checkbox__input:hover:not(:disabled) ~ .fds-checkbox__label { color: var(--fds-semantic-text-action-hover); } - .fds-checkbox:not(.fds-checkbox--readonly, .fds-checkbox--disabled) > .fds-checkbox__input:hover:not(:checked) { + .fds-checkbox:not(.fds-checkbox--readonly) .fds-checkbox__input:hover:not(:checked, :disabled) { --fds-checkbox-border-color: var(--fds-semantic-border-input-hover); box-shadow: @@ -138,7 +138,7 @@ inset 0 0 0 2px var(--fds-checkbox-border-color); } - .fds-checkbox:not(.fds-checkbox--readonly, .fds-checkbox--disabled) > .fds-checkbox__input:hover:checked { + .fds-checkbox:not(.fds-checkbox--readonly) .fds-checkbox__input:hover:checked:not(:disabled) { --fds-checkbox-border-color: var(--fds-semantic-border-input-hover); box-shadow: @@ -146,7 +146,7 @@ inset 0 0 0 2px var(--fds-checkbox-border-color); } - .fds-checkbox:not(.fds-checkbox--readonly, .fds-checkbox--disabled) > .fds-checkbox__input:hover:checked:focus-visible { + .fds-checkbox:not(.fds-checkbox--readonly) .fds-checkbox__input:hover:checked:focus-visible:not(:disabled) { box-shadow: var(--fds-checkbox-border__hover), inset 0 0 0 var(--fds-checkbox-focus-border-width) var(--fds-semantic-border-focus-boxshadow); diff --git a/packages/css/fieldset.css b/packages/css/fieldset.css index 6631bd5cb4..3aac164f10 100644 --- a/packages/css/fieldset.css +++ b/packages/css/fieldset.css @@ -30,8 +30,8 @@ width: 1.2em; } - .fds-fieldset--disabled .fds-fieldset__legend, - .fds-fieldset--disabled .fds-fieldset__description { + .fds-fieldset:disabled .fds-fieldset__legend, + .fds-fieldset:disabled .fds-fieldset__description { color: var(--fds-semantic-border-neutral-subtle); } diff --git a/packages/css/native-select.css b/packages/css/native-select.css index c7270a8835..620d52fd48 100644 --- a/packages/css/native-select.css +++ b/packages/css/native-select.css @@ -50,11 +50,11 @@ gap: var(--fds-spacing-2); } - .fds-native-select--disabled { + .fds-native-select--container:has(.fds-native-select:disabled) { opacity: var(--fds-opacity-disabled); } - .fds-native-select--disabled .fds-native-select { + .fds-native-select:disabled { cursor: not-allowed; } @@ -63,7 +63,7 @@ border-color: var(--fds-semantic-border-neutral-default); } - .fds-native-select--error > .fds-native-select:not(:focus-visible) { + .fds-native-select--error>.fds-native-select:not(:focus-visible) { border-color: var(--fds-semantic-border-danger-default); box-shadow: inset 0 0 0 1px var(--fds-semantic-border-danger-default); } diff --git a/packages/css/radio.css b/packages/css/radio.css index 797f6d0c72..2184b0e15e 100644 --- a/packages/css/radio.css +++ b/packages/css/radio.css @@ -59,22 +59,21 @@ grid-column: 2; } - .fds-radio--disabled > .fds-radio__input, - .fds-radio--disabled > .fds-radio__label, - .fds-radio--disabled > .fds-radio__input::before { - cursor: not-allowed; + .fds-radio--readonly > .fds-radio__input, + .fds-radio--readonly > .fds-radio__label, + .fds-radio--readonly > .fds-radio__input::before { + cursor: default; } - .fds-radio--disabled > .fds-radio__label, - .fds-radio--disabled > .fds-radio__input, - .fds-radio--disabled > .fds-radio__description { + .fds-radio:has(.fds-radio__input:disabled) > .fds-radio__description { opacity: var(--fds-opacity-disabled); } - .fds-radio--readonly > .fds-radio__input, - .fds-radio--readonly > .fds-radio__label, - .fds-radio--readonly > .fds-radio__input::before { - cursor: default; + .fds-radio__input:disabled, + .fds-radio__input:disabled::before, + .fds-radio:has(.fds-radio__input:disabled) > .fds-radio__label { + cursor: not-allowed; + opacity: var(--fds-opacity-disabled); } .fds-radio__input:focus-visible { @@ -113,12 +112,12 @@ /* Only use hover for non-touch devices to prevent sticky-hovering "input:not(:read-only)" does not work so using ".container:not(.readonly) >" instead */ @media (hover: hover) and (pointer: fine) { - .fds-radio:not(.fds-radio--readonly, .fds-radio--disabled) > .fds-radio__label:hover, - .fds-radio:not(.fds-radio--readonly, .fds-radio--disabled) > .fds-radio__input:hover + .fds-radio__label { + .fds-radio:not(.fds-radio--readonly) > .fds-radio__label:hover:not(:disabled), + .fds-radio:not(.fds-radio--readonly) > .fds-radio__input:hover:not(:disabled) + .fds-radio__label { color: var(--fds-semantic-text-action-hover); } - .fds-radio:not(.fds-radio--readonly, .fds-radio--disabled) > .fds-radio__input:hover:not(:checked) { + .fds-radio:not(.fds-radio--readonly) > .fds-radio__input:hover:not(:checked, :disabled) { --fds-radio-border-color: var(--fds-semantic-border-input-hover); box-shadow: @@ -126,7 +125,7 @@ inset 0 0 0 2px var(--fds-radio-border-color); } - .fds-radio:not(.fds-radio--readonly, .fds-radio--disabled) > .fds-radio__input:hover:checked { + .fds-radio:not(.fds-radio--readonly) > .fds-radio__input:hover:checked:not(:disabled) { --fds-radio-border-color: var(--fds-semantic-border-input-hover); box-shadow: @@ -135,7 +134,7 @@ inset 0 0 0 6px var(--fds-radio-background); } - .fds-radio:not(.fds-radio--readonly, .fds-radio--disabled) > .fds-radio__input:hover:checked:focus-visible { + .fds-radio:not(.fds-radio--readonly) > .fds-radio__input:hover:checked:focus-visible:not(:disabled) { box-shadow: var(--fds-radio-border__hover), inset 0 0 0 var(--fds-radio-focus-border-width) var(--fds-semantic-border-focus-boxshadow), diff --git a/packages/css/search.css b/packages/css/search.css index b82f7adf7e..629d6a363e 100644 --- a/packages/css/search.css +++ b/packages/css/search.css @@ -78,7 +78,7 @@ z-index: 1; } - .fds-search--disabled { + .fds-search:has(.fds-search__input:disabled) { opacity: var(--fds-opacity-disabled); } diff --git a/packages/css/switch.css b/packages/css/switch.css index 76675310d1..14298e91db 100644 --- a/packages/css/switch.css +++ b/packages/css/switch.css @@ -85,18 +85,6 @@ cursor: default; } - .fds-switch--disabled > .fds-switch__input, - .fds-switch--disabled > .fds-switch__label, - .fds-switch--disabled > .fds-switch__track { - cursor: not-allowed; - } - - .fds-switch--disabled > .fds-switch__label, - .fds-switch--disabled > .fds-switch__track, - .fds-switch--disabled > .fds-switch__description { - opacity: var(--fds-opacity-disabled); - } - .fds-switch--readonly > .fds-switch__description { margin-left: var(--fds-spacing-1); } @@ -154,6 +142,16 @@ margin-right: 0; } + .fds-switch__input:disabled, + .fds-switch:has(.fds-switch__input:disabled) > .fds-switch__label { + cursor: not-allowed; + } + + .fds-switch:has(.fds-switch__input:disabled) > .fds-switch__label, + .fds-switch:has(.fds-switch__input:disabled) > .fds-switch__description { + opacity: var(--fds-opacity-disabled); + } + .fds-switch__input:focus-visible + .fds-switch__label .fds-switch__track { outline: var(--fds-switch-focus-border-width) solid var(--fds-semantic-border-focus-outline); box-shadow: inset 0 0 0 var(--fds-switch-focus-border-width) var(--fds-semantic-border-focus-boxshadow); diff --git a/packages/css/textarea.css b/packages/css/textarea.css index 9fd10077d1..0dca5c35f3 100644 --- a/packages/css/textarea.css +++ b/packages/css/textarea.css @@ -4,7 +4,7 @@ gap: var(--fds-spacing-2); } - .fds-textarea__readonly__icon { + .fds-textarea__readonly-icon { height: 1.2em; width: 1.2em; } @@ -53,15 +53,15 @@ padding: var(--fds-spacing-4); } - .fds-textarea--disabled { + .fds-textarea:has(.fds-textarea__input:disabled) { opacity: var(--fds-opacity-disabled); } - .fds-textarea--disabled .fds-textarea__input { + .fds-textarea__input:disabled { cursor: not-allowed; } - .fds-textarea--readonly .fds-textarea__input { + .fds-textarea__input:read-only { background: var(--fds-semantic-surface-neutral-subtle); border-color: var(--fds-semantic-border-neutral-default); } diff --git a/packages/css/textfield.css b/packages/css/textfield.css index b73d2542a5..8cefa14fe7 100644 --- a/packages/css/textfield.css +++ b/packages/css/textfield.css @@ -27,7 +27,7 @@ border-radius: var(--fds-border_radius-medium); } - .fds-textfield--disabled .fds-textfield__input { + .fds-textfield__input:disabled { cursor: not-allowed; } @@ -101,7 +101,7 @@ margin-top: calc(var(--fds-spacing-2) * -1); } - .fds-textfield--disabled { + .fds-textfield:has(.fds-textfield__input:disabled) { opacity: var(--fds-opacity-disabled); } diff --git a/packages/react/src/components/form/Checkbox/Checkbox.tsx b/packages/react/src/components/form/Checkbox/Checkbox.tsx index 6a8effe6d1..594b3837da 100644 --- a/packages/react/src/components/form/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/form/Checkbox/Checkbox.tsx @@ -50,7 +50,6 @@ export const Checkbox = forwardRef( className={cl( 'fds-checkbox', `fds-checkbox--${size}`, - inputProps.disabled && `fds-checkbox--disabled`, hasError && `fds-checkbox--error`, readOnly && `fds-checkbox--readonly`, className, @@ -63,6 +62,7 @@ export const Checkbox = forwardRef( {...omit(['size', 'error', 'indeterminate'], rest)} {...inputProps} type='checkbox' + disabled={inputProps.disabled} aria-checked={rest.indeterminate ? 'mixed' : inputProps.checked} /> {children && ( diff --git a/packages/react/src/components/form/Fieldset/Fieldset.tsx b/packages/react/src/components/form/Fieldset/Fieldset.tsx index e4352bcc83..1018959f89 100644 --- a/packages/react/src/components/form/Fieldset/Fieldset.tsx +++ b/packages/react/src/components/form/Fieldset/Fieldset.tsx @@ -59,9 +59,9 @@ export const Fieldset = forwardRef( 'fds-fieldset', !hideLegend && 'fds-fieldset--spacing', readOnly && 'fds-fieldset--readonly', - props?.disabled && 'fds-fieldset--disabled', className, )} + disabled={props?.disabled} ref={ref} {...rest} > diff --git a/packages/react/src/components/form/NativeSelect/NativeSelect.tsx b/packages/react/src/components/form/NativeSelect/NativeSelect.tsx index 3aae147537..2dae118cad 100644 --- a/packages/react/src/components/form/NativeSelect/NativeSelect.tsx +++ b/packages/react/src/components/form/NativeSelect/NativeSelect.tsx @@ -73,7 +73,6 @@ export const NativeSelect = forwardRef(
((props, ref) => { className={cl( 'fds-radio', `fds-radio--${size}`, - inputProps.disabled && `fds-radio--disabled`, hasError && `fds-radio--error`, readOnly && `fds-radio--readonly`, className, @@ -44,6 +43,7 @@ export const Radio = forwardRef((props, ref) => { > ( > ( className={cl( 'fds-textarea', `fds-textarea--${size}`, - textareaProps.disabled && 'fds-textarea--disabled', - readOnly && `fds-textarea--readonly`, hasError && `fds-textarea--error`, className, )} @@ -93,7 +91,7 @@ export const Textarea = forwardRef( {readOnly && ( )} {label} @@ -119,6 +117,8 @@ export const Textarea = forwardRef( className={cl('fds-textarea__input', `fds-focus`)} ref={ref} aria-describedby={describedBy} + disabled={textareaProps.disabled} + readOnly={readOnly} {...omit(['size', 'error', 'errorId'], rest)} {...textareaProps} onChange={(e) => { diff --git a/packages/react/src/components/form/Textfield/Textfield.tsx b/packages/react/src/components/form/Textfield/Textfield.tsx index e7c69af994..5eca998bae 100644 --- a/packages/react/src/components/form/Textfield/Textfield.tsx +++ b/packages/react/src/components/form/Textfield/Textfield.tsx @@ -30,19 +30,19 @@ export type TextfieldProps = { suffix?: string; /** Supported `input` types */ type?: - | 'date' - | 'datetime-local' - | 'email' - | 'file' - | 'month' - | 'number' - | 'password' - | 'search' - | 'tel' - | 'text' - | 'time' - | 'url' - | 'week'; + | 'date' + | 'datetime-local' + | 'email' + | 'file' + | 'month' + | 'number' + | 'password' + | 'search' + | 'tel' + | 'text' + | 'time' + | 'url' + | 'week'; /** * The characterLimit function calculates remaining characters based on `maxCount` * @@ -112,7 +112,6 @@ export const Textfield = forwardRef( className={cl( `fds-textfield`, `fds-textfield--${size}`, - inputProps.disabled && `fds-textfield--disabled`, readOnly && `fds-textfield--readonly`, hasError && `fds-textfield--error`, className, @@ -177,6 +176,7 @@ export const Textfield = forwardRef( )} ref={ref} type={type} + disabled={inputProps.disabled} aria-describedby={describedBy} size={htmlSize} {...omit(['size', 'error', 'errorId'], rest)}