Newer
Older
gnexus-ui-kit / src / scss / components / _forms.scss
@use "../kit-deps" as *;
@use "typography" as *;

.form-group {
	width: 100%;
	max-width: 600px;
	
	.label {
		display: flex;
		flex-direction: column;
		font-size: $font-size-base;
		width: 100%;
		position: relative;

		& > .ph {
			position: absolute;
			color: $color-text-light;
			left: 0;
			bottom: 1px;
			font-size: $icon-size-lg;
			height: $control-height-lg;
			display: inline-flex;
			align-items: center;
			width: $control-height-md;
			justify-content: center;
			transition-duration: .2s;
			transition-property: color, left;
		}

		.input {
			min-height: $control-height-lg;
			font-family: $font-family-base;
			font-size: $font-size-base;
			font-weight: $font-weight-medium;
			line-height: $line-height-base;
			letter-spacing: $letter-spacing-wide;
			padding: $space-3 $space-lg;
			margin-top: $space-sm;
			border-radius: 0;
			border-width: $border-width-base;
			border-bottom-width: $border-width-accent;
			border-style: $border-style-base;
			border-color: $color-text-light;
			color: $color-text-light;
			background-color: $surface-panel-muted;
			transition-duration: $motion-base;
			transition-timing-function: $motion-ease;
			transition-property: background-color, border-color, color;

			@include hover_touch {
				border-bottom-color: $color-text-dark;
			}

			&:focus {
				@include focus_ring;
				border-color: $color-electric-blue;
				background-color: transparent;
			}

			&:disabled {
				color: $color-text-dark;
				border-color: $border-color-muted;
				background: $surface-panel;
				cursor: not-allowed;
				opacity: 0.72;
			}

			&[readonly] {
				color: $color-text-medium;
				border-color: $border-color-muted;
				background: rgba($color-text-light, 0.03);
			}

			&::placeholder {
				color: $color-text-dark;
			}

			&::-webkit-search-cancel-button,
			&::-webkit-search-decoration,
			&::-webkit-search-results-button,
			&::-webkit-search-results-decoration {
				display: none;
				-webkit-appearance: none;
			}
		}

		textarea.input {
			height: $control-height-lg * 2;
			line-height: $line-height-snug;
			resize: none;
		}

		.ph + .input,
		.ph + .select-wrap .select {
			padding-left: $control-height-md;
		}

		.select-wrap {
			margin-top: $space-sm;
		}

		.select {
			width: 100%;
			height: $control-height-lg;
			margin-top: 0;

			/* убрать нативную стрелку */
			appearance: none;
			-webkit-appearance: none;
			-moz-appearance: none;

			&:focus {
				outline: none;
			}

			option {
				color: $color-text-light;
				background: $color-dark;
			}
		}

		.select-wrap::after {
			content: "";
			position: absolute;
			right: $space-lg;
			bottom: 18px;
			transform: translateY(-50%);

			width: 0;
			height: 0;
			border-left: 8px solid transparent;
			border-right: 8px solid transparent;
			border-top: 10px solid $color-text-light;

			pointer-events: none;
		}

		&.error {
			.input:not(:focus) {
				border-color: $color-error;
			}

			& + .input-info {
				color: $color-warning;
			}
		}

		&.success {
			.input:not(:focus) {
				border-color: $color-success;
			}

			& + .input-info {
				color: $color-success;
			}
		}

		&.warning {
			.input:not(:focus) {
				border-color: $color-warning;
			}

			& + .input-info {
				color: $color-warning;
			}
		}
	}

	.input-info {
		font-size: $font-size-md;
		margin-top: $space-2;

		.ph {
			position: relative;
			top: 1px;
		}

		&.error {
			color: $color-warning;
		}
	}
}

.form-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: $space-4;
	width: 100%;
	max-width: 760px;
}

.fieldset {
	width: 100%;
	max-width: 760px;
	margin: 0;
	padding: $space-5;
	border: $border-width-base solid $border-color-muted;
	border-left-width: $border-width-accent;
	background: $surface-panel-muted;
}

.legend {
	padding: $space-1 $space-2;
	color: $color-black;
	background: $color-primary;
	font-size: $font-size-sm;
	font-weight: $font-weight-bold;
	line-height: $line-height-base;
	text-transform: uppercase;
}

.file-upload {
	display: inline-flex;
	align-items: center;
	gap: $space-2;
	min-height: $control-height-md;
	padding: $space-2 $space-3;
	border: $border-width-base solid $color-secondary;
	border-left-width: $border-width-accent;
	color: $color-secondary;
	background: $surface-panel-muted;
	font-size: $font-size-sm;
	font-weight: $font-weight-bold;
	text-transform: uppercase;
	cursor: pointer;
	transition-duration: $motion-base;
	transition-timing-function: $motion-ease;
	transition-property: color, background, border-color;

	input[type="file"] {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
		white-space: nowrap;
	}

	@include hover_touch {
		color: $color-black;
		background: $color-secondary;
	}

	&:focus-within {
		@include focus_ring;
	}
}

.range {
	width: 100%;
	max-width: 600px;
	accent-color: $color-secondary;

	input[type="range"] {
		-webkit-appearance: none;
		appearance: none;
		width: 100%;
		height: $control-height-md;
		margin: 0;
		background: transparent;
		cursor: pointer;
	}

	input[type="range"]::-webkit-slider-runnable-track {
		height: $border-width-accent;
		background: $surface-panel-strong;
		border: $border-width-base solid $border-color-muted;
	}

	input[type="range"]::-webkit-slider-thumb {
		width: $control-choice-size;
		height: $control-height-sm;
		margin-top: calc(-#{$control-height-sm} / 2);
		border: $border-width-base solid $color-secondary;
		background: $color-secondary;
		-webkit-appearance: none;
	}

	input[type="range"]::-moz-range-track {
		height: $border-width-accent;
		background: $surface-panel-strong;
		border: $border-width-base solid $border-color-muted;
	}

	input[type="range"]::-moz-range-thumb {
		width: $control-choice-size;
		height: $control-height-sm;
		border: $border-width-base solid $color-secondary;
		border-radius: 0;
		background: $color-secondary;
	}
}

@include media_down("md") {
	.form-grid {
		grid-template-columns: 1fr;
	}
}

.radio {
	display: inline-flex;
	flex-direction: row;
	gap: $space-sm;
	align-items: center;

	input[type="radio"] {
		display: none;
	}

	.radio-control {
		display: inline-block;
		border-radius: 100%;
		border: $border-width-base solid $color-primary;
		width: $control-choice-size;
		height: $control-choice-size;
		background: transparent;
		transition-duration: $motion-base;
		transition-property: background, border-color;
	}

	@include hover_touch {
	 .radio-control {
			background: $color-grey;
		}
	}

	input[type="radio"]:checked + .radio-control {
		background: $color-primary;
	}

	input[type="radio"]:disabled + .radio-control {
		background: $color-grey;
		border-color: $color-grey;
	}

	input[type="radio"]:focus-visible + .radio-control {
		@include focus_ring;
	}

	.radio-label {
		font-size: $font-size-base;
	}
}

.checkbox {
	display: inline-flex;
	flex-direction: row;
	gap: $space-sm;
	align-items: center;

	input[type="checkbox"] {
		display: none;
	}

	.checkbox-control {
		height: $control-switch-height;
		width: $control-switch-width;
		border: $border-width-base solid $color-primary;
		position: relative;
		background: transparent;
		transition-duration: $motion-base;
		transition-property: border-color, background;
		display: block;
	}

	.checkbox-control:before {
		content: "";
		display: block;
		height: $control-switch-knob;
		width: $control-switch-knob;
		background: $color-primary;
		position: absolute;
		left: -$space-1;
		top: -$space-1;
		transition-duration: $motion-base;
		transition-property: left, background;
	}

	@include hover_touch {
		.checkbox-control {
			background: $color-grey;
		}
	}

	input[type="checkbox"]:checked:not(:disabled) + .checkbox-control {
		background: $color-secondary;
		border-color: $color-secondary;
	}

	input[type="checkbox"]:checked + .checkbox-control:before {
		left: $control-switch-width - $control-switch-knob + $space-1;
	}

	input[type="checkbox"]:disabled + .checkbox-control {
		border-color: $color-grey;
	}

	input[type="checkbox"]:focus-visible + .checkbox-control {
		@include focus_ring;
	}

	input[type="checkbox"]:disabled + .checkbox-control:before {
		background: $color-grey;
	}
}