// 포커스 효과를 위한 믹스인 @mixin focus($offset: -.4rem, $color: $primary, $alpha: .8) { // 포커스 아웃라인 색상 및 투명도 설정 outline-offset: $offset; $transparent: 1 - $alpha; $focus-color: transparentize($color, $transparent); outline: 2px solid $focus-color; } // Flexbox 요소의 확대 및 축소 비율 설정 @mixin flex-size($shrink, $grow) { flex-shrink: $shrink; flex-grow: $grow; } // 버튼 스타일 초기화 믹스인 @mixin btn-reset { color: inherit; border: 0; background-color: inherit; &:hover, &:active { background-color: inherit; } } /* **** 영역 관련 믹스인 **** */ // 컬럼 설정 믹스인 (현재 비어 있음) @mixin columns($total, $num, $gutter) {} // 간격(Spacing) 설정 믹스인 @mixin spacer($num) { @for $i from 1 through $num { $key: $i; $value: ( $i * 4 * 0.1) + rem; // 기본 spacer 값 설정 $spacers: map-merge(($key: $value, ), $spacers) !global; } } // 테두리 둥근 정도(border-radius) 설정 믹스인 @mixin radius($num) { $border-radius: map-merge($num : ($num * 0.1) + rem, ), $border-radius } // 위치(position) 설정 믹스인 @mixin position($p: absolute, $t: null, $b: null, $l: null, $r: null) { position: $p; top: $t; bottom: $b; left: $l; right: $r; } // 가로와 세로 크기를 동일하게 설정하는 믹스인 @mixin foursquare($size) { width: $size; height: $size; } // 가상 요소(pseudo-element) 생성 시 사용 @mixin pseudo($c: null) { content: "#{$c}"; } // Flexbox 레이아웃 설정 믹스인 @mixin flex-layout($d: flex, $ai: flex-start, $jc: flex-start, $fd: row) { display: $d; align-items: $ai; justify-content: $jc; flex-direction: $fd; } // 그룹 요소를 감싸는 컨테이너 믹스인 @mixin group-wrap() { display: flex; flex-wrap: wrap; align-items: stretch; position: relative; width: 100%; } // 그룹 내 개별 요소 설정 믹스인 @mixin group() { flex: 1 1 auto; position: relative; width: 1%; min-width: 0; } // Flexbox 아이템이 동일한 너비를 갖도록 설정하는 믹스인 @mixin equal-width() { flex: 1 1 0px; min-width: 0; } // 요소를 중앙 정렬하는 믹스인 @mixin position-center($type) { @each $type in $position-type { // 좌우 중앙 정렬 @if ($type =='x') { left: 50%; transform: translateX(-50%) } // 상하 중앙 정렬 @else if ($type =='y') { top: 50%; transform: translateY(-50% ); } // 상하좌우 중앙 정렬 @else if ($type =='both') { left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); } } } // transform 기준점을 중앙으로 설정하는 믹스인 @mixin transform-origin($x: 50%, $y: 50%) { transform-origin: $x $y; } /* **** 텍스트 속성 ****/ // 텍스트 말줄임표 설정 (지정된 줄 수 만큼 텍스트를 줄여 표시) @mixin ellipsis($line) { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; -webkit-line-clamp: $line; } // 스크린 리더 전용 스타일 (화면에서 숨기고 접근성 유지) @mixin sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; } // 팝오버/툴팁 등의 텍스트 스타일 초기화 @mixin reset-text { font-family: var(--#{$prefix}-fz-body-md); font-style: normal; font-weight: map-get($fws, normal); line-height: $line-height-base; text-align: left; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; white-space: normal; word-spacing: normal; line-break: auto; } // CSS 애니메이션 가시성 설정 (hidden 또는 visible 값 사용) @mixin visibility($v) { @if ($v ==hidden) { visibility: hidden; z-index: -1; opacity: 0; } @else if ($v ==visible) { visibility: visible; z-index: auto; opacity: 1; } } /* **** 스크롤바 스타일 ****/ // 스크롤바 커스텀 스타일 @mixin scrollbar { &::-webkit-scrollbar { width: .8rem; } &::-webkit-scrollbar-thumb { background-color: var(--#{$prefix}gray-40); border-radius: .8rem; } &::-webkit-scrollbar-track { background-color: var(--#{$prefix}gray-30); } } /* **** 폰트 크기 설정 ****/ // 전역 폰트 크기 설정 (CSS 변수로 지정) @mixin fz() { @each $type, $size in map-get($font-size, 'sizes') { @each $key, $value in $size { --#{$prefix}fz-#{$type}-#{$key}: #{$value}; } } } /* **** 버튼 스타일 ****/ // 버튼 크기 및 스타일 설정 @mixin btn() { @each $type, $size in map-get($btns, 'setting') { @each $key, $value in $size { --#{$prefix}btn-#{$type}-#{$key}: #{$value}; // 높이별 버튼 클래스 추가 @if ($type =='h') { @at-root .btn.#{$key} { height: #{$value}; padding: 0 var(--#{$prefix}btn-px-#{$key}); border-radius: var(--#{$prefix}btn-rd-#{$key}); font-size: var(--#{$prefix}btn-fz-#{$key}); } } } } } /* **** 칩 버튼 스타일 ****/ // 칩 버튼 (outline 또는 fill 스타일 선택) @mixin btn-chip($name, $default) { // 아웃라인 스타일 칩 버튼 설정 @if ($name =='outline') { @each $type, $size in map-get($btnChipOutline, 'setting') { @each $key, $value in $size { --#{$prefix}btnChipOutline-#{$type}-#{$key}: #{$value}; // 높이별 칩 버튼 스타일 적용 @if ($type =='h') { @at-root .btn-chip-outline.#{$key} { height: var(--#{$prefix}btnChipOutline-h-#{$key}); padding: var(--#{$prefix}btnChipOutline-pd-#{$key}); border-radius: var(--#{$prefix}btnChipOutline-rd-#{$key}); font-size: var(--#{$prefix}btnChipOutline-fz-#{$key}); .btn-del { width: var(--#{$prefix}btnChipOutline-size-#{$key}); height: var(--#{$prefix}btnChipOutline-size-#{$key}); background: url(#{$url}/component/common/ico_chip_del.svg) no-repeat 0 0; background-size: contain; } } } // 기본 크기 설정 @if ($default) { @at-root .btn-chip-outline { height: var(--#{$prefix}btnChipOutline-h-#{$default}); padding: var(--#{$prefix}btnChipOutline-pd-#{$default}); border-radius: var(--#{$prefix}btnChipOutline-rd-#{$default}); font-size: var(--#{$prefix}btnChipOutline-fz-#{$default}); .btn-del { width: var(--#{$prefix}btnChipOutline-size-#{$default}); height: var(--#{$prefix}btnChipOutline-size-#{$default}); background: url(#{$url}/component/common/ico_chip_del.svg) no-repeat 0 0; background-size: contain; // 포커스 스타일 추가 &:focus { @include focus($offset: .4rem); } } } } } } } // 채워진 스타일 칩 버튼 설정 @else if ($name =='fill') { @each $type, $size in map-get($btnChipFill, 'setting') { @each $key, $value in $size { --#{$prefix}btnChipFill-#{$type}-#{$key}: #{$value}; // 높이별 칩 버튼 스타일 적용 @if ($type =='h') { @at-root .btn-chip-fill.#{$key} { height: var(--#{$prefix}btnChipFill-h-#{$key}); padding: var(--#{$prefix}btnChipFill-pd-#{$key}); border-radius: var(--#{$prefix}btnChipFill-rd-#{$key}); font-size: var(--#{$prefix}btnChipFill-fz-#{$key}); } } // 기본 크기 설정 @if ($default) { @at-root .btn-chip-fill { height: var(--#{$prefix}btnChipFill-h-#{$default}); padding: var(--#{$prefix}btnChipFill-pd-#{$default}); border-radius: var(--#{$prefix}btnChipFill-rd-#{$default}); font-size: var(--#{$prefix}btnChipFill-fz-#{$default}); // 포커스 스타일 추가 &:focus { @include focus($offset: .4rem); } } } } } } } /* **** form mixin ****/ // input 믹스인: 폼의 텍스트 입력 필드 스타일을 설정 @mixin input() { @each $type, $size in map-get($inputs, 'setting') { @each $key, $value in $size { --#{$prefix}input-#{$type}-#{$key}: #{$value}; @if ($type =='h') { //높이별 class값 추가 @at-root .form-control.#{$key} { height: #{$value}; padding: 0 var(--#{$prefix}input-px-#{$key}); border-radius: var(--#{$prefix}input-rd-#{$key}); font-size: var(--#{$prefix}input-fz-#{$key}); } } } } } // radio 믹스인: 라디오 버튼 스타일 설정 @mixin radio() { @each $type, $size in map-get($radios, 'setting') { @each $key, $value in $size { --#{$prefix}rdo-#{$type}-#{$key}: #{$value}; @if ($type =='size') { @at-root .form-check.#{$key} { >[type=radio] { ~label { font-size: var(--krds-rdo-fz-#{$key}); line-height: var(--krds-rdo-#{$type}-#{$key}); min-height: var(--krds-rdo-#{$type}-#{$key}); padding-left: calc(var(--krds-rdo-#{$type}-#{$key}) + var(--krds-spacer-2)); &::before { width: var(--#{$prefix}rdo-#{$type}-#{$key}); height: var(--#{$prefix}rdo-#{$type}-#{$key}); } &::after { top: calc((var(--#{$prefix}rdo-size-#{$key}) - var(--#{$prefix}rdo-chk-#{$key})) / 2); left: calc((var(--#{$prefix}rdo-size-#{$key}) - var(--#{$prefix}rdo-chk-#{$key})) / 2); width: var(--#{$prefix}rdo-chk-#{$key}); height: var(--#{$prefix}rdo-chk-#{$key}); } } } } } } } } // checkbox 믹스인: 체크박스 스타일 설정 @mixin chk() { @each $type, $size in map-get($checkboxes, 'setting') { @each $key, $value in $size { --#{$prefix}chk-#{$type}-#{$key}: #{$value}; @if ($type =='size') { @at-root .form-check.#{$key} { >[type=checkbox] { ~label { font-size: var(--krds-chk-fz-#{$key}); line-height: var(--krds-chk-#{$type}-#{$key}); min-height: var(--krds-chk-#{$type}-#{$key}); padding-left: calc(var(--krds-chk-#{$type}-#{$key}) + var(--krds-spacer-2)); &::before { width: var(--#{$prefix}chk-#{$type}-#{$key}); height: var(--#{$prefix}chk-#{$type}-#{$key}); } &::after { width: var(--#{$prefix}chk-primary-chk-#{$key}); height: var(--#{$prefix}chk-primary-chk-#{$key}); } } } &.ico-only { >[type=checkbox] { ~label { padding-left: var(--krds-chk-#{$type}-#{$key}); } } } } } } } } // select 믹스인: 셀렉트 박스 스타일 설정 @mixin select() { @each $type, $size in map-get($select, 'setting') { @each $key, $value in $size { --#{$prefix}select-#{$type}-#{$key}: #{$value}; @if ($type =='h') { //높이별 class값 추가 @at-root .form-select.#{$key} { height: #{$value}; padding: var(--#{$prefix}select-pd-#{$key}); border-radius: var(--#{$prefix}select-rd-#{$key}); font-size: var(--#{$prefix}select-fz-#{$key}); background-size: var(--#{$prefix}select-bgs-#{$key}); } } } } } // switch 믹스인: 스위치 컴포넌트 스타일 설정 @mixin switch() { @each $type, $size in map-get($switch, 'setting') { @each $key, $value in $size { --#{$prefix}switch-#{$type}-#{$key}: #{$value}; @if ($type =='w') { @at-root .form-switch.#{$key} { [type=checkbox] { ~i { &::before { width: var(--#{$prefix}switch-b-#{$key}); height: var(--#{$prefix}switch-b-#{$key}); border-radius: var(--#{$prefix}switch-rd-#{$key}); } &::after { width: var(--#{$prefix}switch-w-#{$key}); height: var(--#{$prefix}switch-h-#{$key}); } } ~label { $labelValue : var(--#{$prefix}switch-w-#{$key}); $pdValue : var(--#{$prefix}switch-pd-#{$key}); padding-left: calc($labelValue + $pdValue); margin-left: calc($labelValue * -1); font-size: var(--#{$prefix}switch-fz-#{$key}); } &:checked { ~i { &::before { $posL : calc(var(--#{$prefix}switch-w-#{$key}) - var(--#{$prefix}switch-b-#{$key}) - var(--#{$prefix}switch-br-#{$key})); @include position($l: $posL); } } } } } } } } } // form-chip 믹스인: 칩 형태의 선택 가능한 컴포넌트 스타일 설정 @mixin form-chip($name, $default) { @if ($name =='radio') { @each $type, $size in map-get($rdoChipOutline, 'setting') { @each $key, $value in $size { --#{$prefix}rdoChipOutline-#{$type}-#{$key}: #{$value}; @if ($type =='h') { @at-root .form-chip.#{$key} { .radio { ~.form-chip-outline { gap:var(--#{$prefix}chkChipOutline-gap-#{$key}); height: var(--#{$prefix}rdoChipOutline-h-#{$key}); padding: var(--#{$prefix}rdoChipOutline-pd-#{$key}); border-radius: var(--#{$prefix}rdoChipOutline-rd-#{$key}); font-size: var(--#{$prefix}rdoChipOutline-fz-#{$key}); &::before { width:var(--#{$prefix}chkChipOutline-ico-#{$key}); height:var(--#{$prefix}chkChipOutline-ico-#{$key}); background: url(#{$url}/component/common/ico_check_chip.svg) no-repeat 0 0; background-size: contain; } } &:checked { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_checked.svg); } } } &:disabled { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_disabled.svg); } } } } } } @if ($default) { @at-root .form-chip { .radio { ~.form-chip-outline { gap:var(--#{$prefix}chkChipOutline-gap-#{$key}); height: var(--#{$prefix}rdoChipOutline-h-#{$key}); padding: var(--#{$prefix}rdoChipOutline-pd-#{$key}); border-radius: var(--#{$prefix}rdoChipOutline-rd-#{$key}); font-size: var(--#{$prefix}rdoChipOutline-fz-#{$key}); &::before { width:var(--#{$prefix}chkChipOutline-ico-#{$key}); height:var(--#{$prefix}chkChipOutline-ico-#{$key}); background: url(#{$url}/component/common/ico_check_chip.svg) no-repeat 0 0; background-size: contain; } } &:checked { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_checked.svg); } } } &:disabled { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_disabled.svg); } } } } } } } } } @else if ($name =='checkbox') { @each $type, $size in map-get($chkChipOutline, 'setting') { @each $key, $value in $size { --#{$prefix}chkChipOutline-#{$type}-#{$key}: #{$value}; @if ($type =='h') { @at-root .form-chip.#{$key} { .checkbox { ~.form-chip-outline { gap:var(--#{$prefix}chkChipOutline-gap-#{$key}); height: var(--#{$prefix}chkChipOutline-h-#{$key}); padding: var(--#{$prefix}chkChipOutline-pd-#{$key}); border-radius: var(--#{$prefix}chkChipOutline-rd-#{$key}); font-size: var(--#{$prefix}chkChipOutline-fz-#{$key}); &::before { width:var(--#{$prefix}chkChipOutline-ico-#{$key}); height:var(--#{$prefix}chkChipOutline-ico-#{$key}); background: url(#{$url}/component/common/ico_check_chip.svg) no-repeat 0 0; background-size: contain; } } &:checked { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_checked.svg); } } } &:disabled { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_disabled.svg); } } } } } } @if ($default) { @at-root .form-chip { .checkbox { ~.form-chip-outline { gap:var(--#{$prefix}chkChipOutline-gap-#{$key}); height: var(--#{$prefix}chkChipOutline-h-#{$key}); padding: var(--#{$prefix}chkChipOutline-pd-#{$key}); border-radius: var(--#{$prefix}chkChipOutline-rd-#{$key}); font-size: var(--#{$prefix}chkChipOutline-fz-#{$key}); &::before { width:var(--#{$prefix}chkChipOutline-ico-#{$key}); height:var(--#{$prefix}chkChipOutline-ico-#{$key}); background: url(#{$url}/component/common/ico_check_chip.svg) no-repeat 0 0; background-size: contain; } } &:checked { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_checked.svg); } } } &:disabled { ~.form-chip-outline { &::before { background-image: url(#{$url}/component/common/ico_check_chip_disabled.svg); } } } } } } } } } } //tab setting @mixin tabs() { @each $type, $size in map-get($tabs, 'setting') { @each $key, $value in $size { --#{$prefix}tab-#{$type}-#{$key}: #{$value}; } } }