5월의 시작, 우연히 멘토이신 인제님께서 진행하는 오픈소스 스터디 모집 공고를 보게 되었다.
GDG 송도에서 오프라인으로만 진행하는 것 같아 인천에 사는 사람들을 부러워하고만 있었는데 온라인으로도 진행하는 걸 알게되어 '옳커니!'했다. 망설임 없이 지원서를 제출했고, 스터디에 참가할 수 있게 되었다.
그리고 드디어 오픈소스에 pr 하나를 만들 수 있게 되었다. (슬프게도 5일이 지난 시점에서 아직까지 merge가 되지 않고 있지만..흑흑)
먼저 스터디의 후기를 간략하게 말하자면, '정말 참여하길 잘했다'이다.
원래도 오픈소스 기여에 관심이 많았지만 엄두를 내지 못하고 있었는데, 이 스터디를 통해 그 장벽을 완전히 허물 수 있었다.
앞으로는 여러 오픈소스를 깔짝대며, 기여할 수 있을만한 재밌는 이슈를 찾아보고, 맘에 드는 이슈를 찾았다면 그 이슈를 해결하기 위해 해당 오픈소스를 자세히 파보는, 좋은 코드 공부도 하고 생태계에 기여도 하는 일타이피를 제대로 노리고 싶다.
이슈 선정에 있어서는 사실 멘토님의 도움을 많이 받았다. 멘토님이 공유해주신
이 아티클을 읽고 기여하고픈 여러 이슈를 선정해보긴 했지만, 멘토님이 처음에 추천해주신 이 이슈가 첫 기여를 하기에 간단해보였다. 따라서 최종적으로 이 이슈를 선택했다.
이슈에 대해 간략히 설명해보자면, 아래 코드와 같이 리액트 부트스트랩에서 모달을 사용할 때 다크 테마를 적용했더니,
mport { Button, Modal, ProgressBar } from "react-bootstrap";
function App() {
return (
<>
<Modal show data-bs-theme="dark">
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Simulator
</Modal.Title>
</Modal.Header>
<Modal.Body>
<ProgressBar animated now={45} />
</Modal.Body>
<Modal.Footer>
<Button onClick={() => {}}>Close</Button>
</Modal.Footer>
</Modal>
</>
);
}
export default App;
아래 처럼 모달 내부의 글자가 다크 테마에 맞게 흰색으로 적절히 보여지는 것이 아니라, 그대로 검은색으로 유지가 되는 것이 문제였다.

우리는 보통 다크 테마를 적용하면 아래와 같이 보일 것을 기대한다.

문제의 원인이 무엇인지를 밝혀내기 위해 코드를 내 로컬 환경으로 들고 와 뜯어보았다.
문제의 가장 원인은 분명히 css에 있을 것이라 생각해 개발자 도구를 통해 css를 탐구했다. 그렇게해서 가장 먼저 발견한 실마리는 '색상의 상속' 이었다.
리액트 부트스트랩에 부트스트랩의 스타일을 먹이기 위해서는 부트스트랩에서 제공해주는 css 파일을 사용해야 하고, 만약 그걸 적용할 경우 body 태그에 저절로 text color가 검은색 계열로 지정이 된다. 그리고 문제가 되는 모달 타이틀 컴포넌트에서는 color를 inherit 하고 있기 때문에, (bs theme이 dark인 경우에도) 즉, 특정 색을 선택하는게 아닌 부모로부터 색을 상속받고 있기 때문에, 저렇게 검은색으로 보이는 것 같다는 1차 결론을 내렸다.
body의 color를 white로 지정해주니 글씨가 원하는 대로 잘 보였다.
이것을 멘토님께 말씀드리니, '다양한 방법으로 data-bs-theme="dark"일떄 body color를 white로 설정해주는 방법이 있을거 같은데, 혹시 생각나시는 좋은 방법이 있을까요?' 라고 피드백을 주셨다.
이 피드백을 받고 나는 또 해결 방법을 모색해보았고, 몇 가지 방법을 발견해낼 수 있었다.
하나는 body 태그에 data-bs-them = dark 속성을 끼워넣어주는 것이었다. 그러나 이러면 주의해야할 게, 의도치 않게 다른 컴포넌트의 스타일링도 바뀔 수가 있어서 위험하다.
한가지 발견한 다른 방법은 bootstrap이 제공하는 css 파일을 수정하는 것이다. 혹시나 저렇게 타이틀이 까맣게 보이는 동작이 의도된 동작인가 싶어 css파일을 뜯어보니, data-bs-theme=dark일때, --bs-body-color(컴포넌트의 텍스트 색을 지정하는 변수)가 흰색 계열인 것을 보아 의도는 아닌 듯 했다. 따라서 첫번째 방법을 교훈 삼아 스코프를 좁혀 --bs-body-color가 흰색 계열로 지정되도록 하는 방법이 없을까 싶어 좀 더 자세히 살펴보니,
--bs-modal-color: ;
위처럼 modal 자체의 text color가 아예 지정되지 않은 모습을 발견할 수 있었다. 따라서 개발자 도구를 이용해 modal의 text color를 var(--bs-body-color)로 지정해주니, 흰색으로 잘 변경되는 것을 확인할 수 있었다.
즉, 문제의 원인은 완벽하게 리액트 부트스트랩이 아닌 부트스트랩의 css파일에 있던 것이었다.
그러나 modal 자체의 color를 저렇게 빈 상태로 둔 것이 의도한 것인지 아닌지는 저때까지는 잘 판단이 서지 않았다.
멘토님은 실수일 확률이 높다고 말씀하셨다. 오픈소스에는 생각보다 이런 허점이 많기 때문이다. 그래도 혹시 모르니 다른 컴포넌트에서는 text color 지정을 어떻게 하고 있는지를 살펴보라고 하셨고 나는 이것이 높은 확률로 실수임을 알아챌 수 있었다. 다른 컴포넌트 몇개를 검토해본 결과, 텍스트 컬러를 var(--bs-body-color)로 지정하고 있었기 때문이다.
문제의 원인을 찾았으니 본격적으로 문제를 해결 해 pr을 날릴 차례이다. 문제는 리액트 부트스트랩이 아니라 부트스트랩의 css파일에 있었으므로, 부트스트랩을 포크하고 클론했다.
그리고 머지 않아 부트스트랩은 scss를 사용하여 스타일을 지정한다는 것을 알았고, 모달의 스타일링이 문제이니 먼저 _modal.scss부터 살펴보았다.
.modal {
// scss-docs-start modal-css-vars
// ...
--#{$prefix}modal-color: #{$modal-content-color};
// ...
문제가 되는 부분을 바로 찾을 수 있었다. --bs-modal-color에 아무것도 지정이 되지 않은 이유는 #{$modal-content-color};에 뭔가 문제가 있기 때문일 것이다.
$modal-content-color는 _variables.scss에 존재했다. 그리고 무릎을 탁 쳤다.
$modal-content-color: null !default;
잡았다 요놈
왜 저걸 null로 지정했을까 의문이 들어서 이 코드를 생성한 가장 최근 커밋(작년도 아닌 그보다 더 오래전..)을 살펴보니 아마 확장성을 이유로 이렇게 둔 것 같았다. 다크 테마를 적용하는 기능은 비교적 최근에 생긴 것으로 아는데, 다크 테마를 만드는 과정에서 저 변수를 수정하는 것을 빼놓은 것 같다.
어쨌든 코드를 다음과 같이 수정했다.
$modal-content-color: var(--#{$prefix}body-color) !default;
이제 문제 없이 잘 작동할 것이다.
단 한 줄의 코드 수정이었지만 뿌듯했다. 적어도 다크 모드를 불편하게 사용해왔던 누군가에겐 괜찮은 수정이 아닐까 싶다.
이제 무사히 merge되기만을 기도한다..
1년간의 기다림끝에 머지되었네요 축하드려요!!