Storybook: μž‘μ—…μ„ 톡해 λ…ΈλΈŒ λ³€κ²½ [아이디어]

에 λ§Œλ“  2018λ…„ 07μ›” 09일  Β·  55μ½”λ©˜νŠΈ  Β·  좜처: storybookjs/storybook

λ‚˜λŠ” 이제 막 μŠ€ν† λ¦¬λΆμ„ μ‚¬μš©ν•˜κΈ° μ‹œμž‘ν–ˆκ³  μ§€κΈˆκΉŒμ§€ 그것을 μ’‹μ•„ν•©λ‹ˆλ‹€. λ‚΄κ°€ κ³ μ‹¬ν–ˆλ˜ ν•œ κ°€μ§€λŠ” λΆ€λͺ¨μ— μƒνƒœκ°€ ν¬ν•¨λ˜μ–΄μ•Ό ν•˜λŠ” μˆœμˆ˜ν•œ "μƒνƒœ λΉ„μ €μž₯" ꡬ성 μš”μ†Œλ₯Ό μ²˜λ¦¬ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ checked μ†Œν’ˆμ„ μ‚¬μš©ν•˜λŠ” ν™•μΈλž€μ΄ μžˆμŠ΅λ‹ˆλ‹€. μ²΄ν¬λ°•μŠ€λ₯Ό ν΄λ¦­ν•˜λ©΄ μƒνƒœκ°€ μ „ν™˜λ˜μ§€ μ•Šκ³  onChange κ°€ λ°œμƒν•˜κ³  μ—…λ°μ΄νŠΈλœ checked μ†Œν’ˆμ„ λ‹€μ‹œ 받을 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦½λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ’…λ₯˜μ˜ ꡬ성 μš”μ†Œλ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ λͺ¨λ²” 사둀에 λŒ€ν•œ λ¬Έμ„œλŠ” μ—†λŠ” 것 κ°™μœΌλ©° https://github.com/storybooks/storybook/issues/197 κ³Ό 같은 문제의 μ œμ•ˆμ€ 래퍼 ꡬ성 μš”μ†Œλ₯Ό μƒμ„±ν•˜κ±°λ‚˜ λ‹€λ₯Έ μΆ”κ°€ κΈ°λŠ₯을 μΆ”κ°€ν•˜μ‹­μ‹œμ˜€. κ°€λŠ₯ν•˜λ©΄ ꡬ성 μš”μ†Œ 래퍼λ₯Ό λ§Œλ“€μ§€ μ•ŠλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. λ‚΄ 이야기λ₯Ό κ°€λŠ₯ν•œ ν•œ λ‹¨μˆœν•˜κ²Œ μœ μ§€ν•˜κ³  μ‹ΆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

이 문제λ₯Ό μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” ν•œ 가지 μ•„μ΄λ””μ–΄λŠ” actions μ• λ“œμ˜¨μ„ knobs 와 μ—°κ²°ν•˜μ—¬ λ…ΈλΈŒλ₯Ό μž‘μ—…μ„ 톡해 ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ ν† κΈ€ν•  수 μžˆλ„λ‘ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‚΄κ°€ λ§ν–ˆλ“―μ΄ λ‚˜λŠ” λ™ν™”μ±…μ—μ„œ μ•„μ£Ό μƒˆλ‘œμš΄ κ²ƒμ΄λ―€λ‘œ 이것이 μ‹€ν˜„ κ°€λŠ₯ν•œμ§€ μ—¬λΆ€λŠ” λͺ¨λ₯΄μ§€λ§Œ 적어도 μ œμ•ˆμ„ μ œκΈ°ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

이것은 μŠ€ν† λ¦¬λ₯Ό κ΅¬ν˜„ν•˜λŠ” μ €μ—κ²Œ μžˆμ–΄ 걸림돌이며 λ‹€λ₯Έ μ‚¬λžŒλ“€μ—κ²Œλ„ λ§ˆμ°¬κ°€μ§€μΌ 거라고 μƒκ°ν•©λ‹ˆλ‹€. 래퍼 ꡬ성 μš”μ†Œλ₯Ό λ§Œλ“œλŠ” 것이 μ‹€μ œλ‘œ κ°€μž₯ 쒋은 방법이라면 이λ₯Ό λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•΄ λ¬Έμ„œλ₯Ό μΆ”κ°€ν•˜κ³  이λ₯Ό μˆ˜ν–‰ν•˜λŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

knobs feature request todo

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μš°λ¦¬λŠ” 5.3(1μ›” 초 릴리슀)을 거의 끝내고 6.0(3μ›” 말 릴리슀)에 λŒ€ν•œ λ…ΈλΈŒ μž¬μž‘μ„±μ„ μ‘°μ‚¬ν•˜μ—¬ μ—¬λŸ¬ 가지 였래된 λ…ΈλΈŒ 문제λ₯Ό ν•΄κ²°ν•  κ²ƒμž…λ‹ˆλ‹€. 이 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλŠ”μ§€ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€! κΈ°λ‹€λ € μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

λͺ¨λ“  55 λŒ“κΈ€

이 #3701 PR에 μœ μ‚¬ν•œ 아이디어가 λ„μž…λ˜μ–΄ λ…Όλž€μ΄ λ˜μ—ˆμŠ΅λ‹ˆλ‹€(ν†΅ν•©λ˜μ§€ μ•ŠμŒ).

이에 λŒ€ν•œ 토둠을 λ‹€μ‹œ μ—΄κ³  API μ œμ•ˆμ„ 듀을 수 μžˆμŠ΅λ‹ˆλ‹€ =).

μ•„ κ°μ‚¬ν•©λ‹ˆλ‹€, κ·Έ PR을 λ³Έ 적이 μ—†μŠ΅λ‹ˆλ‹€. @aherriot 에 κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€. 저희도 같은 생각을 ν•˜κ³  μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

API에 λ›°μ–΄λ“€κΈ° 전에 κΈ°λ³Έ κ°œλ…μ„ λ…Όμ˜ν•˜κ³  λ™μ˜ν•΄μ•Ό ν•  것 κ°™μŠ΅λ‹ˆλ‹€. PR의 의견 쀑 ν•˜λ‚˜λŠ” @Hypnosphi의 λ‹€μŒκ³Ό

λ‚˜λŠ” 그것이 μ§„μ‹€μ˜ μ—¬λŸ¬ μ†ŒμŠ€(ꡬ성 μš”μ†Œ 콜백 및 UI μ†μž‘μ΄)λ₯Ό λ„μž…ν•œλ‹€λŠ” 사싀을 μ’‹μ•„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

제 μƒκ°μ—λŠ” λ‹€μ–‘ν•œ 정보 μ†ŒμŠ€λ₯Ό λ„μž…ν•˜λŠ” 것이 μ•„λ‹ˆλΌ ꡬ성 μš”μ†Œ μƒνƒœ(λ…ΈλΈŒ)에 λŒ€ν•΄ _단일_ μ†ŒμŠ€λ₯Ό μœ μ§€ν•˜λ„λ‘ ν—ˆμš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. λ‚΄κ°€ μ œμ•ˆν•œ λ‹€λ₯Έ λͺ¨λ“  μ ‘κ·Ό 방식(래퍼 ꡬ성 μš”μ†Œ, μƒνƒœ μΆ”κ°€ κΈ°λŠ₯, μž¬κ΅¬μ„±)은 사싀 또 λ‹€λ₯Έ μ†ŒμŠ€λ₯Ό μ†Œκ°œν•©λ‹ˆλ‹€. λ‚΄ ν™•μΈλž€ μ˜ˆμ—μ„œλŠ” checked λŒ€ν•œ μ†μž‘μ΄λ₯Ό κ°€μ§ˆ 수 μ—†μœΌλ©° 래퍼 ꡬ성 μš”μ†Œκ°€ checked μ†Œν’ˆμ„ μ œκ³΅ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λ…ΈλΈŒ μ œμ–΄νŒμ„ ꡬ성 μš”μ†Œμ˜ λΆ€λͺ¨λ‘œ λ΄…λ‹ˆλ‹€. 단, ν˜„μž¬ ꡬ성 μš”μ†Œμ—μ„œ μ½œλ°±μ„ κ°€μ Έμ˜¬ 수 μ—†μŠ΅λ‹ˆλ‹€. μ΄λŠ” μΌμ’…μ˜ 일방적이고 λ°˜μ‘ 앱이 일반적으둜 λΉŒλ“œλ˜λŠ” 방식이 μ•„λ‹™λ‹ˆλ‹€.

λ…ΈλΈŒλ₯Ό ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ μ œμ–΄ν•  수 μžˆλ„λ‘ ν•¨μœΌλ‘œμ¨ μŠ€ν† λ¦¬λ₯Ό μ‹œμ—° 쀑인 ꡬ성 μš”μ†Œλ‘œλ§Œ 뢄리할 수 있으며, ν™•μΈλž€κ³Ό 같은 κ°„λ‹¨ν•œ ν”„λ ˆμ  ν…Œμ΄μ…˜ ꡬ성 μš”μ†Œμ˜ κ²½μš°μ™€ 같이 μ‹€μ œ μƒνƒœ 관리 λ©”μ»€λ‹ˆμ¦˜μ„ 뢈투λͺ…ν•˜κ²Œ 남길 수 μžˆμŠ΅λ‹ˆλ‹€. μ²΄ν¬λ°•μŠ€ μžμ²΄λŠ” propsλ₯Ό κ°€μ Έμ˜€λŠ” 방법을 μ‹ κ²½ 쓰지 μ•Šκ³ , redux에 연결될 수 있고, λΆ€λͺ¨κ°€ setState λ₯Ό μ‚¬μš©ν•  μˆ˜λ„ 있고, recomposeμ—μ„œ withState λ₯Ό μ‚¬μš©ν•  μˆ˜λ„ 있고, propsκ°€ λ‹€μŒμ— μ˜ν•΄ μ œμ–΄λ  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 동화책 μ†μž‘μ΄.

μ–΄μ¨Œλ“  λ‚΄κ°€ λ§ν–ˆλ“―μ΄ λ‚˜λŠ” 이것에 맀우 μ΅μˆ™ν•˜λ―€λ‘œ 직관적 인 생각 만 κ³΅μœ ν•©λ‹ˆλ‹€. λ‚΄κ°€ μ˜€ν”„λ² μ΄μŠ€μ΄κ³  μ΄λŸ¬ν•œ μ’…λ₯˜μ˜ μˆœμˆ˜ν•œ μƒνƒœ λΉ„μ €μž₯ ꡬ성 μš”μ†Œλ₯Ό μ²˜λ¦¬ν•˜λŠ” 데 일반적으둜 μΈμ •λ˜λŠ” "λͺ¨λ²” 사둀"κ°€ μžˆλŠ” 경우 λˆ„κ΅°κ°€ λ‚΄κ°€ λ”°λ₯Ό 수 μžˆλŠ” 쒋은 예λ₯Ό μ•Œλ €μ€„ 수 μžˆμŠ΅λ‹ˆκΉŒ?

μ•ˆλ…•ν•˜μ„Έμš” :)

μΆ”κ°€ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ‚΄ ꡬ성 μš”μ†Œκ°€ μ†Œν’ˆμ—μ„œ λͺ¨λ°”일 λ ˆμ΄μ•„μ›ƒμ„ ν‘œμ‹œν•΄μ•Ό ν•˜λŠ”μ§€(λ˜λŠ” ν‘œμ‹œν•˜μ§€ μ•Šμ•„μ•Ό ν•˜λŠ”μ§€) μˆ˜μ‹ ν•  λ•Œ μš°μ—°νžˆ λ°œκ²¬ν–ˆμœΌλ©°, λ‚΄ λͺ©ν‘œλŠ” 뷰포트 λ³€κ²½ 사항을 λ‚΄ λ…ΈλΈŒμ— λ¬ΆλŠ” κ²ƒμ΄μ—ˆκ³  정말 μ’‹μ•˜μ„ κ²ƒμž…λ‹ˆλ‹€ ;)

여기에 λ‚΄ μ‚¬μš© 사둀λ₯Ό μΆ”κ°€ν•˜κ³  μ‹Άμ—ˆκ³  @IanVS 처럼 μ½œλ°±λ„ μ’‹μ•˜μ„ κ²ƒμž…λ‹ˆλ‹€(λ”°λΌμ„œ isMobile μ†Œν’ˆμ„ ν† κΈ€ν•˜λ©΄ 뷰포트 변경을 νŠΈλ¦¬κ±°ν•  수 있음)

μ—¬λŸ¬ μ‚¬λžŒλ“€μ΄ μ†μž‘μ΄ μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” 방법에 관심을 ν‘œλͺ…ν•œλ‹€κ³  λ“€μ—ˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬κ°€ 쒋은 μ•„ν‚€ν…μ²˜μ— λŒ€ν•΄ λ™μ˜ν•  수 μžˆλ‹€λ©΄ 이것이 λ§Žμ€ μ‚¬λžŒλ“€μ—κ²Œ κ°€μΉ˜κ°€ μžˆμ„ 것이라고 μƒκ°ν•©λ‹ˆλ‹€. 특히 이것은 μ‚¬λžŒλ“€μ΄ μ‚¬μš© μ—¬λΆ€λ₯Ό 선택할 수 μžˆλŠ” μΆ”κ°€ κΈ°λŠ₯이고 μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ €λŠ” μ‚¬λžŒλ“€μ—κ²Œ 뢀정적인 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

@Hypnosphi , 이전 κ΅¬ν˜„μΈ WDYT에 λŒ€ν•΄ μ΄μ˜κ°€ μžˆμœΌμ…¨λ‚˜μš”?

이 문제λ₯Ό 계속 κ³΅κ°œν•˜λ €λ©΄ μ—¬κΈ°μ—μ„œ λŒ“κΈ€μ„ μž‘μ„±ν•˜μ„Έμš”. λ‚˜λŠ” μ—¬μ „νžˆ @Hypnosphi κ°€ 이전에 μ—¬κΈ°μ—μ„œ μ œμ•ˆν•œ @igor-dv에 λŒ€ν•΄ 무엇이라고 λ§ν–ˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

제 μƒκ°μ—λŠ” λ‹€μ–‘ν•œ 정보 μ†ŒμŠ€λ₯Ό λ„μž…ν•˜λŠ” 것이 μ•„λ‹ˆλΌ ꡬ성 μš”μ†Œ μƒνƒœμ— λŒ€ν•œ 단일 정보 μ†ŒμŠ€(λ…ΈλΈŒ)λ₯Ό μœ μ§€ν•˜λ„λ‘ ν—ˆμš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. λ‚΄κ°€ μ œμ•ˆν•œ λ‹€λ₯Έ λͺ¨λ“  μ ‘κ·Ό 방식(래퍼 ꡬ성 μš”μ†Œ, μƒνƒœ μΆ”κ°€ κΈ°λŠ₯, μž¬κ΅¬μ„±)은 사싀 또 λ‹€λ₯Έ μ†ŒμŠ€λ₯Ό μ†Œκ°œν•©λ‹ˆλ‹€. λ‚΄ μ²΄ν¬λ°•μŠ€ μ˜ˆμ œμ—μ„œλŠ” 체크된 λ…ΈλΈŒλ₯Ό κ°€μ§ˆ 수 μ—†μœΌλ©° 래퍼 ꡬ성 μš”μ†Œκ°€ 체크된 μ†Œν’ˆμ„ μ œκ³΅ν•˜λ„λ‘ ν—ˆμš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λ…ΈλΈŒ μ œμ–΄νŒμ„ ꡬ성 μš”μ†Œμ˜ λΆ€λͺ¨λ‘œ λ΄…λ‹ˆλ‹€. 단, ν˜„μž¬ ꡬ성 μš”μ†Œμ—μ„œ μ½œλ°±μ„ κ°€μ Έμ˜¬ 수 μ—†μŠ΅λ‹ˆλ‹€. μ΄λŠ” μΌμ’…μ˜ 일방적이고 λ°˜μ‘ 앱이 일반적으둜 λΉŒλ“œλ˜λŠ” 방식이 μ•„λ‹™λ‹ˆλ‹€.

λ‚˜μ—κ²Œ ν•©λ¦¬μ μœΌλ‘œ λ“€λ¦°λ‹€. API에 λŒ€ν•΄ λ…Όμ˜ν•˜μž

이것은 ν›Œλ₯­ν•œ κΈ°λŠ₯이 될 κ²ƒμž…λ‹ˆλ‹€. λ‚˜λŠ” 맀우 기본적인 μ œμ–΄ ꡬ성 μš”μ†Œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ—¬κΈ°μ—μ„œ 이와 λ™μΌν•œ μš”κ΅¬ 사항에 μ§λ©΄ν–ˆμœΌλ©° λ‹€λ₯Έ ꡬ성 μš”μ†Œμ—μ„œλ„ 이전에 μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. λ΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

ν˜„μž¬ ꡬ문을 λ”°λΌκ°€λŠ” 것은 μ•½κ°„μ˜ λ„μ „μ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. μ•„λ§ˆλ„ λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const {value: name, change: setName} = text('Name', 'Kent');

@brunoreis , μ†μž‘μ΄μ˜ λ°˜ν™˜ μ„œλͺ…을 λ³€κ²½ν•˜λŠ” 것이 μ£Όμš” λ³€κ²½ 사항이

import {boolean, changeBoolean} from '@storybook/addon-knobs/react';

stories.add('custom checkbox', () => (
    <MyCheckbox
        checked={boolean('checked', false)}
        onChange={(isChecked) => changeBoolean('checked', isChecked)} />
));

onChange 콜백이 컀링을 ν—ˆμš©ν•  μˆ˜λ„ μžˆμœΌλ―€λ‘œ λ‹€μŒλ„ μž‘λ™ν•©λ‹ˆλ‹€.

onChange={(isChecked) => changeBoolean('checked')(isChecked)}

// which of course simplifies down to
onChange={changeBoolean('checked')}

μ€‘μš”ν•œ 뢀뢄은 첫 번째 μΈμˆ˜κ°€ λ³€κ²½ν•΄μ•Ό ν•˜λŠ” λ…ΈλΈŒμ˜ λ ˆμ΄λΈ”κ³Ό κ°™μ•„μ•Ό ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이λ₯Ό 톡해 μ‚¬μš©μžλŠ” ν˜„μž¬ λ…ΈλΈŒκ°€ μ‚¬μš©λ˜λŠ” 방식을 λ³€κ²½ν•˜μ§€ μ•Šκ³ λ„ 이 λ™μž‘μ„ 선택할 수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. (라벨이 ν˜„μž¬ κ³ μœ ν•  ν•„μš”κ°€ μ—†λŠ” κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄? μ•„λ§ˆλ„...)

@IanVS , λ©‹μ§€λ„€μš”. μž‘λ™ 방식을 λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점에 λ™μ˜ν•©λ‹ˆλ‹€. λ ˆμ΄λΈ”μ„ ν‚€λ‘œ μ‚¬μš©ν•  생각을 ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 방법을 찾지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. νš¨κ³Όκ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. @Hypnosphi κ°€ 무엇을 염두에 두고 μžˆλŠ”μ§€ λ΄…μ‹œλ‹€.

λ…ΈλΈŒμ˜ λ°˜ν™˜ μ„œλͺ…을 λ³€κ²½ν•˜λŠ” 것은 μ£Όμš” λ³€κ²½ μ‚¬ν•­μž…λ‹ˆλ‹€.

기술적으둜 μ§€κΈˆμ€ λ¬Έμ œκ°€ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 곧 μ£Όμš” λ¦΄λ¦¬μŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ‹€μ œλ‘œ 일뢀 ν•˜μœ„ ν˜Έν™˜μ„±μ„ ν—ˆμš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 카레 μ§€μ›μ˜ 아이디어λ₯Ό μ’‹μ•„ν•©λ‹ˆλ‹€.

λ ˆμ΄λΈ”μ΄ ν˜„μž¬ κ³ μœ ν•  ν•„μš”κ°€ μ—†λŠ” κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄?

예, μ‹€μ œλ‘œλŠ” λ‹€μ–‘ν•œ μœ ν˜•μ—μ„œ κ³ μœ ν•©λ‹ˆλ‹€. λ”°λΌμ„œ λ³„λ„μ˜ change<Type> 내보내기가 ν•„μš”ν•˜μ§€ μ•ŠμœΌλ©° change 이면 μΆ©λΆ„ν•©λ‹ˆλ‹€. 기본적으둜 https://github.com/storybooks/storybook/pull/3701 μ—μ„œ λ§Œλ“  κ²ƒμž…λ‹ˆλ‹€.
@aherriot 이 κ·€ν•˜μ˜ λ„μ›€μœΌλ‘œ μ™„λ£Œν•  수 μžˆλ„λ‘ ν•΄λ‹Ή PR을 λ‹€μ‹œ μ—΄κ² μŠ΅λ‹ˆλ‹€.

μš°λ¦¬λŠ” 이것을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€:

const {value: name, change: setName} = text('Name', 'Kent');

text 의 λ°˜ν™˜ μœ ν˜•μ„ λ³€κ²½ν•  ν•„μš” 없이

Javascript ν•¨μˆ˜λŠ” κ°μ²΄μ΄λ―€λ‘œ 속성을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
개체λ₯Ό ꡬ쑰화할 수 μžˆμŠ΅λ‹ˆλ‹€.

screen shot 2018-09-19 at 00 08 35

@ndelangen text ν•¨μˆ˜λŠ” μ‹€μ œλ‘œ κ°œμ²΄μ΄μ§€λ§Œ λ°˜ν™˜ 값은 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€. 이것은 κ·€ν•˜μ˜ μ˜ˆμ—μ„œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

const { foo, bar } = x() // note the parens

μš°λ¦¬λŠ” λ‹€μŒκ³Ό 같은 것을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€(이름은 λ…ΌμŸμ˜ 여지가 μžˆμŠ΅λ‹ˆλ‹€):

const {value: name, change: setName} = text.mutable('Name', 'Kent');

μ™œ 이것이 μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆκΉŒ?

const { foo, bar } = x() // note the parens

x의 λ°˜ν™˜μ€ 속성도 κ°€μ§ˆ 수 μžˆλŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

screen shot 2018-09-23 at 14 12 28

λ‚˜λŠ” λ‹Ήμ‹ μ˜ μ›λž˜ μ˜ˆμ—μ„œ x = () => {} 에 λŒ€ν•΄ μ΄μ•ΌκΈ°ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

text κ°€ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ ν•˜λ©΄ μ‚¬μš©μžλŠ” μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•©λ‹ˆλ‹€.

// Before
<Foo bar={text('Bar', '')}>

// After
<Foo bar={text('Bar', '')()}>
                         ^^ this

μ•Œ κ² μ–΄μš”

이에 λŒ€ν•œ @IanVS μ œμ•ˆμ€

이 κΈ°λŠ₯이 있으면 쒋을 κ²ƒμž…λ‹ˆλ‹€.

"react hooks"와 같은 "destruct"λŠ” μ–΄λ–»μŠ΅λ‹ˆκΉŒ?

const [foo, setFoo] = useString('foo', 'default');

@DimaRGB와 같은 말을 ν•˜λŸ¬ μ™”μŠ΅λ‹ˆλ‹€.
κΈ°μ‘΄ ꡬ문을 μœ μ§€ν•˜κ³  후크와 μœ μ‚¬ν•œ ν˜ΈμΆœμ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

.add('example', () => {
  const [selected, setSelected] = useBool(false);

  return <SomeComponent selected={selected} onSelected={setSelected} />
})

λ°˜μ‘ ꡬ성 μš”μ†Œκ°€ 자체 props λ₯Ό μ—…λ°μ΄νŠΈν•΄μ•Ό ν•˜λŠ” 것이 μ•„λ‹ˆλΌ λΆ€λͺ¨μ—κ²Œ λ³€κ²½ν•΄μ•Ό ν•œλ‹€κ³  μ•Œλ¦¬λŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€. λ•Œλ‘œλŠ” ꡬ성 μš”μ†Œμ— μ†Œν’ˆμ„ ν† κΈ€ν•΄μ•Ό ν•˜λŠ” 일뢀 μš”μ†Œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€(λ•Œλ‘œλŠ” ν•˜μœ„ μš”μ†Œλ₯Ό ν΄λ¦­ν•˜λ©΄ λ‚΄κ°€ 가지고 μžˆλŠ” 탐색 λͺ¨μŒ 메뉴λ₯Ό μ—΄μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— 이 λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€).

@IanVS λ‚˜λŠ” λΆ€λͺ¨ μ†Œν’ˆμ„ ν†΅ν•΄μ„œλ§Œ μ—…λ°μ΄νŠΈλ˜λŠ” ν† κΈ€ ꡬ성 μš”μ†Œκ°€ 있고 μŠ€ν† λ¦¬ 뢁 μŠ€ν† λ¦¬μ˜ μ‚¬μš©μžκ°€ ν† κΈ€ν•˜λ©΄ UI μƒνƒœκ°€ λ…ΈλΈŒ νŒ¨λ„μ— ν‘œμ‹œλœ 것과 μΌμΉ˜ν•˜μ§€ μ•ŠλŠ” 상황이 μžˆμŠ΅λ‹ˆλ‹€. @storybook/addons-knobs 의 개인 방법을 μ‚¬μš©ν•˜μ—¬ ν•΄ν‚Ήν–ˆμŠ΅λ‹ˆλ‹€. 더 κ°„λ‹¨ν•œ μ œμ•ˆμ€ λ‹€μŒκ³Ό 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 곡식 APIλ₯Ό μ œκ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

import { manager } from '@storybook/addons-knob/dist/registerKnobs.js'

const { knobStore } = manager
// The name given to your knob - i.e:  `select("Checked", options, defaultValue)`
knobStore.store['Checked'].value = newValue
// Danger zone! _mayCallChannel() triggers a re-render of the _whole_ knobs form.
manager._mayCallChannel()

@erickwilder κ·€ν•˜μ˜ μ ‘κ·Ό 방식을 μ‹œλ„ν–ˆμ§€λ§Œ λ…ΈλΈŒ 양식을 μ—…λ°μ΄νŠΈν•˜μ§€ μ•ŠλŠ” 것 κ°™μ•˜μŠ΅λ‹ˆλ‹€(ꡬ성 μš”μ†Œμ— 제곡된 μ†Œν’ˆμ„ μ—…λ°μ΄νŠΈν•œ κ²½μš°μ—λ„).

νŽΈμ§‘ν•˜λ‹€:

긁닀; λ‚˜λŠ” λΆ„λͺ…νžˆ 'μ œμ–΄λ˜μ§€ μ•ŠλŠ”'λ°©μ‹μœΌλ‘œ μž‘λ™ν•˜λŠ” ν™•μΈλž€κ³Ό ν•¨κ»˜ options()λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ—ˆκΈ° λ•Œλ¬Έμ— μ—…λ°μ΄νŠΈλ₯Ό 보지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. 닀쀑 μ„ νƒμœΌλ‘œ μ „ν™˜ν•˜κ³  μ½œλ°±μ—μ„œ 이 방법을 μ‚¬μš©ν•˜μ—¬ μ—…λ°μ΄νŠΈλœ 값을 λ…ΈλΈŒ ν˜•μ‹μœΌλ‘œ κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.

// Ditch when https://github.com/storybooks/storybook/issues/3855 gets resolved properly.
function FixMeKnobUpdate(name, value) {
    addons.getChannel().emit(CHANGE, { name, value });
}

λ‚΄ μ„€μ •μ˜ 일뢀 μ„ΈλΆ€ 사항을 μƒλž΅ν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • Storybookκ³Ό ν•¨κ»˜ Vue.jsλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • 값을 λ³€κ²½ν•˜κ³  λ‹€μ‹œ λ Œλ”λ§μ„ νŠΈλ¦¬κ±°ν•˜λŠ” μ½”λ“œλŠ” μŠ€ν† λ¦¬ λž˜ν•‘ ꡬ성 μš”μ†ŒμΈ 경우 λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μˆ˜ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬ν•œ μ ‘κ·Ό 방식이 λͺ¨λ“  μ‚¬λžŒμ—κ²Œ νš¨κ³Όκ°€ μžˆμ„μ§€ λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

@IanVS에 μ „μ μœΌλ‘œ λ™μ˜ν•©λ‹ˆλ‹€. μ €λŠ” μŠ€ν† λ¦¬λΆμ„ μ’‹μ•„ν•˜μ§€λ§Œ μ•‘μ…˜μ„ 톡해 λ…ΈλΈŒλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” κΈ°λŠ₯이 정말 κ·Έλ¦¬μ›Œμš”. 제 κ²½μš°μ—λŠ” 두 개의 κ°œλ³„ ꡬ성 μš”μ†Œ A와 Bκ°€ μžˆμ§€λ§Œ 제 이야기 쀑 ν•˜λ‚˜μ—μ„œλŠ” 두 ꡬ성 μš”μ†Œλ₯Ό λͺ¨λ‘ μ‚¬μš©ν•˜μ—¬ ꡬ성을 보여주고 μ‹ΆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ AIλ₯Ό λ³€κ²½ν•  λ•Œλ§ˆλ‹€ Bλ₯Ό μˆ˜μ •ν•˜κ³  κ·Έ λ°˜λŒ€λ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.

λ‚΄ μ„€μ •(Angular 7)으둜 @erickwilder 의 해킹을 μ‹œλ„ν–ˆμ§€λ§Œ λ…ΈλΈŒ μ €μž₯μ†Œλ₯Ό μ—…λ°μ΄νŠΈν•˜λ €κ³  ν•  λ•Œλ§ˆλ‹€ λ‹€μŒ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

였λ₯˜: Angular Zone에 없을 κ²ƒμœΌλ‘œ μ˜ˆμƒλ˜μ§€λ§Œ μ‹€μ œλ‘œ μžˆμŠ΅λ‹ˆλ‹€!

μ–΄λ–»κ²Œλ“  이것을 Angular μ™ΈλΆ€μ—μ„œ μ‹€ν–‰ν•˜λ €κ³  μ‹œλ„ν–ˆμ§€λ§Œ ν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€... μ΅œμ•…μ˜ μ‹œλ‚˜λ¦¬μ˜€μ—μ„œλŠ” A와 B의 λž˜νΌκ°€ 될 μ„Έ 번째 ꡬ성 μš”μ†Œ Cλ₯Ό λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€.

이 (λ°˜μ‘, 각도, VUE, 아무것도)ν•˜μ§€λ§Œ λ…ΈλΈŒ λΆ€κ°€ κΈ°λŠ₯의 λ‹€μ‹œ λ Œλ”λ§μ— ν”„λ ˆμž„ μ›Œν¬ / λΌμ΄λΈŒλŸ¬λ¦¬μ— κ΄€λ ¨λ˜μ§€ μ•ŠλŠ” @davidolivefarga @erickwilderμ—μ„œ μž„μ‹œ λ°©νŽΈμ€ ν”„λ ˆμž„ μ›Œν¬μ— λŒ€ν•΄ μž‘λ™ν•©λ‹ˆλ‹€.

μœ„μ—μ„œ μ–ΈκΈ‰

+1은 λ…ΈλΈŒ 이름을 μ—…λ°μ΄νŠΈν•  λ¬Έμžμ—΄λ‘œ ν¬ν•¨ν•˜κ³  μƒˆ 값을 ν¬ν•¨ν•˜λŠ” νŠΈλ¦¬κ±°μ— 곡개적으둜 ν‘œμ‹œλ˜λŠ” λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

import { manager } from "@storybook/addon-knobs"

manager.updateKnob(
  propName, // knobs property, example from above "Checked"
  newValue, // new value to set programmatically, ex. true
)

λ‚˜λŠ” 이것이 κ³΅μ‹μ μœΌλ‘œ μ§€μ›λ˜κΈ°λ₯Ό μ •λ§λ‘œ μ›ν•©λ‹ˆλ‹€.

κ·Έ λ™μ•ˆ Storybook v5λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μŒκ³Ό 같은 λ”μ°ν•œ ν•΄ν‚€ μ†”λ£¨μ…˜μ„ μ‚¬μš©ν•΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€.

window.__STORYBOOK_ADDONS.channel.emit('storybookjs/knobs/change', {
  name: 'The name of my knob',
  value: 'the_new_value'
})

πŸ™ˆ

πŸ™ˆ

κ΄€λ ¨: #6916

이것은 λ©‹μ§ˆ κ²ƒμž…λ‹ˆλ‹€ ... 특히 λͺ¨λ‹¬ λ•Œλ¬Έμž…λ‹ˆλ‹€.

λ‚˜λŠ” 이것이 μœ μš©ν•  것이라고 μƒκ°ν•œλ‹€.

μ˜ˆμ‹œ:

storiesOf('input', module)
  .addDecorator(withKnobs)
  .add('default', () => <input type={text('type', 'text')} value={text('value', '')} disabled={boolean('disabled', false)} placeholder={text('placeholder', '')} onChange={action('onChange')} />)

이것은 ν˜„μž¬ μž‘λ™ν•˜μ§€λ§Œ ν…ŒμŠ€νŠΈλœ μš”μ†Œμ˜ props에 μ„€μ •λœ 값에 onChange 이벀트 λŒ€μƒ 값을 μ—°κ²°ν•˜λ €λŠ” 것이 λ‹Ήμ—°ν•΄ λ³΄μž…λ‹ˆλ‹€. 이것은 μš”μ†Œμ˜ μ μš©μ„ 더 잘 보여쀄 κ²ƒμž…λ‹ˆλ‹€.

이것은 유용 ν•  κ²ƒμž…λ‹ˆλ‹€

μ—¬κΈ°μ—μ„œ μ†”λ£¨μ…˜μ„ κ°€λ¦¬ν‚€λŠ” @mathieuk/ @raspo 에 +1.

μš°λ¦¬λŠ” 잠재적으둜 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œλ„ 이것에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. helpers λͺ¨λ“ˆμ—μ„œ λͺ‡ 가지 일반 λ©”μ„œλ“œλ₯Ό μƒμ„±ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?

import addons from "@storybook/addons";

export const emitter = (type, options) => addons.getChannel().emit(type, options);

export const updateKnob = (name, value) => (
  emitter("storybookjs/knobs/change", { name, value })
);

그리고 μ΄μ•ΌκΈ°μ—μ„œ ν•„μš”μ— 따라 μ „ν™”...

import { text } from "@storybook/addon-knobs";
import { updateKnob } from 'helpers';

// ...
const value = text("value", "Initial value");
<select
  value={value}
  onChange={({ target }) => updateKnob("value", target.value)}
>

...ν•˜μ§€λ§Œ μ—¬μ „νžˆ λ…ΈλΈŒ API에 λ‚΄μž₯될 수 μžˆλŠ” 무언가에 λŒ€ν•œ νŽ‘ν‚€ν•œ μ–‘λ°©ν–₯ 바인딩 ν•΄κ²° λ°©λ²•μ²˜λŸΌ λŠκ»΄μ§‘λ‹ˆλ‹€.

μœ„μ˜ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ? 맀우 μœ μš©ν•œ κΈ°λŠ₯이 될 κ²ƒμž…λ‹ˆλ‹€ πŸ‘

κ΅¬ν˜„λ˜λŠ” 이 κΈ°λŠ₯을 μ‚¬μš©ν•˜λ©΄ 맀우 κ°•λ ₯ν•œ μƒν˜Έ 쒅속 λ…ΈλΈŒλ₯Ό μ•„μ£Ό μ‰½κ²Œ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μŠ€ν† λ¦¬μ—μ„œ λ‹€μŒκ³Ό 같이 ν•˜λ‚˜μ˜ λ…ΈλΈŒκ°€ λ‹€λ₯Έ λ…ΈλΈŒμ— 따라 λ™μ μœΌλ‘œ μ—…λ°μ΄νŠΈλ˜λ„λ‘ ν•  수 μžˆλ‹€λ©΄ νŽ˜μ΄μ§€ 맀김 ꡬ성 μš”μ†Œ μŠ€ν† λ¦¬λ₯Ό λ§Œλ“œλŠ” 것을 상상해 λ³΄μ‹­μ‹œμ˜€.

const resultsCount = number(
    'Results count',
    currentPage, {
        max: 100,
        min: 0,
        range: true
    }
);
const resultsArray: React.ReactNode[] = new Array(resultsCount)
    .fill(true)
    .map((_, idx) => <div key={idx + 1}>Test Pagination Result #{idx + 1}</div>);
const childrenPerPage = 10;
const currentPage = number(
    'Current page index',
    0, {
        max: Math.ceil(resultsCount / childrenPerPage) - 1,
        min: 0,
        range: true
    }
);

기본적으둜 currentPage λ…ΈλΈŒμ˜ μ΅œλŒ€ λ²”μœ„κ°€ resultsCount λ…ΈλΈŒλ₯Ό 10μ”© μ¦κ°€μ‹œν‚¬ λ•Œ λ™μ μœΌλ‘œ μ—…λ°μ΄νŠΈλ˜κΈ°λ₯Ό ν¬λ§ν•˜λ©΄μ„œ 이 μž‘μ—…μ„ μ‹œλ„ν–ˆμ§€λ§Œ 각 λ…ΈλΈŒμ˜ 초기 κ°’μœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. 생성 μ‹œ μΊμ‹œλ˜κ³  후속 λ Œλ”λ§μ—μ„œ λ‚΄λΆ€ μƒνƒœ 값을 μž¬μ •μ˜ν•˜λŠ” 데 μ‚¬μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚˜λŠ”μ΄ 증가 ν•  λ•Œ μœ„μ˜ μ½”λ“œλ‘œ resultsCount λ‚΄κ°€ κΈ°λŒ€ 10+에 μ˜ν•΄ max 의 currentPage κΈ°λ³Έ 값에도 λΆˆκ΅¬ν•˜κ³ , λ˜ν•œ 1 증가 ν• μ„ν•˜μ§€λ§Œ κ·Έ κ°€μΉ˜μ˜ μˆ™λ°• 동일 λ³€κ²½λœ 값을 κ³„μ‚°ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€( Math.ceil(resultsCount / childrenPerPage) - 1 λ‘œκΉ…μ€ μ˜ˆμƒλ˜λŠ” μƒˆ 값을 λ³΄μ—¬μ€λ‹ˆλ‹€).

μš°λ¦¬λŠ” 5.3(1μ›” 초 릴리슀)을 거의 끝내고 6.0(3μ›” 말 릴리슀)에 λŒ€ν•œ λ…ΈλΈŒ μž¬μž‘μ„±μ„ μ‘°μ‚¬ν•˜μ—¬ μ—¬λŸ¬ 가지 였래된 λ…ΈλΈŒ 문제λ₯Ό ν•΄κ²°ν•  κ²ƒμž…λ‹ˆλ‹€. 이 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλŠ”μ§€ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€! κΈ°λ‹€λ € μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

@shilman 이 κΈ°λŠ₯에 λŒ€ν•΄ 맀우 κΈ°λŒ€ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€ πŸ˜„

μ €, @atanasster & @PlayMa256 은 이λ₯Ό μœ„ν•œ κΈ°λ°˜μ„ ν•œλ™μ•ˆ μž‘μ—…ν•΄ μ™”μŠ΅λ‹ˆλ‹€. μ œλŒ€λ‘œ ν•˜λ €λ©΄ λͺ‡ 번 더 λ°˜λ³΅ν•΄μ•Ό ν•˜μ§€λ§Œ 6.0.0μ—μ„œ 100%λ₯Ό λ‹¬μ„±ν•˜κ³  μŠ€ν† λ¦¬λΆμ˜ 데이터 및 λ°˜μ‘μ„±μ— 혁λͺ…을 μΌμœΌν‚¬ 수 μžˆλ‹€κ³  맀우 ν™•μ‹ ν•©λ‹ˆλ‹€.

혁λͺ…을 μΌμœΌν‚€λ‹€? 뜨거운 망할 digity. 그만 놀렀, λ‚΄ λͺΈμ€ 쀀비됐어

λͺ¨λ‹¬μ˜ 경우 +1 :)

μ²˜μŒλΆ€ν„° λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 것이 믿기지 μ•ŠμŠ΅λ‹ˆλ‹€. μ—…λ°μ΄νŠΈλ₯Ό κΈ°λ‹€λ¦¬λŠ” 쀑...

μ•ˆλ…• μ—¬λŸ¬λΆ„!
μž„μ‹œ μ†”λ£¨μ…˜μœΌλ‘œ λ‚΄ μ•± λ‹€μŒ μ½”λ“œμ—μ„œ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

import { addons } from '@storybook/addons';
import { CHANGE } from '@storybook/addon-knobs';

const channel = addons.getChannel();

channel.emit(CHANGE, {
  name: 'prop_name',
  value: prop_value,
});

아직 이 κΈ°λŠ₯이 기본적으둜 κ΅¬ν˜„λ˜κΈ°λ₯Ό 기닀리고 μžˆμŠ΅λ‹ˆλ‹€.

Observable을 μ‚¬μš©ν•˜μ—¬ κ·Έ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” Angular와 ν•¨κ»˜ μŠ€ν† λ¦¬ 뢁을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

`
.add('차트 데이터 μ—…λ°μ΄νŠΈ 쀑', () => {

const myObservable= new BehaviorSubject([{a: 'a', b: 'b'}]);
return {
  template: '
  <my-component
    myInput: myData,
    (myEvent)="myEventProp($event)"
  ></my-component>
  ',
  props: {
    myData: myObservable,
    myEventProp: $event => {
      myObservable.next([]);
      action('(myEvent)')($event);
    }
  }
};

})
`

@norbert-doofus 덕뢄에 μ˜ˆμ œκ°€ 도움이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€ πŸ‘

μ•ˆλ…• κ°±, μš°λ¦¬λŠ” 6.0-λ² νƒ€μ—μ„œ μ• λ“œμ˜¨ μ»¨νŠΈλ‘€μ„ μΆœμ‹œν–ˆμŠ΅λ‹ˆλ‹€!

μ»¨νŠΈλ‘€μ€ μž₯기적으둜 μ• λ“œμ˜¨ λ…ΈλΈŒλ₯Ό λŒ€μ²΄ν•˜κΈ° μœ„ν•œ νœ΄λŒ€μš© μžλ™ 생성 λ…ΈλΈŒμž…λ‹ˆλ‹€.

였늘 μ—…κ·Έλ ˆμ΄λ“œν•˜μ—¬ μ‚¬μš©ν•΄ λ³΄μ‹­μ‹œμ˜€. 이 μ•ˆμ •ν™” 버전을 μΆœμ‹œν•  수 μžˆλ„λ‘ λ„μ™€μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

λŒ€λ‹¨ν•΄! READMEλ₯Ό μ½κ³ λŠ” μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€(λ‚΄κ°€ 놓쳀을 μˆ˜λ„ 있음). 이 μƒˆλ‘œμš΄ controls ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? 이 λ¬Έμ œμ—μ„œ μš”μ²­ν•œ λ‚΄μš©μ€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?

APIκ°€ 아직 κ³΅μ‹μ μœΌλ‘œ μ§€μ›λ˜λŠ”μ§€ ν™•μ‹ ν•  μˆ˜λŠ” μ—†μ§€λ§Œ κ°€λŠ₯ν•©λ‹ˆλ‹€. μ €λŠ” @tmeasday 와

  • [ ] μŠ€ν† λ¦¬ μ»¨ν…μŠ€νŠΈμ— updateArgs λ₯Ό μΆ”κ°€ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?
  • [ ] μŠ€ν† λ¦¬μ—μ„œ ν˜ΈμΆœλ˜λŠ” μ½œλ°±μ— μŠ€ν† λ¦¬ μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ? ( this.context?.updateArgs(....) )

Controls에 관심이 μžˆμ§€λ§Œ μ–΄λ””μ„œλΆ€ν„° μ‹œμž‘ν•΄μ•Ό 할지 λͺ¨λ₯΄λŠ” μ‚¬λžŒμ„ μœ„ν•΄ μƒˆλ‘œμš΄ CRA ν”„λ‘œμ νŠΈμ—μ„œ μ‹€μ œ 데λͺ¨λ‘œ μ΄λ™ν•˜λŠ” λΉ λ₯΄κ³  κ°„λ‹¨ν•œ 단계별 μ—°μŠ΅μ„ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. 확인 해봐:

=> CRA 및 TypeScriptκ°€ ν¬ν•¨λœ μŠ€ν† λ¦¬λΆ 컨트둀

Controls READMEμ—λŠ” "knob to controls" λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ λ¬Έμ„œλ„ μžˆμŠ΅λ‹ˆλ‹€.

=> μ• λ“œμ˜¨ λ…ΈλΈŒμ—μ„œ μ–΄λ–»κ²Œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•©λ‹ˆκΉŒ?

μ•ˆλ…• μ—¬λŸ¬λΆ„!
μž„μ‹œ μ†”λ£¨μ…˜μœΌλ‘œ λ‚΄ μ•± λ‹€μŒ μ½”λ“œμ—μ„œ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

import { addons } from '@storybook/addons';
import { CHANGE } from '@storybook/addon-knobs';

const channel = addons.getChannel();

channel.emit(CHANGE, {
  name: 'prop_name',
  value: prop_value,
});

아직 이 κΈ°λŠ₯이 기본적으둜 κ΅¬ν˜„λ˜κΈ°λ₯Ό 기닀리고 μžˆμŠ΅λ‹ˆλ‹€.

groupId λ₯Ό μ‚¬μš©ν•  λ•Œ λ‹€μŒκ³Ό 같이 name κ·Έλ£Ή IDλ₯Ό μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 const show = boolean('Show Something', true, 'Group')

channel.emit(CHANGE, {
  name: 'Show Something_Group',
  value: prop_value,
});

λ˜ν•œ channel λŠ” EventEmitterμ΄λ―€λ‘œ addListener μˆ˜μ‹ λ˜λŠ” λ§€κ°œλ³€μˆ˜κ°€ 무엇인지 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

channel.addListener(CHANGE, console.log)

λ‹€μŒμ€ v6μ—μ„œ addon-controls λ₯Ό μ‚¬μš©ν•˜μ—¬ 이 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법에 관심이 μžˆλŠ” μ‚¬λžŒμ„ μœ„ν•œ μ½”λ“œμž…λ‹ˆλ‹€.

import { useArgs } from '@storybook/client-api';

// Inside a story
export const Basic = ({ label, counter }) => {
    const [args, updateArgs] = useArgs();
    return <Button onClick={() => updateArgs({ counter: counter+1 })>{label}: {counter}<Button>;
}

이것이 이 λͺ©μ μ— κ°€μž₯ μ ν•©ν•œ APIμΈμ§€λŠ” λͺ¨λ₯΄κ² μ§€λ§Œ μž‘λ™ν•΄μ•Ό ν•©λ‹ˆλ‹€. λͺ¨λ…Έλ ˆν¬μ˜ 예:

https://github.com/storybookjs/storybook/blob/next/examples/official-storybook/stories/core/args.stories.js#L34 -L43

@shilmanλ‹˜, κ°μ‚¬ν•©λ‹ˆλ‹€! 그게 νŠΈλ¦­μ„ ν–ˆλ‹€.

관심 μžˆλŠ” μ‚¬λžŒλ“€μ„ μœ„ν•΄ 이 전체 μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•œ μ •ν™•ν•œ Checkbox μŠ€ν† λ¦¬ checked μ†Œν’ˆμ΄ μžˆμŠ΅λ‹ˆλ‹€. Storybook 6.0.0-rc.9λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œ μ—°κ²°λœ μ΄μ•ΌκΈ°λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

export const checkbox = (args) => {
  const [{ checked }, updateArgs] = useArgs();
  const toggleChecked = () => updateArgs({ checked: !checked });
  return <Checkbox {...args} onChange={toggleChecked} />;
};
checkbox.args = {
  checked: false,
  label: 'hello checkbox!',
};
checkbox.argTypes = {
  checked: { control: 'boolean' },
};

cb-arg

@shilman μ œμ–΄λœ ν…μŠ€νŠΈ μž…λ ₯을 μœ„ν•΄ μŠ€ν† λ¦¬μ—μ„œ useArgs λ₯Ό ν™œμš©ν•˜λ €κ³  μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€(일반적으둜 useState 후크λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μŒμ„ 톡해 κ΅¬μ„±μš”μ†Œμ˜ value μ†Œν’ˆμ„ μ—…λ°μ΄νŠΈν•  수 μžˆλŠ” 경우 onChange 이벀트). κ·ΈλŸ¬λ‚˜ μ‚¬μš©μžκ°€ 문자λ₯Ό μž…λ ₯ν•  λ•Œλ§ˆλ‹€ ꡬ성 μš”μ†Œκ°€ 포컀슀λ₯Ό μžƒλŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. argsλ₯Ό μ—…λ°μ΄νŠΈν•  λ•Œλ§ˆλ‹€ μŠ€ν† λ¦¬λ₯Ό μƒˆλ‘œ κ³ μΉ˜κ±°λ‚˜ λ‹€μ‹œ λ Œλ”λ§ν•˜κΈ° λ•Œλ¬ΈμΌκΉŒμš”?

μ œμ–΄λœ ν…μŠ€νŠΈ μž…λ ₯이 μžˆλŠ” ꡬ성 μš”μ†Œμ— λŒ€ν•΄ 인수/μ»¨νŠΈλ‘€μ„ μ‚¬μš©ν•˜λŠ” 데 ꢌμž₯λ˜λŠ” λ‹€λ₯Έ 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

이것은 6.0.0-rc.13μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

@jcq μž¬ν˜„μœΌλ‘œ μƒˆ 문제λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆκΉŒ? 이것은 useArgs 의 μ£Όμš” μ‚¬μš© μ‚¬λ‘€λŠ” μ•„λ‹ˆμ—ˆμ§€λ§Œ ν™•μ‹€νžˆ μ§€μ›ν•˜κ³  싢은 μ‚¬λ‘€μ΄λ―€λ‘œ 기꺼이 μžμ„Ένžˆ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

@shilman 문제 μ—†μŒ β€” 여기에 μƒˆλ‘œμš΄ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
https://github.com/storybookjs/storybook/issues/11657

λ˜ν•œ 잘λͺ»λœ λ™μž‘μ΄ λ¬Έμ„œμ—μ„œλŠ” ν‘œμ‹œλ˜μ§€λ§Œ 일반 μΊ”λ²„μŠ€ λͺ¨λ“œμ—μ„œλŠ” μ˜¬λ°”λ₯΄κ²Œ μž‘λ™ν•œλ‹€λŠ” 점을 λΆ„λͺ…νžˆ ν–ˆμ–΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€.

Observable을 μ‚¬μš©ν•˜μ—¬ κ·Έ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” Angular와 ν•¨κ»˜ μŠ€ν† λ¦¬ 뢁을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

`
.add('차트 데이터 μ—…λ°μ΄νŠΈ 쀑', () => {

const myObservable= new BehaviorSubject([{a: 'a', b: 'b'}]);
return {
  template: '
  <my-component
    myInput: myData,
    (myEvent)="myEventProp($event)"
  ></my-component>
  ',
  props: {
    myData: myObservable,
    myEventProp: $event => {
      myObservable.next([]);
      action('(myEvent)')($event);
    }
  }
};

})
`

이것은 Angularλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‚˜λ₯Ό μœ„ν•΄ μΌν–ˆμ§€λ§Œ 5 ν–‰μ—μ„œ myData.value λ³€κ²½ν–ˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 아직 μ‹œλ„ν•˜μ§€ μ•Šμ•˜μ§€λ§Œ(μ§€κΈˆμ€ 이전 λ²„μ „μ˜ μŠ€ν† λ¦¬λΆμ— κ³ μ •λ˜μ–΄ 있음) 이 문제λ₯Ό μ§€κΈˆ μ’…λ£Œν•  수 μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. args/controls에 λŒ€ν•œ ν›Œλ₯­ν•œ μž‘μ—…μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰