@remember-web/primitive 0.4.8 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/src/Common/Divider/index.cjs.js +32 -23
  2. package/dist/src/Common/Divider/index.cjs.js.map +1 -1
  3. package/dist/src/Common/Divider/index.d.ts +15 -2
  4. package/dist/src/Common/Divider/index.d.ts.map +1 -1
  5. package/dist/src/Common/Divider/index.esm.js +30 -3
  6. package/dist/src/Common/Divider/index.esm.js.map +1 -1
  7. package/dist/src/ModalScreen/index.cjs.js +63 -0
  8. package/dist/src/ModalScreen/index.cjs.js.map +1 -0
  9. package/dist/src/ModalScreen/index.d.ts +23 -0
  10. package/dist/src/ModalScreen/index.d.ts.map +1 -0
  11. package/dist/src/ModalScreen/index.esm.js +57 -0
  12. package/dist/src/ModalScreen/index.esm.js.map +1 -0
  13. package/dist/src/ModalScreen/radix.cjs.js +49 -0
  14. package/dist/src/ModalScreen/radix.cjs.js.map +1 -0
  15. package/dist/src/ModalScreen/radix.d.ts +15 -0
  16. package/dist/src/ModalScreen/radix.d.ts.map +1 -0
  17. package/dist/src/ModalScreen/radix.esm.js +43 -0
  18. package/dist/src/ModalScreen/radix.esm.js.map +1 -0
  19. package/dist/src/ModalScreen/styles.cjs.js +20 -0
  20. package/dist/src/ModalScreen/styles.cjs.js.map +1 -0
  21. package/dist/src/ModalScreen/styles.d.ts +5 -0
  22. package/dist/src/ModalScreen/styles.d.ts.map +1 -0
  23. package/dist/src/ModalScreen/styles.esm.js +11 -0
  24. package/dist/src/ModalScreen/styles.esm.js.map +1 -0
  25. package/dist/src/index.cjs.js +39 -62
  26. package/dist/src/index.cjs.js.map +1 -1
  27. package/dist/src/index.d.ts +8 -7
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.esm.js +7 -13
  30. package/dist/src/index.esm.js.map +1 -1
  31. package/dist/src/radix.cjs.js +33 -0
  32. package/dist/src/radix.cjs.js.map +1 -0
  33. package/dist/src/radix.d.ts +20 -0
  34. package/dist/src/radix.d.ts.map +1 -0
  35. package/dist/src/radix.esm.js +9 -0
  36. package/dist/src/radix.esm.js.map +1 -0
  37. package/package.json +8 -4
  38. package/src/Common/Divider/index.tsx +52 -3
  39. package/src/ModalScreen/ModalScreen.Bottom.stories.tsx +308 -0
  40. package/src/ModalScreen/ModalScreen.Header.stories.tsx +261 -0
  41. package/src/ModalScreen/ModalScreen.stories.tsx +269 -0
  42. package/src/ModalScreen/index.tsx +79 -0
  43. package/src/ModalScreen/radix.tsx +77 -0
  44. package/src/ModalScreen/styles.ts +54 -0
  45. package/src/index.ts +8 -7
  46. package/src/radix.ts +24 -0
@@ -0,0 +1,308 @@
1
+ import { IconResetM } from '@remember-web/icon';
2
+ import { contents150, contents200, secondary100 } from '@remember-web/mixin';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
+ import { Button } from '@/Buttons';
5
+ import { Flex, Typography } from '@/Common';
6
+ import { Checkbox } from '@/Control';
7
+ import { ModalScreen } from './index';
8
+
9
+ const meta = {
10
+ title: 'Primitive/ModalScreen/Bottom',
11
+ component: ModalScreen.Bottom,
12
+ } satisfies Meta<typeof ModalScreen.Bottom>;
13
+
14
+ export default meta;
15
+ type Story = StoryObj<typeof ModalScreen.Bottom>;
16
+
17
+ const _PcDecorator = (Story: React.ComponentType) => (
18
+ <div
19
+ style={{
20
+ backgroundColor: '#f2f2f2',
21
+ padding: '40px',
22
+ minWidth: '400px',
23
+ }}
24
+ >
25
+ <Story />
26
+ </div>
27
+ );
28
+
29
+ const _layout = {
30
+ decorators: [_PcDecorator],
31
+ };
32
+
33
+ // ===== Bottom Stories =====
34
+ export const BottomSingleButton: Story = {
35
+ ..._layout,
36
+ name: 'SingleButton',
37
+ render: () => (
38
+ <ModalScreen.Bottom
39
+ rightElement={
40
+ <Button variant="primary" size="xLarge" layout="block">
41
+ 확인
42
+ </Button>
43
+ }
44
+ />
45
+ ),
46
+ };
47
+
48
+ export const BottomDualButtons: Story = {
49
+ ..._layout,
50
+ name: 'DualButtons',
51
+ render: () => (
52
+ <ModalScreen.Bottom
53
+ rightElement={
54
+ <Flex gap={8}>
55
+ <Button variant="outline" size="xLarge" layout="block">
56
+ 취소
57
+ </Button>
58
+ <Button variant="primary" size="xLarge" layout="block">
59
+ 확인
60
+ </Button>
61
+ </Flex>
62
+ }
63
+ />
64
+ ),
65
+ };
66
+
67
+ export const BottomWithDescription: Story = {
68
+ ..._layout,
69
+ name: 'WithDescription',
70
+ render: () => (
71
+ <ModalScreen.Bottom
72
+ leftElement={
73
+ <Typography variant="UIBody2" color={contents150}>
74
+ 선택한 프로젝트의 관심인재에 후보자를 저장합니다
75
+ </Typography>
76
+ }
77
+ rightElement={
78
+ <Button variant="primary" size="xLarge" layout="block">
79
+ 저장
80
+ </Button>
81
+ }
82
+ />
83
+ ),
84
+ };
85
+
86
+ export const BottomWithDescriptionHighlight: Story = {
87
+ ..._layout,
88
+ name: 'WithDescriptionHighlight',
89
+ render: () => (
90
+ <ModalScreen.Bottom
91
+ leftElement={
92
+ <Typography variant="UIBody2" color={contents150}>
93
+ 선택한 프로젝트의{' '}
94
+ <span style={{ color: secondary100 }}>관심인재</span>에 후보자를
95
+ 저장합니다
96
+ </Typography>
97
+ }
98
+ rightElement={
99
+ <Button variant="primary" size="xLarge" layout="block">
100
+ 제출
101
+ </Button>
102
+ }
103
+ />
104
+ ),
105
+ };
106
+
107
+ export const BottomWithLongDescription: Story = {
108
+ ..._layout,
109
+ name: 'WithLongDescription',
110
+ render: () => (
111
+ <ModalScreen.Bottom
112
+ leftElement={
113
+ <Typography variant="UIBody2" color={contents150}>
114
+ 선택한 프로젝트의 관심인재에 후보자를 저장합니다선택한 프로젝트의
115
+ 관심인재에 후보자를 저장합니다선택한 프로젝트의 관심인재에 후보자를
116
+ 저장합니다선택한 프로젝트의 관심인재에 후보자를 저장합니다선택한
117
+ 프로젝트의 관심인재에 후보자를 저장합니다
118
+ </Typography>
119
+ }
120
+ rightElement={
121
+ <Button variant="primary" size="xLarge" layout="block">
122
+ 제출
123
+ </Button>
124
+ }
125
+ />
126
+ ),
127
+ };
128
+
129
+ export const BottomWithOptionButton: Story = {
130
+ ..._layout,
131
+ name: 'WithOptionButton',
132
+ render: () => (
133
+ <ModalScreen.Bottom
134
+ leftElement={
135
+ <button
136
+ type="button"
137
+ style={{
138
+ all: 'unset',
139
+ display: 'flex',
140
+ alignItems: 'center',
141
+ gap: '4px',
142
+ }}
143
+ >
144
+ <IconResetM />
145
+ <span>선택 초기화</span>
146
+ </button>
147
+ }
148
+ rightElement={
149
+ <Button variant="primary" size="xLarge" layout="block">
150
+ 적용
151
+ </Button>
152
+ }
153
+ />
154
+ ),
155
+ };
156
+
157
+ export const BottomCompleteExample: Story = {
158
+ ..._layout,
159
+ name: 'CompleteExample',
160
+ render: () => (
161
+ <ModalScreen.Bottom
162
+ leftElement={
163
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
164
+ <Checkbox name="agree" variant="checkbox" />
165
+ <label htmlFor="agree">
166
+ <Typography variant="UIBody2" color={contents200}>
167
+ 다시 보지 않기
168
+ </Typography>
169
+ </label>
170
+ </div>
171
+ }
172
+ rightElement={
173
+ <Button variant="primary" size="xLarge" layout="block">
174
+ 확인
175
+ </Button>
176
+ }
177
+ />
178
+ ),
179
+ };
180
+
181
+ export const WithoutDivider: Story = {
182
+ ..._layout,
183
+ name: 'WithoutDivider',
184
+ render: () => (
185
+ <ModalScreen.Bottom
186
+ divider={false}
187
+ rightElement={
188
+ <Button variant="primary" size="xLarge" layout="block">
189
+ 확인
190
+ </Button>
191
+ }
192
+ />
193
+ ),
194
+ };
195
+
196
+ // ===== Mobile Type =====
197
+ const _mobileLayout = {
198
+ parameters: {
199
+ layout: 'fullscreen',
200
+ },
201
+ globals: {
202
+ viewport: { value: 'mobile1', isRotated: false },
203
+ },
204
+ };
205
+
206
+ export const MobileSingleButton: Story = {
207
+ ..._mobileLayout,
208
+ name: 'Mobile/SingleButton',
209
+ render: () => (
210
+ <ModalScreen.Bottom
211
+ rightElement={
212
+ <Button variant="primary" size="xLarge" layout="block">
213
+ 확인
214
+ </Button>
215
+ }
216
+ />
217
+ ),
218
+ };
219
+
220
+ export const MobileDualButtons: Story = {
221
+ ..._mobileLayout,
222
+ name: 'Mobile/DualButtons',
223
+ render: () => (
224
+ <ModalScreen.Bottom
225
+ rightElement={
226
+ <Flex gap={8}>
227
+ <Button variant="outline" size="xLarge" layout="block">
228
+ 취소
229
+ </Button>
230
+ <Button variant="primary" size="xLarge" layout="block">
231
+ 확인
232
+ </Button>
233
+ </Flex>
234
+ }
235
+ />
236
+ ),
237
+ };
238
+
239
+ export const MobileWithDescription: Story = {
240
+ ..._mobileLayout,
241
+ name: 'Mobile/WithDescription',
242
+ render: () => (
243
+ <ModalScreen.Bottom
244
+ leftElement={
245
+ <Typography variant="UIBody2" color={contents150} ellipsis={1}>
246
+ 선택한 프로젝트의 관심인재에 후보자를 저장합니다
247
+ </Typography>
248
+ }
249
+ rightElement={
250
+ <Button variant="primary" size="xLarge" layout="block">
251
+ 저장
252
+ </Button>
253
+ }
254
+ />
255
+ ),
256
+ };
257
+
258
+ export const MobileWithOptionButton: Story = {
259
+ ..._mobileLayout,
260
+ name: 'Mobile/WithOptionButton',
261
+ render: () => (
262
+ <ModalScreen.Bottom
263
+ leftElement={
264
+ <button
265
+ type="button"
266
+ style={{
267
+ all: 'unset',
268
+ display: 'flex',
269
+ alignItems: 'center',
270
+ gap: '4px',
271
+ }}
272
+ >
273
+ <IconResetM />
274
+ <span>선택 초기화</span>
275
+ </button>
276
+ }
277
+ rightElement={
278
+ <Button variant="primary" size="xLarge" layout="block">
279
+ 적용
280
+ </Button>
281
+ }
282
+ />
283
+ ),
284
+ };
285
+
286
+ export const MobileCompleteExample: Story = {
287
+ ..._mobileLayout,
288
+ name: 'Mobile/CompleteExample',
289
+ render: () => (
290
+ <ModalScreen.Bottom
291
+ leftElement={
292
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
293
+ <Checkbox name="agree" variant="checkbox" />
294
+ <label htmlFor="agree">
295
+ <Typography variant="UIBody2" color={contents200}>
296
+ 다시 보지 않기
297
+ </Typography>
298
+ </label>
299
+ </div>
300
+ }
301
+ rightElement={
302
+ <Button variant="primary" size="xLarge" layout="block">
303
+ 확인
304
+ </Button>
305
+ }
306
+ />
307
+ ),
308
+ };
@@ -0,0 +1,261 @@
1
+ import { Dialog } from '@radix-ui/react-dialog';
2
+ import { IconCloseM, IconPlusS } from '@remember-web/icon';
3
+ import { contents200, secondary100 } from '@remember-web/mixin';
4
+ import type { Meta, StoryObj } from '@storybook/react-vite';
5
+ import { Button } from '@/Buttons';
6
+ import { Typography } from '@/Common';
7
+ import { ModalScreen } from './index';
8
+ import { ModalScreen as RadixModalScreen } from './radix';
9
+
10
+ const meta = {
11
+ title: 'Primitive/ModalScreen/Header',
12
+ component: ModalScreen.Header,
13
+ } satisfies Meta;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ const _PcDecorator = (Story: React.ComponentType) => (
19
+ <div
20
+ style={{
21
+ backgroundColor: '#f2f2f2',
22
+ padding: '40px',
23
+ minWidth: '400px',
24
+ }}
25
+ >
26
+ <Story />
27
+ </div>
28
+ );
29
+
30
+ const _layout = {
31
+ decorators: [_PcDecorator],
32
+ };
33
+
34
+ // ===== Default Type =====
35
+ export const DefaultBasic: Story = {
36
+ ..._layout,
37
+ name: 'Default/Basic',
38
+ args: {
39
+ type: 'default' as const,
40
+ title: '프로젝트 추가',
41
+ divider: true,
42
+ },
43
+ };
44
+
45
+ export const DefaultRadixHeader: Story = {
46
+ ..._layout,
47
+ name: 'Default/Radix Header',
48
+ args: {
49
+ type: 'default' as const,
50
+ title: '프로젝트 추가',
51
+ divider: true,
52
+ },
53
+ render: (args) => {
54
+ return (
55
+ <Dialog>
56
+ <RadixModalScreen.Header {...args} />
57
+ </Dialog>
58
+ );
59
+ },
60
+ };
61
+
62
+ export const DefaultWithoutDivider: Story = {
63
+ ..._layout,
64
+ name: 'Default/WithoutDivider',
65
+ args: {
66
+ type: 'default',
67
+ title: '프로젝트 추가',
68
+ divider: false,
69
+ },
70
+ };
71
+
72
+ export const DefaultWithRightElement: Story = {
73
+ ..._layout,
74
+ name: 'Default/WithRightElement',
75
+ args: {
76
+ type: 'default' as const,
77
+ title: '프로젝트 추가',
78
+ rightElement: (
79
+ <button type="button" style={{ all: 'unset' }}>
80
+ <IconCloseM />
81
+ </button>
82
+ ),
83
+ },
84
+ };
85
+
86
+ // ===== Vertical Type =====
87
+ export const VerticalBasic: Story = {
88
+ ..._layout,
89
+ name: 'Vertical/Basic',
90
+ args: {
91
+ type: 'vertical' as const,
92
+ title: '후보자 폴더 편집',
93
+ description: (
94
+ <Typography variant="UIBody2" color={contents200}>
95
+ 입력된 정보는{' '}
96
+ <span style={{ color: secondary100 }}>적합 인재 자동 추천</span>에
97
+ 활용되며, <span style={{ color: secondary100 }}>제안 발송</span> 시에
98
+ 사용됩니다.
99
+ </Typography>
100
+ ),
101
+ },
102
+ };
103
+
104
+ export const VerticalWithRightElement: Story = {
105
+ ..._layout,
106
+ name: 'Vertical/WithRightElement',
107
+ args: {
108
+ type: 'vertical' as const,
109
+ title: '채용 포지션 생성',
110
+ description: (
111
+ <Typography variant="UIBody2" color={contents200}>
112
+ <span style={{ color: secondary100 }}>공고 등록</span> 및{' '}
113
+ <span style={{ color: secondary100 }}>인재검색</span>을 위해 포지션을
114
+ 생성해야 합니다.
115
+ </Typography>
116
+ ),
117
+ rightElement: (
118
+ <button type="button" style={{ all: 'unset' }}>
119
+ <IconCloseM />
120
+ </button>
121
+ ),
122
+ },
123
+ };
124
+
125
+ export const VerticalLongDescription: Story = {
126
+ ..._layout,
127
+ name: 'Vertical/LongDescription',
128
+ args: {
129
+ type: 'vertical' as const,
130
+ title: '회원 정보 수정',
131
+ description:
132
+ '정확한 정보를 입력하면 더 나은 매칭이 가능합니다. 회사명, 직무, 경력 기간 등을 상세히 입력해주세요.',
133
+ rightElement: (
134
+ <Button variant="outline" size="small" icon={<IconPlusS />} type="button">
135
+ 새 포지션 추가
136
+ </Button>
137
+ ),
138
+ },
139
+ };
140
+
141
+ // ===== Horizontal Type =====
142
+ export const HorizontalBasic: Story = {
143
+ ..._layout,
144
+ name: 'Horizontal/Basic',
145
+ args: {
146
+ type: 'horizontal' as const,
147
+ title: '메시지 전송',
148
+ description: '김석진 외 n명',
149
+ },
150
+ };
151
+
152
+ export const HorizontalWithRightElement: Story = {
153
+ ..._layout,
154
+ name: 'Horizontal/WithRightElement',
155
+ args: {
156
+ type: 'horizontal' as const,
157
+ title: '지역',
158
+ description: '복수 선택 가능',
159
+ rightElement: (
160
+ <button type="button" style={{ all: 'unset' }}>
161
+ <IconCloseM />
162
+ </button>
163
+ ),
164
+ },
165
+ };
166
+
167
+ // ===== Mobile Type =====
168
+ const _mobileLayout = {
169
+ parameters: {
170
+ layout: 'fullscreen',
171
+ },
172
+ globals: {
173
+ viewport: { value: 'mobile1', isRotated: false },
174
+ },
175
+ };
176
+
177
+ export const MobileBasic: Story = {
178
+ ..._mobileLayout,
179
+ name: 'Mobile/Basic',
180
+ args: {
181
+ title: '필터 적용',
182
+ divider: true,
183
+ },
184
+ };
185
+
186
+ export const MobileDefaultWithRightElement: Story = {
187
+ ..._mobileLayout,
188
+ name: 'Mobile/Default/WithRightElement',
189
+ args: {
190
+ type: 'default' as const,
191
+ title: '프로젝트 추가',
192
+ rightElement: (
193
+ <button type="button" style={{ all: 'unset' }}>
194
+ <IconCloseM />
195
+ </button>
196
+ ),
197
+ },
198
+ };
199
+
200
+ export const MobileVerticalBasic: Story = {
201
+ ..._mobileLayout,
202
+ name: 'Mobile/Vertical/Basic',
203
+ args: {
204
+ type: 'vertical' as const,
205
+ title: '후보자 폴더 편집',
206
+ description: (
207
+ <Typography variant="UIBody2" color={contents200}>
208
+ 입력된 정보는{' '}
209
+ <span style={{ color: secondary100 }}>적합 인재 자동 추천</span>에
210
+ 활용되며, <span style={{ color: secondary100 }}>제안 발송</span> 시에
211
+ 사용됩니다.
212
+ </Typography>
213
+ ),
214
+ },
215
+ };
216
+
217
+ export const MobileVerticalWithRightElement: Story = {
218
+ ..._mobileLayout,
219
+ name: 'Mobile/Vertical/WithRightElement',
220
+ args: {
221
+ type: 'vertical' as const,
222
+ title: '채용 포지션 생성',
223
+ description: (
224
+ <Typography variant="UIBody2" color={contents200}>
225
+ <span style={{ color: secondary100 }}>공고 등록</span> 및{' '}
226
+ <span style={{ color: secondary100 }}>인재검색</span>을 위해 포지션을
227
+ 생성해야 합니다.
228
+ </Typography>
229
+ ),
230
+ rightElement: (
231
+ <button type="button" style={{ all: 'unset' }}>
232
+ <IconCloseM />
233
+ </button>
234
+ ),
235
+ },
236
+ };
237
+
238
+ export const MobileHorizontalBasic: Story = {
239
+ ..._mobileLayout,
240
+ name: 'Mobile/Horizontal/Basic',
241
+ args: {
242
+ type: 'horizontal' as const,
243
+ title: '메시지 전송',
244
+ description: '김석진 외 n명',
245
+ },
246
+ };
247
+
248
+ export const MobileHorizontalWithRightElement: Story = {
249
+ ..._mobileLayout,
250
+ name: 'Mobile/Horizontal/WithRightElement',
251
+ args: {
252
+ type: 'horizontal' as const,
253
+ title: '지역',
254
+ description: '복수 선택',
255
+ rightElement: (
256
+ <button type="button" style={{ all: 'unset' }}>
257
+ <IconCloseM />
258
+ </button>
259
+ ),
260
+ },
261
+ };