"ํ์ ์ด์ผ๊ธฐ" ๋๋ ์ด์ผ๊ธฐ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉด ์ข์ ๊ฒ์
๋๋ค. ๋ด ๊ฒฝ์ฐ์๋ ๋์ผํ ๋ฆฌํฌ์งํ ๋ฆฌ์ ํฌํจ๋ ๋ค์ํ ๋ฏธ๋ "์ฑ"์ด ํฌํจ๋ฉ๋๋ค. ๊ฐ๋จํ ์๋ฃจ์
์ ui.core.foo
๋ฐ ui.core.bar
์ ๊ฐ์ ์ด๋ฆ์ ์์ ์ ํ์ํ๋ ์ต์
์
๋๋ค.
โโโ core
โโโ bar
โโโ foo
๋ ธ๋ ํ์ฅ ๋ฐ ์ถ์๋ฅผ ์ง์ํฉ๋๋ค.
ํ์ฌ๋ก์๋ ์ด๋ฅผ ๊ตฌํํ ๊ณํ์ด ์์ต๋๋ค. ํ์์ ์ด๋ ต๊ฒ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. "ui.core", "ui.app"๊ณผ ๊ฐ์ ์ ์ผ๋ก ์คํ ๋ฆฌ ์ข ๋ฅ์ ์ด๋ฆ์ ์ง์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ์์ ๋ฐ๋ผ ํํฐ๋งํ ์ ์์ต๋๋ค.
์ด์ผ๊ธฐ๊ฐ ๋ง์ ๊ฒฝ์ฐ ๋ช ๊ฐ์ง ์ด์ผ๊ธฐ์ฑ ์ธ์คํด์ค๋ฅผ ์์ํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ ์คํ ๋ฆฌ๋ถ ๊ตฌ์ฑ ๋๋ ํ ๋ฆฌ๊ฐ ์์ผ๋ฉด ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด์จ๋ ๊ทธ๊ฒ์ ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ์ ๋๋ค.
์ด ์ ์ ๊ธฐ๊บผ์ด ์ธ์ ํ๊ณ ๋ค๋ฅธ ๊ตฌ์ฑ์ ๋ง๋ค๊ณ ๋ค๋ฅธ ํฌํธ์์ ์คํํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
ํ์ง๋ง ์คํ ๋ฆฌ๋ถ์ด ์ฌ๋ฌ ๊ตฌ์ฑ ํ์ผ์ ์ฌ์ฉํ๋๋ก ํ์ฉํ ๋ค์ ๋ช ๋ช ๋ ๊ตฌ์ฑ ํ์ผ ๊ฐ์ ์ ํํ๊ฑฐ๋ ๋ค์ ๋ก๋ํ๋ ๊ฒ์ด ํจ์ฌ ๋ ๋ซ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ตฌ์ฑ์ ์ ํํ๋ UI์ ๊ฒฝ์ฐ ๊ตฌ์ฑ ํ์ผ์ด ๋ค๋ฅธ ๊ตฌ์ฑ ํ์ผ์ "๋ก๋"ํ ๊ฒฝ์ฐ์๋ง ๋ํ๋๋ฉฐ ์ฌ์ด๋๋ฐ ํ์์ ์๋จ ๋๋ ํ๋จ์ ์๋ ์ฌ์ด๋๋ฐ ํญ๋ชฉ์ผ ์ ์์ต๋๋ค.
์ด์จ๋ - ๋ ํฐ ์ฑ์ ๊ฒฝ์ฐ ๊ตฌ์ฑ์ ๋ถํ ํ ์ ์๊ฑฐ๋ ๋ถํ ํ์ง ์์ผ๋ฉด ์ข ๋ฏธ์น ๊ฒ ๊ฐ์ต๋๋ค.
์ถ๊ฐ ๊ตฌ์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ง๋์น๊ฒ ๋ณต์กํ ๊ฒ ๊ฐ์ต๋๋ค. ํด๋์/๊ณ์ธต ๋ณด๊ธฐ์ ๋ํ ํ ๊ธ์ ์ด๋ป์ต๋๊น? ์์ผ๋ก ๋ฉฐ์น ๋์ ๊ตฌํ์ ์์ํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค.
์ด๊ฒ์ ๋์๊ฒ๋ ๋งค์ฐ ๊ท์คํ ๊ธฐ๋ฅ์ด์ง๋ง ์ฌ๋ฌ ์ฑ์ด ์๋ ๋จ์ผ ์ฑ ๋ด์์ ๊ตฌ์ฑ ์์ ์ ํ์ ๊ตฌ์ฑํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
์์ผ๋ก ๋์๊ฐ ์ ์๋ค๋ฉด ๋ ์ฌ์ฉ ์ฌ๋ก ๋ชจ๋์์ ์๋ํ ์ ์๋ ๊ตฌํ์ ํ์ฑํ๋ ๋ฐ ๋์์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
@travi ์ฐ๋ฆฌ์ ๋ ๋ค๋ฅธ ์์ด๋์ด ์ค ํ๋๋ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ ํํ๊ธฐ ์ํด ํํฐ ์์ ๋ฐ๋ก ์๋์ ๋๋กญ๋ค์ด ๋ฉ๋ด๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค.
์นดํ ๊ณ ๋ฆฌ๋ config.js ๋ฐ ๋ค๋ฅธ ํ์ผ ์ธํธ์ ํ ๋น๋ฉ๋๋ค. ๋ฐ๋ผ์ ๊ทธ๋ฃนํ์ ๋ ๋ค๋ฅธ ๊ณ์ธต์ ๊ฐ์ง ์ ์์ต๋๋ค.
๊ทธ๋ฌํ ์ ํ์ ์๋ฃจ์ ์ด ํ ์์ ์์ ์ ์๊ตฌ ์ฌํญ์ ์ถฉ์กฑํ๊ธฐ์ ์ถฉ๋ถํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ํ ์์์ ์ธ๊ธํ ๋ค์์คํ์ด์ค ๊ท์น์ ์ฌ์ ํ โโ๋๋กญ๋ค์ด์์ ์ ํ ํญ๋ชฉ์ผ๋ก ํด์๋ ์ ์๋ ๋ฒ์ฃผ๋ฅผ ํ ๋นํ๋ ํฉ๋ฆฌ์ ์ธ ๋ฐฉ๋ฒ์ผ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด๋ฌํ ์๋ฃจ์ ์ ์ฌ์ฉํ๋ฉด ๋ฒ์ฃผ ๊ฐ ์ฐ๊ฒฐ์ด ์ฌ์ ํ ๊ฐ๋จํ๊ฒ ์ ์ง๋ ์ ์์ต๋๋ค.
๋ด๊ฐ ๋ง๋ค๊ณ ์๋ ์ฑ(๋์จํ "๊ธฐ๋ฅ" ์์ญ ์์ ๊ตฌ์ฑ๋ ์๋ฐฑ ๊ฐ์ ๊ตฌ์ฑ ์์)์์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ํ์ฌ ์์ ์ค์ธ ์์ญ์ ๋ํ ์ด์ผ๊ธฐ๋ฅผ ๋์ ์ผ๋ก ์์ฑํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
find.file(
/\.story\.js/,
path.resolve(__dirname, '../src/app/components', targetComponentPath),
function(files) {
var requires = files.map(function(file) {
return "require('" + path.relative(__dirname, file) + "');";
});
fs.writeFileSync(path.resolve(__dirname, '../.storybook/stories.js'), requires.join("\n"));
}
);
์ฆ, Storybook์ ๋ค๋ฅธ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ํ์์กฐ์ฐจ ์์ต๋๋ค. ๊ธฐ๋ณธ ์ ๊ณต ์ต์ ์ผ๋ก ์ด์ ๋ํ ์ผ์ ์์ค์ ์ง์์ ์ํฉ๋๋ค.
์ด๊ฒ์ ๋ํ ์ด๋ค ์ ๋ฐ์ดํธ?
+1
๋งค์ฐ ์ ์ฉํ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค!
+1
+1
+1
+1
+1
+1
@arunoda๋ , ์นดํ ๊ณ ๋ฆฌ ๊ตฌํ์ ์ง์ ์ด ์์๋์?
๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ฌ๋์ด ๋ ๊ฐ์ ์คํ ๋ฆฌ๋ถ ๊ตฌ์ฑ ๊ฐ์ ์ ํํ๋ ์์ ์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๊น?
+1 ํ ๋จ๊ณ์ ์ถ๊ฐ ์ค์ฒฉ์ด ์ ๋์ ์ผ๋ก ํ์ํฉ๋๋ค./
+1
+1
+1
+1
+1
+1
์ฑ์ด ์ฑ์ฅํ๋ ๋์ ๊ตฌ์ฑ ์์ ๋ชฉ๋ก๋ ์ปค์ง๊ณ ์ค์ฒฉ์ด ๋ ํ์ํ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค. 1๊ฐ ์ด์์ ๋ ๋ฒจ์ ์ด๋ฏธ ๋ง์ ๊ฒฝ์ฐ๋ฅผ ์ปค๋ฒํ ๊ฒ์ ๋๋ค.
+1
์๋ค ์!
์ด๋ฌํ ๊ธฐ๋ฅ์ด ๊ฐ๊น์ด ์ฅ๋์ ๊ณํ๋์ง ์๋๋ค๋ ์ฌ์ค์๋ ๋ถ๊ตฌํ๊ณ ์ด๊ฒ์ด Storybook Addons API๋ฅผ ํตํด ๊ทธ๋ฌํ ๋์์ ์ป์ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ์ง๋ ์์ต๋๋ค.
๋ค์์ ๊ทธ๋ฌํ ์ ๋์จ์ ๋๋ค.
(ํ์) ์คํ ๋ฆฌ์ ๋ํ ๋ฌด์ ํ ์์ค์ ์ค์ฒฉ ์ถ๊ฐ
์ค์ฒฉ ์์ค์ ํ๋ ๋ ์ถ๊ฐํ๋ ค๋ฉด ์คํ ๋ฆฌ์ .chapter(name)
๋ฅผ ์ถ๊ฐํ์ธ์.
// stories.js:
storiesOf('React App', module)
.chapter('Left panel')
.add('Button 1', fn(1))
.add('Button 2', fn(2))
.chapter('Bottom Panel')
.add('Input 3', fn(3))
.add('Input 4', fn(4))
.endOfChapter()
.chapter('Header Panel')
.add('Input 5', fn(5))
.add('Input 6', fn(6))
.endOfChapter()
.endOfChapter()
.chapter('Right panel')
.add('Button 7', fn(7))
.add('Button 8', fn(8))
.endOfChapter()
Knobs
, addWithInfo
๋ฐ ๊ธฐํ ์ ๋์จ๊ณผ ํธํstoryDecorator
๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ฅ์ ๋ํํ์ญ์์ค.๋ชจ๋ ํผ๋๋ฐฑ์ ๋งค์ฐ ๊ฐ์ฌํ๊ฒ ์ต๋๋ค! :)
@UsulPro ๋ฐ๊ฐ์ต๋๋ค!
@UsulPro Storybook Chapters๋ ํ๋ฅญํ ์๋ฃจ์ ์ ๋๋ค. ๊ฐ์ฌ ํด์!
@UsulPro๊ฐ ์ ํํ ์ ๊ฐ
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ! @UsulPro ( storybook-chapters
๋ก ๋ฉ์ง ์์
์ ์ํํ)์ ๊ฒฝ์ํ๋ ค๋ ๊ฒ์ด ์๋๋ผ preview
์ฐฝ. ์ด๊ฒ์ ๋ถํธ์คํธ๋ฉ ๋ฌธ์์ detailed components view
์ฌ์ด์์ ์ฝ๊ฒ ์ ํํ ์ ์๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ํนํ ์ ์ฉํฉ๋๋ค related components view
๋ณด์ฌ์ค ๊ตฌ์ฑ ์์๊ฐ ๋ง์ต๋๋ค. ์ฌ๋ฌ ์คํ ๋ฆฌ๋ถ ์ธ์คํด์ค๋ฅผ ์ค์ ํ๋ ๊ฒฝ๋ ๋ฒ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ ์ฉํ๋ค๋ฉด ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค - https://github.com/majapw/storybook-addon-toggle
๋๋ @UsulPro ์ ๋ฉ์ง storybook-chapters
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ ์์ ํ์ผ ๊ณ์ธต์ ์คํ ๋ฆฌ๋ถ ์ฑํฐ๋ก ๋ฏธ๋ฌ๋งํ ์คํ ๋ฆฌ๋ถ ๋ก๋๋ฅผ ๋ง๋ค์์ต๋๋ค: storybook-filepath-chapters
์ด๋ฅผ ํตํด ๋ด ์คํ ๋ฆฌ๋ฅผ ๊ตฌ์ฑ ์์์ ํจ๊ป ์ธ๋ผ์ธ์ผ๋ก _stories
ํ์ผ์ด๋ ํด๋์ ๋ฃ์ ์ ์์ต๋๋ค. ๋ก๋๋ ๋ชจ๋ ์คํ ๋ฆฌ ํ์ผ์ ์ฐพ์ ํด๋น ํ์ ๊ตฌ์กฐ์ ๋งคํํฉ๋๋ค.
๋ฐ๋ปํ ํผ๋๋ฐฑ ๊ฐ์ฌํฉ๋๋ค, ์ฌ๋ฌ๋ถ!
@hadfieldn ์ storybook-filepath-chapters
๋ฅผ ๋ณด๋ ์ ๋ง ๋ฉ์ง๋ค์ ! ๐
๋๋ storybook-addon-toggle
๋ฅผ ์๋ก ๋ค์๋ฉด, ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ฌ์ธต์ ์ผ๋ก ๋ฟ๋ง ์๋๋ผ ์์์์๋ ๊ตฌ์ถํ ์ ์๋ ๊ฐ๋ฅ์ฑ์ ๊ฐ๋ ๊ฒ์ด ๋ฐ๋์งํฉ๋๋ค. ์ฌ์ค ๊ธฐ์ ์ ์ผ๋ก๋ ๊ฐ๋ฅํ์ง๋ง (์ ๋์จ API ๋ด์์ ์ ์ง) ์ต์ ์ ๋ฐฉ๋ฒ์ ์ ํํ๊ธฐ๋ ์ด๋ ต๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ง๋ ์ด๊ฒ์ ๋ฐ์ฝ๋ ์ดํฐ(@majapw์ ๊ฐ์)๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ ๋์จ ํจ๋์ ํตํด ์ํํ ์ ์์ต๋๋ค.
์์ง ์คํ ๋ฆฌ ์์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ถ๊ฐํ ๊ณํ์ ์์ง๋ง storybook-chapters
์ ๋์จ์๋ ์ด์ API ๊ฐ ์์ผ๋ฉฐ ์ด๋ฌํ ๊ณ์ธต ๊ตฌ์กฐ์ ๊ตฌ์ฑ์ ๋จ์ํํ ์ ์์ต๋๋ค.
enable
/disable
์คํ ๋ฆฌ ํ์/์จ๊ธฐ๊ธฐ
๋ค์๊ณผ ๊ฐ์ด ์๋ํฉ๋๋ค.
-
์คํ ๋ฆฌ์ enable()
/ disable()
๋ฅผ ์ถ๊ฐํ์ธ์. ์ธ์๋ก ์ ์ด ๊ธฐ๋ฅ์ ์ ๋ฌํ ์ฝ๋ฐฑ์ ์ง์ ํฉ๋๋ค.
let toLight = () => {};
let toDark = () => {};
storiesOf('Heroes Lightside', module)
.enable((en) => { toLight = en; })
.add('Yoda', info('Yoda'))
.add('Mace Windu', info('Mace Windu'));
storiesOf('Heroes Darkside', module)
.disable((en) => { toDark = en; })
.add('Darth Sidious', info('Darth Sidious'))
.add('Darth Maul', info('Darth Maul'));
๋น์ ์ ์ฌ์ฉํ ์์๋ toLight(false)
์จ๊ธธ Heroes Lightside
๋ฐ toDark(true)
๋ณด์ฌ Heroes Darkside
์ด์ผ๊ธฐ๋ฅผ. toLight
๋ฐ toDark
๋ฅผ ์ผ๋ถ ๋ฐ์ฝ๋ ์ดํฐ์ ๋ฃ๊ฑฐ๋ ๋ค๋ฅธ ์คํ ๋ฆฌ์์ ์ฝ๋ฐฑํ ์ ์์ต๋๋ค. ๊ฐ์ฅ ๊ฐ๋จํ ์๋ฅผ ๋ณด์ฌ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
storiesOf('Choose Your Side', module)
.add('Lightside', () => {
toLight();
toDark(false);
return (<div>{'Lightside selected'}</div>);
})
.add('Darkside', () => {
toDark();
toLight(false);
return (<div>{'Darkside selected'}</div>);
});
์ด์ Choose Your Side
, Heroes Lightside
๋ฐ Heroes Darkside
3๊ฐ์ง ์คํ ๋ฆฌ ์ธํธ๊ฐ ์์ต๋๋ค. ๋ง์ง๋ง ๋ ๊ฐ ์ค ํ๋๋ง ๋ณผ ์ ์์ผ๋ฉฐ ์ฒซ ๋ฒ์งธ๋ ์ ํํ ์ ์์ต๋๋ค.
๋ค์ ๋ฆด๋ฆฌ์ค ์์๋ ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅํ ์ ๋์จ ํจ๋์ ํตํด ์คํ ๋ฆฌ์ ๊ฐ์์ฑ์ ์ ์ดํ๋ โโ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๊ณํ์
๋๋ค.
-
ํ์ฑํ/๋นํ์ฑํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์ ํธํ๋ ๋ก์ง์ผ๋ก ์ฌ์ฉ์ ์ ์ ํ์์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ๊ณ์ธต ๊ตฌ์กฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ๊ตฌํํ ๊ฒ์ด์ง๋ง ์ปค๋ฎค๋ํฐ๊ฐ ์ด๋ป๊ฒ ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋์ง์ ๋ํ ๊ฐ๋ ์ ์ข์ํ ๊ฒ์ ๋๋ค.
UX ํ๋ช ํ, ๋๋ ์ด ์์ด๋์ด๋ฅผ ์ข์ํฉ๋๋ค: http://multi-level-push-menu.make.rs/demo/basichtml/basichtml.html
๊ตฌ์ฑ์ ์์ง ๋ชจ๋ฆ ๋๋ค. ํ์ผ ํ์์ ์ฌ์ฉํ๊ณ ํ์ผ ์์คํ ์ ๋ฏธ๋ฌ๋งํ๊ฑฐ๋ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค. https://github.com/sm-react/storybook-chapters/issues/1#issue -215446017
@ndelangen ์คํ ๋ฆฌ ์ธ๋ถ์์ ํ์์ ์ ์ํ ์ ์๋๋ก (์ ์ด๋ ์ ํ์ ์ผ๋ก?) ์๊ฐ์
@jackmccloy ๊ด์ฌ์ด ์์ต๋๋ค. ๋ฌด์จ ๋ง์ธ์ง ์์ธํ ๋ง์ํด ์ฃผ์๊ฒ ์ต๋๊น?
๋ค๋ฅธ ๋ฌธ์ ์์ ์ธ๊ธํ์ง๋ง ๋ฒ์ฃผ์ ๋ํ ๋ด ๋ชฉํ๋ ๋๋ถ๋ถ ์์ ์ค๊ณ ์ ์ ๋ ฌํ๋ ๊ฒ์ ๋๋ค. ํจํด ๋ฉ ์ ์ํ ๋ฏน ๋์์ธ์ ์ํ ๊ณต์ ์คํ์ผ ๊ฐ์ด๋ ์ ๊ทผ ๋ฐฉ์์ด์ง๋ง ์คํ ๋ฆฌ๋ถ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ฉด ๋ง์ง๋ง ๋จ์ ๊ณต๋ฐฑ์ ์ฑ์ธ ์ ์์ต๋๋ค.
์ด๋ฏธ ๊ตฌ์ฑ ์์๋ฅผ ํด๋น ๋ฒ์ฃผ์ ์ต์์ ํด๋์ ์ ๋ ฌํ๋ฏ๋ก ์ต์์ ํด๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ ์์๋ฅผ ๋ฒ์ฃผ์ ๋ก๋ํ ์ ์๋ ๊ฒ๋ ์ดฌ์์ ์ข์ ์ผ์ด ๋ ๊ฒ์ ๋๋ค.
@travi ํด๋ ๋ ์ด์์์ ์ธ์ํด ์ค ์ ์์ต๋๊น?
์ด ์ ํํ ๋ชฉ์ ์ ์ํด ์คํ ๋ฆฌ๋ถ์ ๊ฐ์ ํ๋ ๋ฐ ํ์คํ ๊ด์ฌ์ด ์์ง๋ง ํด๋ ๊ตฌ์กฐ์์ ์ด ๋ถ๋ฅ๋ฅผ ์ฝ๋ ๋ฐ ๊ธฐ์ ์ ์ผ๋ก ํ์ํ ๊ฒ์ด ๋ฌด์์ธ์ง ๊ด์ฌ์ด ์์ต๋๋ค.
๋ณธ์ง์ ์ผ๋ก
project root
|
+--
| +-- atoms
| | +-- foo
| | +-- index.js // the component
| | +-- stories.js
...
| +-- molecules
| | +-- bar
| | +-- index.js
| | +-- stories.js
...
| +-- organisms
| | +-- baz
| | +-- index.js
| | +-- stories.js
๊ทธ๊ฒ ๋์์ด ๋๋์? ๊ฐ ์ต์์ ํด๋ ์๋์ ์ฌ๋ฌ ๊ตฌ์ฑ ์์๊ฐ ์์ผ๋ฉฐ ๋๋ก๋ ๋ค๋ฅธ ํด๋ ์์ค์ผ๋ก ๊ทธ๋ฃนํ๋ฉ๋๋ค. ๋์์ด๋๋ค๋ฉด ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๊ฒ๋์ด ๊ธฐ์ฉ๋๋ค.
์ข์์, ๊ทธ๋์ ์ฐ๋ฆฌ๊ฐ ํ ์ ์๋ ๊ฒ์ config.js
ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ ๊ฒ์
๋๋ค. autoDiscoverStories
์ ๋. ์ฆ, ์คํ ๋ฆฌ๋ฅผ ์๋์ผ๋ก ๊ฐ์ ธ์ฌ ํ์๊ฐ ์์ผ๋ฉฐ ํ์ผ ์์คํ
ํด๋๊ฐ ๋ฒ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
@ndelangen ์ ๊ฐ ์๊ฐํ๋
ํ ๊ฐ์ง ๊ฐ๋ฅ์ฑ:
ํ์ฌ ๊ฐ ์คํ ๋ฆฌ๋ ์นดํ
๊ณ ๋ฆฌ๊ฐ ํ ๋น๋๋ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์ ์ ๋ชฉ์ด ํ ๋น๋๋ ๋ ๋ฒ์งธ ๋จ๊ณ์ ๋ ๋จ๊ณ๋ก ์ถ๊ฐ๋ฉ๋๋ค.
storiesOf('storyCategory', module).add('storyTitle', () => <Component />)
์ฌ๋ฌ ์คํ ๋ฆฌ๋ฅผ ๋์ผํ ์นดํ ๊ณ ๋ฆฌ์ ์ถ๊ฐํ ์ ์์ง๋ง ๊ตฌ์กฐ๋ ์ ์ฐ์ฑ์ ์ด๋ ์ ๋ ์ ํํฉ๋๋ค. ๋ชจ๋ ์คํ ๋ฆฌ์๋ ์นดํ ๊ณ ๋ฆฌ์ ์ ๋ชฉ์ด ์์ด์ผ ํ๋ฉฐ ์นดํ ๊ณ ๋ฆฌ๋ ์ ๋ชฉ๋ณด๋ค "์์ ์์ค"์ ๋๋ค.
๊ทธ๋ฌ๋ ์ด์ผ๊ธฐ๋ฅผ ์ฝ๊ฐ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ ์ํ ์ ์๋ค๋ฉด, ์ฆ
const storyData = {
category: "category",
title: "storyTitle",
}
stories.add(() => <Component />, storyData)
๋ค์ํ ํ์ ์ต์ ์ ๋ ์ฝ๊ฒ ์คํํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ ํ์์ ๊ทธ๋๋ก ์ ์ง๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ ์์ ์ธ ๊ธฐ๋ณธ๊ฐ์ด๋ฉฐ ์๋ง๋ ์ฐ๋ฆฌ ๋๋ถ๋ถ์๊ฒ ์ถฉ๋ถํ ๊ฒ์
๋๋ค. storyData
๋ ์ ํ ์ฌํญ์ผ ์๋ ์์ต๋๋ค. ์นดํ
๊ณ ๋ฆฌ๊ฐ ์๋ ์คํ ๋ฆฌ๋ ์ต์์ ์์ค์ ํ์๋ ์ ์๊ณ , ์ ๋ชฉ์ด ์๋ ์คํ ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ์ฑ ์์์ displayName
์ ํ์๋ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ปค๋ฎค๋ํฐ๋ (a) stroyData
์ถ๊ฐ ๋ฉํ๋ฐ์ดํฐ ํ๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ (b) ๋ฉํ๋ฐ์ดํฐ ํ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ ํจ๋์ด ๋ ๋๋ง๋๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ์ฌ ์คํ ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ์คํํ ์ ์์ต๋๋ค.
๋ช ๊ฐ์ง ์์ด๋์ด:
// add an additional level to the hierarchy called subCategory
const stroyData = {
category: "Buttons",
subCategory: "Blue",
title: "BlueButton",
}
stories.add(() => <BlueButton />, storyData)
// add tags to a story that you could then filter by
const stroyData = {
category: "Buttons",
tags: ["button", "homepage"],
title: "HomepageButton",
}
stories.add(() => <HomepageButton />, storyData)
// have a story to appear in multiple categories
const stroyData = {
categories: ["Buttons", "Homepage Elements"],
title: "HomepageButton",
}
stories.add(() => <HomepageButton />, storyData)
๋ฉ์ง! ๊ทธ๊ฒ์ ์์ฃผ ๊ธฐ๋ณธ์ด๋ฉฐ ์ค์ ๋ก ํ์ฅ ๊ฐ๋ฅํฉ๋๋ค. ์ด๊ฒ์ ๋ํด ์ ์ ์๊ฐํ๊ฒ ์ต๋๋ค. ๐ค
์์ฒญ๋. ๊ฒฐ์ ํ ์ฌํญ์ ์๋ ค์ฃผ์ธ์. ์ด๋ค ๋ฐฉํฅ์ ์ ํํ์๋ ์ ๊ฐ ํ ์ ์๋ ๊ณณ์์ ์ ์ํ๊ฒ ์ต๋๋ค. - ํ๋ก์ ํธ์ ์ด๋ ฌํ ํฌ
@jackmccloy ์ ์ ์์ ํ๋ฅญํฉ๋๋ค. ๋ฉ์ง ์์ด๋์ด์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
๊ทธ๋ฌ๋ UI๋ฅผ ์ผ๋ จ์ "์๊ฐ์ ํ
์คํธ ์ฌ๋ก"๋ก ์๊ฐํ๊ณ ์ํ๋น add()
ํธ์ถ์ ์ฌ์ฉํ์ฌ UI ์ํ๋ฅผ ๊ฐ๋ณ ์คํ ๋ฆฌ๋ก ์ฝ๊ฒ ์ ์ํ๋ Storybooks์ ๊ฐ๋ ฅํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ถ์ฅํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
add()
ํธ์ถ์ ์คํ ๋ฆฌ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ ์๋ชป๋ ์์ค์์ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๋์ผํ ์ ์์ ๋ณด๊ณ ์ถ์ง๋ง storiesOf()
๊ธฐ๋ฅ์ ์ฌ์ฉ:
storiesOf({
title: Component,
category: "My Category"
}, module)
.add("when empty", () => <List items=[] />)
.add("with items", () => <List items=["one", "two", "three"] />)
.add("etc.", () => <List items={etc} />);
Component.displayName
์์ ์ ๋ชฉ์ ๊ฐ์ ธ๊ฐ ์ ์๊ณ ํ์ ๋ฒ์ฃผ์ ๋ํ ๋ค๋ฅธ ๋ชจ๋ ์์ด๋์ด๋ ์ฌ๋ฌ ๋ฒ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ์ถ๊ฐํ ์ ์๋ค๋ ์์ด๋์ด๊ฐ ๋ง์์ ๋ญ๋๋ค. ์ํ ์ถ๊ฐ์ ๋จ์์ฑ์ ์ ์งํ๊ณ ์ถ์ต๋๋ค.
๋ฒ์ฃผ๊ฐ ์ ์๋ ์์น์ ๊ด๊ณ์์ด ๋ช ์ฌํด์ผ ํ ํ ๊ฐ์ง๋ ๋ค๋ฅธ ํ์ผ์ด ๋ฒ์ฃผ์ ์ถ๊ฐ๋ ์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. ์นดํ ๊ณ ๋ฆฌ๊ฐ ๋จ์ผ ํ์ผ์์๋ง ์ ์๋ ์ ์๋ค๋ฉด ๋งค์ฐ ์ ํ์ ์ผ ๊ฒ์ ๋๋ค.
@travi์ ๋์ํฉ๋๋ค. ๊ทธ๋์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๋ฌธ์์ด(์ผ๋ถ ์ฌ์ ํค์ ๋งคํ๋ ๊ฒ์ด๋ผ๊ณ ์์ํจ)์ด ๋งค๋ ฅ์ ์ธ ์ด์ ์ ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์คํ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ด ๋ฒ์ฃผ๋ฅผ ํ ๊ณณ์์ ์ ์ํ ์ ์๋ค๊ณ ์์ํ๊ณ ์์ต๋๋ค.
// categories.js
export const Layouts = "Layouts";
export const Components = "Components";
export const Styles = "Styles";
// DashboardLayout.story.js
import { Layouts } from "../categories";
import DashboardLayout from "./DashboardLayout";
storiesOf({
title: DashboardLayout,
category: Layouts
}, module)
.add("default", () => <DashboardLayout />);
๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ๋ด ์ฑ์ ๋จ๊ฒจ์ง ๊ตฌํ ์ธ๋ถ ์ฌํญ์ด ๋ ๊ฒ์ ๋๋ค.
@theinterned @jackmccloy ๊ทํ์ ์ ์์ด ๋ง์์ ๋ญ๋๋ค .
๋๋ ๋น์ ์ด ์์์ ๊น์ด์ ๊ณ์ธต์์ ๋น์ ์ ์ ์์ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์์์ง ์๊ฐํ๊ณ ์์ต๋๋ค. category
/ subCategory
๊ฒฝ๋ก ๊ตฌ์ฑ ์์์ ๋ฐฐ์ด์ด ์๋ path
์ผ ์ ์์ต๋๋ค. (๋น์ ์ด ๊ฑฐ๊ธฐ์ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ์๋ํ ๊ฒ์ ์๋๋ผ๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ๋จ์ง ๋น์ ์ ์์ด๋์ด๋ฅผ ์ธ์ฉํ์ ๋ฟ์
๋๋ค.)
๋ํ ํ์ผ ์์คํ
์ ์ฌ์ฉํ์ฌ ํ์ ๊ณ์ธต์ ์์ฑํ๋ ๊ตฌ์ฑ ์ต์
์ ์์ด๋์ด๊ฐ ๋ง์์ ๋ญ๋๋ค. ์ด ์ต์
์ด ํ์ฑํ๋๋ฉด path
์ธ์๋ ์ ํ ์ฌํญ์ด ๋ฉ๋๋ค.
์ด๊ฒ์ ํ์ฅ ๋ชฉํ์ ๊ฐ๊น์ง๋ง ๊ณ์ธต ๊ตฌ์กฐ์ ๊ฐ ์คํ ๋ฆฌ ํ์ด์ง๋ฅผ ๋ณ๋์ ์ฒญํฌ๋ก ๋ก๋ํ์ฌ ์คํ ๋ฆฌ๋ถ์ด ์ปค์ง์๋ก ๊ฐ๋ณ๊ฒ ์ ์งํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ํ ์คํ ๋ฆฌ๋ถ ๋ก๋๊ฐ ํน์ ํ์ผ ์์คํ ํด๋๋ฅผ ๋ฃจํธ ์ปจํ ์คํธ๋ก ์ฌ์ฉํ์ฌ ์คํํ๋๋ก ํ์ฉํ์ฌ ์ ์ฒด ํ๋ก์ ํธ์ ๋ชจ๋ ์คํ ๋ฆฌ๊ฐ ์๋๋ผ ํด๋น ํด๋์ ์ ์๋ ์คํ ๋ฆฌ๋ง์ผ๋ก ์คํ ๋ฆฌ๋ถ์ ๋น๋ํ ์ ์๋๋ก ํ๋ ๊ฒ๋ ์ข์ต๋๋ค.
์ฌ๋๋ค์ ๊ตฌ์ฑ์์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ์ ์/๋ฑ๋กํ๋ ๊ฒ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํฉ๋๊น?
// config.js
import { configure, addCategory } from '@kadira/storybook';
function init() {
require('../src/stories');
addCategory({
id: 'atom',
name: 'Atoms',
index: 0
});
addCategory({
id: 'molecule',
name: 'Molecules',
index: 1
})
}
configure(init, module);
// component.story.js
import Component from "./Component";
storiesOf({
title: Component,
category: 'atom'
}, module)
.add("default", () => <DashboardLayout />);
category: ['atom', 'deprecated']
๋ฐฐ์ด์ ์ง์ํ ์๋ ์์ต๋๋ค. ์ ์ ๋ ๊น์?
์ด๊ฒ์ ์์ ์ค๊ณ์์ ์ค์ํ ์นดํ ๊ณ ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅธ ์์๋ก ๋ฐฐ์น๋๋๋ก ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
๊ตฌ์ฑ์์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ฒ์ํ๋ ๊ฒ์ ์ข์ง๋ง ๋งค์ง ๋ฌธ์์ด์ ์ข์ง ์์ต๋๋ค ๐
๊ทธ๊ฒ์ ๋์๊ฒ ์๋ฏธ๊ฐ ์์ต๋๋ค.
๋ํ ๋ฌธ์์ด๊ณผ ์ผ์นํ๊ธฐ๋ฅผ ํฌ๋งํ์ง ์๊ณ ๊ตฌ์ฑ์ ์ ์๋ ๊ฒ์์ ์คํ ๋ฆฌ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ +1
@ndelangen์ด ๋ฒ์ฃผ๋ฅผ
Storybook์์ ๋ด๊ฐ ์ข์ํ๋ ํ ๊ฐ์ง๋ ๊ตฌ์ฑ ์์์ ๊ฐ์ ์์น์ story.jsx
ํ์ผ์ด ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๊ฒ๋ง์ผ๋ก ๊ตฌ์ฑ ์์๊ฐ Storybook์ ์๋์ง ์ฌ๋ถ๋ฅผ ์ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ๊ทธ ๋ณด์ฆ -
story.jsx
ํ์ผ์ด ์กด์ฌํ๋ฉด ์คํ ๋ฆฌ๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ - ์นดํ
๊ณ ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ์ ์ํ์ฌ ์ทจ์ํด์๋ ์ ๋๋ ์ค์ํ ๊ฒ์
๋๋ค.
ํด๋น ๋ณด๊ธฐ์์ ๊ตฌ์ฑ์ ๋ฒ์ฃผ์ ๋ํด id
๋ฐ index
๊ฐ ํ์ํ์ง ์์ ์๋ ์์ต๋๋ค. ์ด์ ๊ฐ์ ๊ฒ(์ต์
ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ )์ด ์๋ํ ์ ์์ต๋๋ค.
setOptions({
categoryOrder: [
"First Category",
"Second Category",
"Third Category",
});
์ฌ๊ธฐ์ First Category
, Second Category
, Third Category
๋ ๋ฐ๋์ ์ฒซ ๋ฒ์งธ, ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ๋ก ํ์๋๋ฉฐ ์คํ ๋ฆฌ์ ์ ์ธ๋ ๋ค๋ฅธ ์นดํ
๊ณ ๋ฆฌ๋ ์ด ์ธ ๊ฐ ๋ค์ ์ํ๋ฒณ์์ผ๋ก ํ์๋ฉ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ด ์์ ๊น์ด ์ค์ฒฉ์ ์ ์ดํ๋ โโํ๋ช ํ ๋ฐฉ๋ฒ์ผ ์๋ ์์ต๋๋ค.
categoryOrder: [
{
"Atoms": [
{
"Buttons": []
}
],
}, {
"Molecules": [],
}],
์นดํ
๊ณ ๋ฆฌ๊ฐ "๋ฒํผ"์ธ ์คํ ๋ฆฌ๋ Atoms -> Buttons
์์ ๋ํ๋ฉ๋๋ค. "Atoms" ์นดํ
๊ณ ๋ฆฌ์ ์คํ ๋ฆฌ๋ Atoms
, Buttons
(๊ทธ๋ฌ๋ ๋ด๋ถ๋ ์๋) ๋ฑ์ ๋ํ๋ฉ๋๋ค.
์ฌ์ฉ์๋ ๊ตฌ์ฑ ์์ด ํ ์์ค์ ๊น์ด(์ง๊ธ๊ณผ ๊ฐ์ด)์ ์ต์ํ์ ๊ตฌ์ฑ์ผ๋ก ์์ ์์ค์ ๊น์ด๋ฅผ ์ป์ ์ ์์ต๋๋ค. ์ค์ํ ๊ฒ์ ์คํ ๋ฆฌ ์์ฒด๊ฐ ์๋๋ผ ๊น์ด๊ฐ ์๋ ์นดํ ๊ณ ๋ฆฌ(๊ตฌ์ฑ ์์ค์์ ์ค์ )๊ฐ ๋๋ค๋ ๊ฒ์ ๋๋ค(์ฆ, ์คํ ๋ฆฌ๋ ์นดํ ๊ณ ๋ฆฌ๋ง ์ค์ ํฉ๋๋ค. ์นดํ ๊ณ ๋ฆฌ๊ฐ ๊ณ์ธต ๊ตฌ์กฐ์์ ๋ํ๋๋ ์์น๋ฅผ ์ ์ํ์ง ์์).
@theinterned ์ํ ์ถ๊ฐ์ ๋จ์์ฑ์ ์ ์งํด์ผ ํ๋ค๋ ์ ์ ๋ค์ ๋์ํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ์ง ์์์ต๋๋ค. ์๋ง๋ b/c๋ ๋ ธ๋ธ ์ ๋์จ์ ๋ง์ด ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋์ ์ ๋ ๊ตฌ์ฑ ์์์ ์คํ ๋ฆฌ ์ฌ์ด์ 1-1 ๊ด๊ณ๋ฅผ ์ ์งํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์คํ ๋ฆฌ ์ ๋ชฉ์ ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ์ค๋ช ํ๋ ๊ฒ์ด ์๋๋ผ ๊ตฌ์ฑ ์์๋ฅผ ์ค๋ช ํฉ๋๋ค.
๋ ์ฌ์ฉ ์ฌ๋ก ๋ชจ๋์์ ์๋ํ ์ ์๋ ํ ๊ฐ์ง ์ ์ฌ์ ์ธ ์๋ฃจ์ ์ ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ๋ ๊ฒ์ ๋๋ค.
const storyData = {
category: "category",
title: "first item",
}
stories.add(() => <Component />, storyData)
.add(() => <Component />, {title: "second item"})
.add(() => <Component />, {title: "third item"})
์ฌ๊ธฐ์ (a) ์คํ ๋ฆฌ์ ์์๋ ์ ์ธ๋ ์์น์์ ์ ์ดํ ์ ์๊ณ (์ธ๋ถ ๊ตฌ์ฑ์ด ํ์ํ์ง ์์) (b) storyData
๋งค๊ฐ๋ณ์๋ ์ด์ ๊ฐ์ฒด๋ฅผ ๋ณด์กดํ์ฌ ๋ค์ ๊ฐ๋ง ๋ฎ์ด์๋๋ค. ๋ช
์์ ์ผ๋ก ์ ๋ฌ๋ฉ๋๋ค.
๊ทธ๋ฅ ์๊ฐ.
์ต์์ ์นดํ ๊ณ ๋ฆฌ๋ง์ผ๋ก๋ ํฅ๋ถ๋์ง๋ง, ์ค์ฒฉ๋ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ง์ํ ๋งํผ ์ถฉ๋ถํ ์งํ๋๋ค๋ฉด ์นดํ ๊ณ ๋ฆฌ ์ด๋ฆ์ด ๋ค๋ฅธ ์นดํ ๊ณ ๋ฆฌ ๊ฐ์ ๊ณ ์ ํ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ๋ ๊ฒ์ด ์์ ํ์ง ์๋ค๋ ์ ์ ์ฃผ๋ชฉํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
์์ ์ค๊ณ ์๋ฅผ ๊ณ์ํ๋ฉด ์์, ๋ถ์ ๋ฐ ์ ๊ธฐ์ฒด์ ์ต์์ ๋ฒ์ฃผ ๊ฐ๊ฐ์ ๋ํด ๋์ผํ ์ด๋ฆ์ ํ์ ๋ฒ์ฃผ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค. ํจํด ๋ฉ ๋ฐ๋ชจ ์์ ์์์ด ์ด์ ๋ํ ์ข์ ์์ ๋๋ค. ๊ฐ๋ณ ํ๋ ์์๋ ์์ ์๋์ ๋์ด๋๊ณ ํ๋์ ๋ ์ด๋ธ์ ์กฐํฉ์ ๋ถ์ ์๋์ ๋์ด๋๋ฉฐ ์์ ํ ํํ๋ก ๊ทธ๋ฃนํ๋ ์ฌ๋ฌ ํ๋๋ ์ ๊ธฐ์ฒด ์๋์ ํ์๋ฉ๋๋ค.
ํฅ๋ฏธ๋ก์ด ์๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ์ ๋ชฉ, ์คํ ๋ฆฌ ๋ฐ ์คํ ๋ฆฌ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ค๋ ์ฝ๋ฐฑ์ผ๋ก ์ ์๋ ์ ์๊ณ ์ฌ์ฉ์๊ฐ ์ฝ๋ฐฑ์ ๊ตฌ์ฑํ๊ธฐ ์ํด ์ ๋ฌํ ์ ์๋ ์ผ๋ถ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ ์ ์๋์ง ๊ณ ๋ คํ๋ ๊ฒ์ ๋๋ค.
storyData = {
title: Component,
category: ({ title, story, storyPath, meta }) => someCategoryPath,
meta: { ..whateverMeta }
}
์ ์ผํ ์๊ตฌ ์ฌํญ์ ์ฝ๋ฐฑ์ด ์คํ ๋ฆฌ์ ๋ํ ๋ฒ์ฃผ ๊ฒฝ๋ก๋ฅผ ์ ์ํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
storyData.category() //=> returns the below array
// a simple category path might look like:
[ "One category" ];
// The path for a story nested three categories deep would look like:
[ "Parent Category", "Child Category", "Grandchild category where the story lives" ];
์ด๊ฒ์ ์ฌ๋๋ค์ด ์ํ๋ ์นดํ ๊ณ ๋ฆฌ ์์คํ ์ ์์ฑํ ์ ์๊ฒ ํด์ค๋๋ค.
์ ์ญ ๊ตฌ์ฑ์ ์ํ๋ฉด ์ฝ๋ฐฑ ๋ด์์ ๋ฑ๋กํ๊ณ ์ฌ์ฉ์ ์ ์ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์คํ ๋ฆฌ๋ฅผ ๋ฑ๋กํ ๋ฒ์ฃผ/ํ์ ๋ฒ์ฃผ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
categories: [
{
"Atoms": [
{
"Buttons": []
}
],
}, {
"Molecules": [],
}];
function setCategory({ meta }) {
const { categroyPath } = meta; // maybe a dot path string like "Atoms.Buttons" ?
const category = categroyPath.split('.'); // [ "Atoms", "Buttons" ]
return validatePath(category, categories); // categories["Atoms"]["Buttons"] is a valid path
}
ํ์ผ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์นดํ ๊ณ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ค์ ํ๋ ค๋ฉด ๊ฒฝ๋ก ์ ๋ณด๊ฐ ์์ด์ผ ํฉ๋๋ค.
function setCategory({ storyPath }) {
// for story path `src/components/Atoms/MyComponent.story.js`
let folders =storyPath.split('/'); // [ "src", "components", "Atoms", "MyComponent.story.js" ];
folders = without(folders, 'src'); // ["components", "Atoms", "MyComponent.story.js" ];
folders.pop(); // [ "components", "Atoms" ]
return folders;
}
๊ฐ๋จํ ์นดํ ๊ณ ๋ฆฌ ์ด๋ฆ์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ํ๋๋ง ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค! (๊ทธ๋ฆฌ๊ณ ์นดํ ๊ณ ๋ฆฌ๋ ๋จ์ํ ๋ฌธ์์ด, ์นดํ ๊ณ ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ค๋ช ํ๋ ๋ฐฐ์ด ๋๋ ์นดํ ๊ณ ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ๋ฐํํ๋ ์ฝ๋ฐฑ ์ค ํ๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.)
์ด์ ํ๋์ด ํ๊ณ์ ๋๋ค!
๋น์ทํ ์ฐธ๊ณ ๋ก ์ ๋ ฌ ์์๋ฅผ ์ ์ํ๊ธฐ ์ํด ๋ฑ๋กํ ์ ์๋ addCategorySort
ํจ์๋ฅผ ์ ์ํฉ๋๋ค. ์ด ํจ์๋ ๋ชจ๋ ์คํ ๋ฆฌ๋ฅผ ๋ก๋ํ๊ณ ์ ๋ ฌํ์ฌ ์์ฑ๋ ํธ๋ฆฌ ๋ฒ์ฃผ ๊ตฌ์กฐ๋ฅผ ์ทจํฉ๋๋ค.
import { configure, addCategorySort } from "@kadira/storybook";
addCategorySort( categories => /* sort logic here */ );
configure(loadStories, module);
@travi ์ด๋ฆ์ด ์ค๋ณต๋ ๋ฒ์ฃผ์ ํ์์ฑ์ ๊ณ ๋ คํ์ง ์์์ง๋ง ์ค์ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ํด๊ฒฐ์ฑ ์ ๋ํ ์๊ฐ์ด ์์ต๋๊น? ์ด๊ฒ์ด ๋์๊ฒ ๋ ์ค๋ฅด๋ ๊ฒ์ด์ง๋ง ๋ ๋์ ํด๊ฒฐ์ฑ ์ด์์ ์ ์์ต๋๋ค.
const storyData = {
categories: ["Buttons"], // any category with the title "buttons"
}
const storyData = {
categories: ["Atoms.Buttons"], // any category with the title "buttons" that also has the parent category "atoms"
}
@interterned ๋๋ ์ ๊ทผ ๋ฐฉ์์ ํ๊ณ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์๋ํ๋ ๊ฒ์ ํ์๋กํ๊ฑฐ๋ ์ํ๋)๊ฐ ๊ณ ๊ธ ์ฌ์ฉ์(์๋ฒฝํ๊ฒ ์๋ํ๋ ๊ฒ์ ์ํ๋ ์ฝ๊ฐ์ ๋ ธ๋ ฅ).
@jackmccloy ์ ... ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๊ฒ์ด ๋ชจ๋ ์ฌ๋์๊ฒ ์๊ตฌ ์ฌํญ์ด๋์ด์๋ ์๋๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๋๋ค์ด ์ง์ํ๊ธฐ๋ฅผ ์ํ๋ ๋ค์ํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์๋ ๊ฒ ๊ฐ์ผ๋ฏ๋ก ์ฝ๋ฐฑ ์์คํ ์ ๋ชจ๋ ์ฌ๋์ด ์์ ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ฌ์ฉ์ ์ ์ํ ์ ์๋๋ก ํ์ฅ์ฑ์ ์ ๊ณตํ๋ ์ข์ ๋ฐฉ๋ฒ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๊ฒ์ด "ํ๋ณตํ ๊ธธ"์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค์ง ์์๊น ํ๋ ๊ฑฑ์ ์ ๋์ด์ฃผ๊ธฐ ์ํด ๋ค์์ ๊ถ์ฅํฉ๋๋ค.
storydData.category
๊ฐ ๋ฌธ์์ด์ ํ์ฉํ๋๋ก ํ๋ฉด ์นดํ
๊ณ ๋ฆฌ๊ฐ ์ต์์ ์นดํ
๊ณ ๋ฆฌ๊ฐ ๋ฉ๋๋ค.storydData.category
๊ฐ ๋ฐฐ์ด์ ์์๊ฐ ๋ฒ์ฃผ์ ๋ํ ๊ฒฝ๋ก์ธ ๋ฐฐ์ด์ ํ์ฉํ๋๋ก ํฉ๋๋ค.// given
storydData.category = ["grand parent", "parent", "story category"];
// category tree would look like:
categories = {
"grand parent": {
"parent": {
"story category": /* the story lives here */
}
}
};
์ ์ฌํ๊ฒ ์ ๋ ฌ์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ธฐ๋ณธ ์ ๋ต(์ํ)์ ์ง์ํ ์ ์์ผ๋ฉฐ ํ์ํ ๊ฒฝ์ฐ ์ฌ์ ๊ตฌ์ถ๋ ๋ค๋ฅธ ์ ๋ ฌ ์ ๋ต(๊ฐ์ฒด ๋ชจ์์ ๋ฐ๋ฅธ ์ ๋ ฌ, ๋ฉํ ๋ฐ์ดํฐ์ ์ธ๋ฑ์ค ์ ๋ ฌ ๋ฑ...)์ ์ ๊ณตํ ์ ์์ต๋๋ค.
@ndelangen ์์ผ๋ก ๋์๊ฐ ๋ณด์ญ๋๊น ? ์์ ์ค์ธ ์ฌ๋์ด ์์ต๋๊น? ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ฃผ๋ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋๊ตฐ๊ฐ๊ฐ ์์
์ ์์ํ๊ณ ๊ทธ๋ค์ ์๋ฃจ์
์ด ์คํ ๊ฐ๋ฅํ๋ค๋ ์๋ฆผ์ ๋ฐ์ผ๋ฉด PR needed
๋ ์ด๋ธ์ ์ ๊ฑฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ด๊ฒ์ ํ์ฌ ๋ก๋๋งต์ ์์ง๋ง ์์ง ์์
์ด ์๋ฃ๋์ง ์์์ต๋๋ค.
์์ํ๊ณ ์ถ๋ค๋ฉด ๋งค์ฐ ํ์ํฉ๋๋ค!
@jackmccloy ๊ด์ฐฎ์ผ์๋ค๋ฉด ์ ๋ ์ด ์์ ์ ์ฐธ์ฌํด์ ์ฐธ์ฌํด๋ ๋ ๊น์?
@UsulPro 100%, ๋๋ ๊ทธ๊ฒ์ ๋ํด ํฅ๋ถํ ๊ฒ์ ๋๋ค. ์ผ์์ผ ์คํ(NYC ์๊ฐ)์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ดํด๋ณด๊ธฐ ์์ํ ๊ณํ์ ๋๋ค. ๋์์ ์จ๋ผ์ธ ์ํ๊ฐ ๋๋ฉด lmk์ ์ฐ๋ฆฌ๊ฐ ๋ํ๋ฅผ slack์ผ๋ก ์ด๋ํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋๋ ์กฐ๊ธ ํ๊ณ ๋ ํ ๋ช ๊ฐ์ง ์๊ฐ๊ณผ ํจ๊ป ์ฌ๊ธฐ์ ๊ฒ์ ํ ๊ฒ์ ๋๋ค.
@jackmccloy @usulpro ์ ๋ ์ด ์์ ์ ํ์คํ ๊ด์ฌ์ด ์์ต๋๋ค.
@interned ์ ๋ง ์ข์ ๊ฒ
@UsulPro ์ฃ์กํฉ๋๋ค. ์ฌํ ์์ฅ ๋ ๊ฐ์ด ์ฐ๋ฆฌ ๊ฐ์ ์ ๊ฐํํ์ต๋๋ค.
๋๋ ๊ธ์์ผ์ ์ง์ฅ์ ํดํน ๋ ์ด ์๊ณ ๊ทธ ๋ ์ผํ ๊ณํ์ ๋๋ค. ์์ํ ๊ธฐํ๊ฐ ์์์ต๋๊น? Slack๊ณผ ๋๊ธฐํํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ์ ๋ SB ์ฑ๋์ ์์ต๋๋ค.
ํ ์์ค์ ์ค์ฒฉ๋ง ํ์ํ ๊ฒฝ์ฐ React Storybook Addon Chapters ๊ฐ ํ์์ ๋ง์ ์ ์์ต๋๋ค.
์ ๋ @igor-dv ์ ๋ฐ์ด๋ ์คํ ๋ฆฌ ๊ณ์ธต ๊ตฌํ์ ์ฒซ ๋ฒ์งธ ๋ฒ์ ์ ์ถ์ํ์ผ๋ฉฐ ๋ ๋์ ์ปค๋ฎค๋ํฐ์ ์ถ์ํ๊ธฐ ์ ์ ๊ฐ์ ํ ์ ์๋๋ก ์ํ์ ๋ํ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ์ถ์ต๋๋ค.
https://gist.github.com/shilman/947a3d1d4cfdf5c3a8bb06d3d4eb84cf
@ 1i1it @andrubot @arunoda @atnovember @danielbartsch @franzihubrick @hadfieldn @iaanvn @imsnif @isuvorov @jackmccloy @joeruello @johnnyghost @lnmunhoz @majapw @markopavlovic @mystetskyivlad @mzedeler @ndelangen @nirhart @ noahprince22 @revolunet @sethkinast @theinterned @thesisb @travi @usulpro @yangshun @zeroasterisk @zvictor
์คํ ๋ฆฌ ๊ณ์ธต ๊ตฌ์กฐ์์ ๋ฐ๊ฒฌํ ์์ ๋จ์ :
๋๋ ํ ๋ฆฌ์ ํ์ ๋๋ ํ ๋ฆฌ๊ฐ ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ ๋๋ ํ ๋ฆฌ๋ฅผ ํด๋ฆญํ ๊ฒฐ๊ณผ๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค.
ํ์ ๋๋ ํ ๋ฆฌ๊ฐ ์๋ ๊ฒฝ์ฐ ํด๋๊ฐ ํ์ฅ๋์ง๋ง ์คํ ๋ฆฌ ์์ค์ ์๋ ๊ฒฝ์ฐ ์คํ ๋ฆฌ๊ฐ ์๋์ผ๋ก ์ ํ๋ฉ๋๋ค.
์ฌ์ฉ์๋ ๋ด๋ถ์ ์คํ ๋ฆฌ๋ฅผ ์ ํํ์ง ์๊ณ dir์ ๋ด์ฉ์ ๋ณด๊ณ ์ถ์ดํ ์ ์์ต๋๋ค.
react-treebeard
์์ ์ด ๋ฌธ์ ์ ๊ด๋ จ๋ ์ ์์ต๋๋ค.
https://github.com/alexcurtis/react-treebeard/issues/33
storybooks/react-treebeard
๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ํ PR์ ํ์ํ ๊ฐ์น๊ฐ ์์ ์ ์์ต๋๋ค.
์ด์ ๊ตฌํ์์ kind
์ ํํ ๋ ์ฒซ ๋ฒ์งธ ์คํ ๋ฆฌ๊ฐ ์๋ ์ ํ๋์์ต๋๋ค. ๊ทธ๋์ ์ด ๊ธฐ๋ฅ์ ๋ณด์กดํ๊ณ ์ถ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฏธ ๋ฒ๊ทธ์ฒ๋ผ ๋ณด์
๋๋ค.
๊ทธ๋ฆผ์์ Component 5
๋ ๋๋ ํ ๋ฆฌ๊ฐ ์๋๋ผ kind
์
๋๋ค.
์ฌ์ค ๋๋ ์ด๋ฐ ํ๋์ด ์ซ๋ค...
๊ธด ์ด์ผ๊ธฐ์ ์ด๋ฆ์ด ์ด์ํ๊ฒ ํฌ์ฅ๋ฉ๋๋ค.
์ฌ์ด๋๋ฐ์ ํฌ๊ธฐ๋ฅผ ์ ๋ง ์๊ฒ ์กฐ์ ํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ฐฝ์ด ์ฌ์ด๋๋ฐ์ ๋์น ์ ์์ต๋๋ค.
๊ณ์ธต ํด๋๋ฅผ ๊ฐ๋ณ ์คํ ๋ฆฌ์ ๊ฒฐํฉํ ์ ์์ต๋๊น? ์ต์์ ์์ค์์ ์ํ๋ ์คํ ๋ฆฌ๊ฐ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋จ์ผ ํญ๋ชฉ์ด ์๋ ํด๋๊ฐ ์์ต๋๋ค.
ํ์ฌ ์ด๋ ๊ฒ ํ๋ฉด
storiesOf('Something', module).add('top story');
storiesOf('Something.Chapter', module).add('substory');
๊ทธ๋ฐ ๋ค์ ํด๋๊ฐ ์๋ ํญ๋ชฉ๊ณผ ํญ๋ชฉ์ด ์๋ ํญ๋ชฉ์ธ 'Something'์ ๋ํด 2๊ฐ์ ํญ๋ชฉ์ ๋ง๋ญ๋๋ค.
@TheSisb ๊ฐ์ฌํฉ๋๋ค. ๊ณต์ ๋ฆด๋ฆฌ์ค์์ ์์ ๋ ๊ฒ์ ๋๋ค.
@psimyn , ํ์ฌ ๊ตฌํ์์๋ ๋ถ๊ฐ๋ฅํฉ๋๋ค.. ํ์ง๋ง ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.. @UsulPro ๋ ์ด๊ธฐ PR์์๋ ์ด๊ฒ์ ์ธ๊ธํ์ต๋๋ค.
IMO ์ด๊ฒ์ ์ข์ ๋์์ด ์๋๋ฉฐ ๋ ๋ณต์กํฉ๋๋ค. ๋ชจ๋ IDE์ ๋น๊ตํ๋ฉด ๋ค์์คํ์ด์ค(dirs/folders/packages)๊ฐ ์์ผ๋ฉฐ ํด๋น ๋ค์์คํ์ด์ค(๋๋ ๊ทผ์ฒ)์ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง ์ผ๋ถ ํญ๋ชฉ์ด ์์ ์ ์์ต๋๋ค.
์ด์จ๋ ์ด๊ฒ ์ปค๋ฎค๋ํฐ์์ ๋ฐ๋ผ๋ ํ๋์ด๋ผ๋ฉด ๋ฐ๊ฟ์ผ ํ๊ฒ ์ง๋ง ์ถ์๋ฅผ ์ํ ๋ง๊ฐ๋ ์ซ๋ค =)
์ด๊ฒ์ ๋ด๊ฐ ํ์ํ๋ ์ ํํ ์๋ฃจ์ ์ ๋๋ค !!! ๊ฐ์ฌํฉ๋๋ค +1
@psimyn ๊ธฐ๋ฅ์ ์ค๋ช
ํ๋ ์ ๋ฌธ์ ๋ฅผ ์ฌ์ญ์์ค. ์ด ๋ฌธ์ ๋ 3.2.0
์ ์ถ์์ ํจ๊ป ๊ณง ์ข
๋ฃ๋ฉ๋๋ค.
์ด์ ์๋ก์ด CSF ํ์์ผ๋ก ์ฌ๋ฌ ์์ค์ ์ค์ฒฉ์ด ๊ฐ๋ฅํฉ๋๊น?
@gaurav5430 ์ผ๋ง ๋์์ ๊ฐ๋ฅํ์ต๋๋ค. ์ฌ๊ธฐ์์ ์ฐ๋ฆฌ์ ์๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
๋์ฒ์์ก:
import React from 'react';
import { linkTo } from '@storybook/addon-links';
import { Welcome } from '@storybook/react/demo';
export default {
title: 'Other/Demo/Welcome',
component: Welcome,
};
export const ToStorybook = () => <Welcome showApp={linkTo('Other/Demo/Button')} />;
ToStorybook.storyName = 'to Storybook';
์๋
ํ์ธ์ @ndelangen
๊ฐ์ฌํฉ๋๋ค: https://storybook.js.org/docs/basics/writing-stories/#story -hierarchy
๋ด๊ฐ ์ํ๋ ๊ฒ์ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ ์ ๋ชฉ๋ฟ๋ง ์๋๋ผ story.name
๊ธฐ๋ฐ์ผ๋ก ํ์ ํด๋๋ฅผ ๋ง๋๋ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
export default {
title: 'Other/Demo/Welcome',
component: Welcome,
};
export const ToStorybook = () => <Welcome showApp={linkTo('Other/Demo/Button')} />;
ToStorybook.story = { name: 'to/Storybook' };
Other/Demo/Welcome/To/Storybook
์์ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ์คํ ๋ฆฌ ํ์ผ์ ๋ง๋ค๊ณ ๊ฐ๊ฐ์ ์ฌ๋ฐ๋ฅธ ๊ณ์ธต ๊ตฌ์กฐ๋ก ๊ธฐ๋ณธ๊ฐ์ ๋ด๋ณด๋ด๋ ๊ฒ์ ๋๋ค.
one.stories.js
์์์ ๊ฐ์ด :
export default {
title: 'Other/Demo/Welcome/One',
component: Welcome,
};
export const ToStorybookOne = () => <Welcome showApp={linkTo('Other/Demo/Button')} />;
๊ทธ๋ฆฌ๊ณ two.stories.js
export default {
title: 'Other/Demo/Welcome/Two',
component: Welcome,
};
export const ToStorybookTwo = () => <Welcome showApp={linkTo('Other/Demo/Button')} />;
๊ทธ๋ ๊ฒ ํ๋ฉด ๋ ์ด์ผ๊ธฐ๊ฐ ์คํ ๋ฆฌ๋ถ ํด๋ ๊ตฌ์กฐ์ ์์๋๋ก ํ์๋ฉ๋๋ค.
@gaurav5430 ๊ถ์ฅ ์ฌ์ฉ๋ฒ์ด๋ฉฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋๋๋ค. ๐
@gaurav5430 ๊ถ์ฅ ์ฌ์ฉ๋ฒ์ด๋ฉฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋๋๋ค. ๐
์, ์ด ๋ ํ์ผ์ ๋์ผํ ๊ตฌ์ฑ ์์์ ๋ค๋ฅธ ์ํ์ ๋ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ํ๊ธฐ๋ฅผ ์ฃผ์ ํ์ต๋๋ค. ํ์์ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์์๋ 2๊ฐ์ ๊ธฐ๋ณธ ์ํ์ ์ด๋ฌํ 2๊ฐ์ ๊ธฐ๋ณธ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ์ฌ๋ฌ ํ์ ์ํ๊ฐ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ตฌ์ฑ ์์์ ๋ชจ๋ ์ํ๋ฅผ ๋์ผํ ํ์ผ์ ์ ์งํ์ง๋ง ์ด ๊ฒฝ์ฐ ์คํ ๋ฆฌ์ ๊ณ์ธต ๊ตฌ์กฐ์ ๋ํด ๋ณ๋์ ํ์ผ์ด ํ์ํฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์๋ค ์!
์ด๋ฌํ ๊ธฐ๋ฅ์ด ๊ฐ๊น์ด ์ฅ๋์ ๊ณํ๋์ง ์๋๋ค๋ ์ฌ์ค์๋ ๋ถ๊ตฌํ๊ณ ์ด๊ฒ์ด Storybook Addons API๋ฅผ ํตํด ๊ทธ๋ฌํ ๋์์ ์ป์ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ์ง๋ ์์ต๋๋ค.
๋ค์์ ๊ทธ๋ฌํ ์ ๋์จ์ ๋๋ค.
์คํ ๋ฆฌ๋ถ ์ฑํฐ
์คํ ๋ฆฌ๋ถ ์ฑํฐ
(ํ์) ์คํ ๋ฆฌ์ ๋ํ ๋ฌด์ ํ ์์ค์ ์ค์ฒฉ ์ถ๊ฐ
์ค์ฒฉ ์์ค์ ํ๋ ๋ ์ถ๊ฐํ๋ ค๋ฉด ์คํ ๋ฆฌ์
.chapter(name)
๋ฅผ ์ถ๊ฐํ์ธ์.ํน์ง
Knobs
,addWithInfo
๋ฐ ๊ธฐํ ์ ๋์จ๊ณผ ํธํstoryDecorator
๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ฅ์ ๋ํํ์ญ์์ค.๋ฐ๋ชจ ํ์ด์ง
ํ๋ก์ ํธ
์์
๋ชจ๋ ํผ๋๋ฐฑ์ ๋งค์ฐ ๊ฐ์ฌํ๊ฒ ์ต๋๋ค! :)