@causw/core 0.0.8 → 0.0.10

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.
package/dist/index.mjs CHANGED
@@ -1,8 +1,13 @@
1
- import React from 'react';
1
+ import React4, { createContext, useId, useState, useContext } from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { Slot } from '@radix-ui/react-slot';
4
6
 
5
7
  // src/components/Text/Text.tsx
8
+ function mergeStyles(...inputs) {
9
+ return twMerge(clsx(inputs));
10
+ }
6
11
 
7
12
  // src/components/Text/Text.styles.ts
8
13
  var colorClasses = {
@@ -16,7 +21,7 @@ var colorClasses = {
16
21
  "gray-700": "text-gray-700",
17
22
  "gray-800": "text-gray-800",
18
23
  "gray-900": "text-gray-900",
19
- "blue-50": "text-blue-50",
24
+ "blue-100": "text-blue-100",
20
25
  "blue-500": "text-blue-500",
21
26
  "blue-700": "text-blue-700",
22
27
  "red-100": "text-red-100",
@@ -24,245 +29,859 @@ var colorClasses = {
24
29
  white: "text-white-main",
25
30
  black: "text-black-main"
26
31
  };
27
- var variantStyles = {
28
- caption: {
29
- sm: {
30
- normal: {
31
- fontSize: "text-12",
32
- lineHeight: "leading-normal",
33
- fontWeight: "font-regular"
34
- },
35
- point: {
36
- fontSize: "text-12",
37
- lineHeight: "leading-normal",
38
- fontWeight: "font-semibold"
39
- }
32
+ var alignClasses = {
33
+ left: "text-left",
34
+ center: "text-center",
35
+ right: "text-right",
36
+ justify: "text-justify"
37
+ };
38
+ var typographyStyles = {
39
+ // Caption variants
40
+ "caption-sm": "typo-caption-sm",
41
+ "caption-sm-point": "typo-caption-sm-point",
42
+ "caption-md": "typo-caption-md",
43
+ "caption-md-point": "typo-caption-md-point",
44
+ // Body2 variants
45
+ "body2-sm": "typo-body2-sm",
46
+ "body2-sm-point": "typo-body2-sm-point",
47
+ "body2-md": "typo-body2-md",
48
+ "body2-md-point": "typo-body2-md-point",
49
+ // Body variants
50
+ "body-sm": "typo-body-sm",
51
+ "body-sm-point": "typo-body-sm-point",
52
+ "body-md": "typo-body-md",
53
+ "body-md-point": "typo-body-md-point",
54
+ // Subtitle variants
55
+ "subtitle-sm": "typo-subtitle-sm",
56
+ "subtitle-sm-point": "typo-subtitle-sm-point",
57
+ "subtitle-md": "typo-subtitle-md",
58
+ "subtitle-md-point": "typo-subtitle-md-point",
59
+ // Title variants (always bold)
60
+ "title-sm": "typo-title-sm",
61
+ "title-md": "typo-title-md",
62
+ // Head variants (always bold)
63
+ "head-sm": "typo-head-sm",
64
+ "head-md": "typo-head-md",
65
+ // Fixed size variants
66
+ "fixed-12": "typo-fixed-12",
67
+ "fixed-14": "typo-fixed-14",
68
+ "fixed-15": "typo-fixed-15",
69
+ "fixed-16": "typo-fixed-16",
70
+ "fixed-18": "typo-fixed-18",
71
+ "fixed-20": "typo-fixed-20",
72
+ "fixed-24": "typo-fixed-24"
73
+ };
74
+ function textStyles({
75
+ typography,
76
+ textColor,
77
+ align
78
+ }) {
79
+ const baseStyles4 = "font-sans";
80
+ const colorClass = colorClasses[textColor];
81
+ const typographyClass = typographyStyles[typography];
82
+ const alignClass = align ? alignClasses[align] : "";
83
+ return mergeStyles([baseStyles4, colorClass, typographyClass, alignClass]);
84
+ }
85
+
86
+ // src/components/Text/Text.tsx
87
+ var Text = ({
88
+ typography = "body-sm",
89
+ textColor = "gray-700",
90
+ align,
91
+ as,
92
+ children,
93
+ className = "",
94
+ ...props
95
+ }) => {
96
+ const Component = as || "span";
97
+ const classes = textStyles({ typography, textColor, align });
98
+ return React4.createElement(
99
+ Component,
100
+ {
101
+ className: mergeStyles(classes, className),
102
+ ...props
40
103
  },
41
- md: {
42
- normal: {
43
- fontSize: "text-14",
44
- lineHeight: "leading-normal",
45
- fontWeight: "font-medium"
46
- },
47
- point: {
48
- fontSize: "text-14",
49
- lineHeight: "leading-normal",
50
- fontWeight: "font-semibold"
51
- }
104
+ children
105
+ );
106
+ };
107
+ Text.displayName = "Text";
108
+ var FieldContext = createContext(null);
109
+ var useFieldContext = () => {
110
+ const context = useContext(FieldContext);
111
+ if (!context) {
112
+ return null;
113
+ }
114
+ return context;
115
+ };
116
+ var FieldRoot = ({
117
+ children,
118
+ disabled = false,
119
+ error = false,
120
+ className,
121
+ ...props
122
+ }) => {
123
+ const id = useId();
124
+ return /* @__PURE__ */ jsx(FieldContext.Provider, { value: { id, disabled, error }, children: /* @__PURE__ */ jsx("div", { className: mergeStyles("flex flex-col gap-2", className), ...props, children }) });
125
+ };
126
+ var FieldLabel = ({
127
+ children,
128
+ className,
129
+ typography = "body-sm-point",
130
+ textColor = "gray-700",
131
+ ...labelProps
132
+ }) => {
133
+ const fieldContext = useFieldContext();
134
+ const id = fieldContext?.id;
135
+ return /* @__PURE__ */ jsx(
136
+ Text,
137
+ {
138
+ typography,
139
+ textColor,
140
+ htmlFor: id,
141
+ className: mergeStyles("px-1", className),
142
+ ...labelProps,
143
+ children
52
144
  }
53
- },
54
- body2: {
55
- sm: {
56
- normal: {
57
- fontSize: "text-14",
58
- lineHeight: "leading-normal",
59
- fontWeight: "font-regular"
60
- },
61
- point: {
62
- fontSize: "text-14",
63
- lineHeight: "leading-normal",
64
- fontWeight: "font-semibold"
65
- }
66
- },
67
- md: {
68
- normal: {
69
- fontSize: "text-16",
70
- lineHeight: "leading-normal",
71
- fontWeight: "font-medium"
72
- },
73
- point: {
74
- fontSize: "text-16",
75
- lineHeight: "leading-normal",
76
- fontWeight: "font-semibold"
77
- }
145
+ );
146
+ };
147
+ var FieldDescription = ({
148
+ children,
149
+ className,
150
+ ...props
151
+ }) => {
152
+ const fieldContext = useFieldContext();
153
+ const id = fieldContext?.id;
154
+ const error = fieldContext?.error;
155
+ if (error) return null;
156
+ return /* @__PURE__ */ jsx(
157
+ Text,
158
+ {
159
+ typography: "body2-sm",
160
+ textColor: "gray-400",
161
+ id: id ? `${id}-description` : void 0,
162
+ className,
163
+ ...props,
164
+ children
78
165
  }
79
- },
80
- body: {
81
- sm: {
82
- normal: {
83
- fontSize: "text-16",
84
- lineHeight: "leading-tight",
85
- fontWeight: "font-regular"
86
- },
87
- point: {
88
- fontSize: "text-16",
89
- lineHeight: "leading-normal",
90
- fontWeight: "font-bold"
91
- }
92
- },
93
- md: {
94
- normal: {
95
- fontSize: "text-18",
96
- lineHeight: "leading-normal",
97
- fontWeight: "font-medium"
98
- },
99
- point: {
100
- fontSize: "text-18",
101
- lineHeight: "leading-normal",
102
- fontWeight: "font-bold"
103
- }
166
+ );
167
+ };
168
+ var FieldErrorDescription = ({
169
+ children,
170
+ className,
171
+ ...props
172
+ }) => {
173
+ const fieldContext = useFieldContext();
174
+ const id = fieldContext?.id;
175
+ const error = fieldContext?.error;
176
+ if (!error) return null;
177
+ return /* @__PURE__ */ jsx(
178
+ Text,
179
+ {
180
+ typography: "body2-sm",
181
+ textColor: "red-400",
182
+ id: id ? `${id}-error` : void 0,
183
+ className,
184
+ ...props,
185
+ children
104
186
  }
105
- },
106
- subtitle: {
107
- sm: {
108
- normal: {
109
- fontSize: "text-18",
110
- lineHeight: "leading-normal",
111
- fontWeight: "font-medium"
112
- },
113
- point: {
114
- fontSize: "text-18",
115
- lineHeight: "leading-normal",
116
- fontWeight: "font-bold"
117
- }
118
- },
119
- md: {
120
- normal: {
121
- fontSize: "text-20",
122
- lineHeight: "leading-normal",
123
- fontWeight: "font-medium"
124
- },
125
- point: {
126
- fontSize: "text-20",
127
- lineHeight: "leading-normal",
128
- fontWeight: "font-bold"
187
+ );
188
+ };
189
+ FieldRoot.displayName = "Field";
190
+ FieldLabel.displayName = "Field.Label";
191
+ FieldDescription.displayName = "Field.Description";
192
+ FieldErrorDescription.displayName = "Field.ErrorDescription";
193
+ var Field = Object.assign(FieldRoot, {
194
+ Label: FieldLabel,
195
+ Description: FieldDescription,
196
+ ErrorDescription: FieldErrorDescription
197
+ });
198
+ var TextInput = ({
199
+ id: idProp,
200
+ disabled: disabledProp,
201
+ error: errorProp,
202
+ className,
203
+ leftIcon,
204
+ rightIcon,
205
+ variant = "default",
206
+ typography = "body2-sm",
207
+ textColor = "gray-700",
208
+ ...props
209
+ }) => {
210
+ const field = useFieldContext();
211
+ const id = idProp ?? field?.id;
212
+ const disabled = disabledProp ?? field?.disabled ?? false;
213
+ const error = errorProp ?? field?.error ?? false;
214
+ const classes = textStyles({ typography, textColor });
215
+ const inputStyles = mergeStyles(
216
+ "w-full bg-transparent outline-none",
217
+ "placeholder:text-gray-400",
218
+ "caret-gray-600"
219
+ );
220
+ const variantStyles = {
221
+ default: mergeStyles(
222
+ "rounded-md p-4",
223
+ "bg-white",
224
+ "focus-within:ring-2 focus-within:ring-gray-600"
225
+ ),
226
+ underline: mergeStyles(
227
+ "py-2 px-0",
228
+ "border-b border-gray-400",
229
+ "bg-transparent",
230
+ "focus-within:border-gray-600"
231
+ )
232
+ };
233
+ const wrapperStyles = mergeStyles(
234
+ "flex items-center gap-2 self-stretch",
235
+ variantStyles[variant],
236
+ disabled && "cursor-not-allowed opacity-50",
237
+ error && variant === "default" && "ring-2 ring-red-400 focus-within:ring-red-400",
238
+ error && variant === "underline" && "border-red-400 focus-within:border-red-400",
239
+ className
240
+ );
241
+ return /* @__PURE__ */ jsxs("div", { className: wrapperStyles, children: [
242
+ leftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-gray-400", children: leftIcon }),
243
+ /* @__PURE__ */ jsx(
244
+ "input",
245
+ {
246
+ id,
247
+ disabled,
248
+ className: mergeStyles(inputStyles, classes),
249
+ ...props
129
250
  }
251
+ ),
252
+ rightIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-gray-400", children: rightIcon })
253
+ ] });
254
+ };
255
+ TextInput.displayName = "TextInput";
256
+ function createPrimitive(node) {
257
+ const Node = (props) => {
258
+ const { asChild, ...primitiveProps } = props;
259
+ const Comp = asChild ? Slot : node;
260
+ return /* @__PURE__ */ jsx(Comp, { ...primitiveProps });
261
+ };
262
+ Node.displayName = `Primitive.${node}`;
263
+ return Node;
264
+ }
265
+ var Primitive = {
266
+ div: createPrimitive("div"),
267
+ span: createPrimitive("span"),
268
+ img: createPrimitive("img"),
269
+ button: createPrimitive("button"),
270
+ label: createPrimitive("label"),
271
+ input: createPrimitive("input"),
272
+ textarea: createPrimitive("textarea"),
273
+ a: createPrimitive("a"),
274
+ p: createPrimitive("p"),
275
+ h2: createPrimitive("h2"),
276
+ ul: createPrimitive("ul"),
277
+ li: createPrimitive("li"),
278
+ svg: createPrimitive("svg"),
279
+ circle: createPrimitive("circle")
280
+ };
281
+ var TextAreaRoot = ({ className, children, ...props }) => {
282
+ const field = useFieldContext();
283
+ const wrapperStyles = mergeStyles(
284
+ "rounded-md p-4",
285
+ "bg-white",
286
+ "focus-within:ring-2 focus-within:ring-gray-600",
287
+ field?.disabled && "cursor-not-allowed opacity-50",
288
+ field?.error && "ring-2 ring-red-400 focus-within:ring-red-400",
289
+ className
290
+ );
291
+ return /* @__PURE__ */ jsx(Primitive.div, { className: wrapperStyles, ...props, children });
292
+ };
293
+ var TextAreaInput = ({
294
+ resize = true,
295
+ disabled: disabledProp,
296
+ className,
297
+ ...props
298
+ }) => {
299
+ const field = useFieldContext();
300
+ const disabled = disabledProp ?? field?.disabled ?? false;
301
+ const textareaStyles = mergeStyles(
302
+ "w-full min-w-0 min-h-10 bg-transparent outline-none",
303
+ "typo-body-sm",
304
+ "text-gray-700 placeholder:text-gray-400",
305
+ "caret-gray-600",
306
+ resize ? "resize-y" : "resize-none",
307
+ disabled && "cursor-not-allowed",
308
+ className
309
+ );
310
+ return /* @__PURE__ */ jsx("textarea", { className: textareaStyles, disabled, ...props });
311
+ };
312
+ var TextAreaFooter = ({
313
+ className,
314
+ children,
315
+ ...props
316
+ }) => {
317
+ return /* @__PURE__ */ jsx(Primitive.div, { className: mergeStyles("mt-2", className), ...props, children });
318
+ };
319
+ TextAreaRoot.displayName = "TextArea";
320
+ TextAreaInput.displayName = "TextArea.Input";
321
+ TextAreaFooter.displayName = "TextArea.Footer";
322
+ var TextArea = Object.assign(TextAreaRoot, {
323
+ Input: TextAreaInput,
324
+ Footer: TextAreaFooter
325
+ });
326
+ var RadioGroupContext = createContext(null);
327
+ var useRadioGroupContext = () => {
328
+ return useContext(RadioGroupContext);
329
+ };
330
+ var RadioGroup = ({
331
+ name,
332
+ value,
333
+ defaultValue,
334
+ onValueChange,
335
+ className,
336
+ children,
337
+ ...props
338
+ }) => {
339
+ const [internalValue, setInternalValue] = React4.useState(defaultValue);
340
+ const currentValue = value ?? internalValue;
341
+ const handleChange = (newValue) => {
342
+ if (value === void 0) {
343
+ setInternalValue(newValue);
130
344
  }
131
- },
132
- title: {
133
- sm: {
134
- normal: {
135
- fontSize: "text-22",
136
- lineHeight: "leading-normal",
137
- fontWeight: "font-bold"
138
- },
139
- point: {
140
- fontSize: "text-22",
141
- lineHeight: "leading-normal",
142
- fontWeight: "font-bold"
143
- }
144
- },
145
- md: {
146
- normal: {
147
- fontSize: "text-32",
148
- lineHeight: "leading-normal",
149
- fontWeight: "font-bold"
150
- },
151
- point: {
152
- fontSize: "text-32",
153
- lineHeight: "leading-normal",
154
- fontWeight: "font-bold"
155
- }
345
+ onValueChange?.(newValue);
346
+ };
347
+ return /* @__PURE__ */ jsx(
348
+ RadioGroupContext.Provider,
349
+ {
350
+ value: { name, value: currentValue, onChange: handleChange },
351
+ children: /* @__PURE__ */ jsx(
352
+ Primitive.div,
353
+ {
354
+ role: "radiogroup",
355
+ className: mergeStyles("flex flex-col gap-5", className),
356
+ ...props,
357
+ children
358
+ }
359
+ )
156
360
  }
157
- },
158
- head: {
159
- sm: {
160
- normal: {
161
- fontSize: "text-30",
162
- lineHeight: "leading-normal",
163
- fontWeight: "font-bold"
164
- },
165
- point: {
166
- fontSize: "text-30",
167
- lineHeight: "leading-normal",
168
- fontWeight: "font-bold"
169
- }
170
- },
171
- md: {
172
- normal: {
173
- fontSize: "text-48",
174
- lineHeight: "leading-normal",
175
- fontWeight: "font-bold"
176
- },
177
- point: {
178
- fontSize: "text-48",
179
- lineHeight: "leading-normal",
180
- fontWeight: "font-bold"
361
+ );
362
+ };
363
+ var RadioIcon = ({ checked }) => /* @__PURE__ */ jsx(
364
+ "svg",
365
+ {
366
+ xmlns: "http://www.w3.org/2000/svg",
367
+ width: "20",
368
+ height: "20",
369
+ viewBox: "0 0 20 20",
370
+ fill: "none",
371
+ className: "transition-all duration-150 ease-in-out",
372
+ children: /* @__PURE__ */ jsx(
373
+ "circle",
374
+ {
375
+ cx: "10",
376
+ cy: "10",
377
+ r: checked ? 7 : 7.5,
378
+ stroke: "currentColor",
379
+ strokeWidth: checked ? 6 : 5,
380
+ className: "transition-all duration-150 ease-in-out"
181
381
  }
382
+ )
383
+ }
384
+ );
385
+ var Radio = ({
386
+ value,
387
+ children,
388
+ className,
389
+ checked: checkedProp,
390
+ onChange,
391
+ ...props
392
+ }) => {
393
+ const group = useRadioGroupContext();
394
+ const isChecked = group ? group.value === value : checkedProp;
395
+ const name = group?.name ?? props.name;
396
+ const handleChange = (e) => {
397
+ group?.onChange?.(value);
398
+ onChange?.(e);
399
+ };
400
+ return /* @__PURE__ */ jsxs(
401
+ "label",
402
+ {
403
+ className: mergeStyles(
404
+ "flex cursor-pointer items-center gap-2",
405
+ "transition-opacity duration-150 hover:opacity-80",
406
+ className
407
+ ),
408
+ children: [
409
+ /* @__PURE__ */ jsx(
410
+ "input",
411
+ {
412
+ type: "radio",
413
+ name,
414
+ value,
415
+ checked: isChecked,
416
+ onChange: handleChange,
417
+ className: "sr-only",
418
+ ...props
419
+ }
420
+ ),
421
+ /* @__PURE__ */ jsx(
422
+ "span",
423
+ {
424
+ className: mergeStyles(
425
+ "flex-shrink-0 transition-colors duration-150",
426
+ isChecked ? "text-gray-800 hover:text-gray-800" : "text-gray-200 hover:text-gray-400"
427
+ ),
428
+ children: /* @__PURE__ */ jsx(RadioIcon, { checked: !!isChecked })
429
+ }
430
+ ),
431
+ /* @__PURE__ */ jsx(Text, { typography: "body-sm", textColor: "gray-800", children })
432
+ ]
182
433
  }
434
+ );
435
+ };
436
+ RadioGroup.displayName = "RadioGroup";
437
+ Radio.displayName = "Radio";
438
+ var ToggleContext = React4.createContext(null);
439
+ var useToggleContext = () => {
440
+ const context = React4.useContext(ToggleContext);
441
+ if (!context) {
442
+ throw new Error(
443
+ "Toggle \uC11C\uBE0C \uCEF4\uD3EC\uB10C\uD2B8\uB294 <Toggle> \uCEF4\uD3EC\uB10C\uD2B8 \uB0B4\uBD80\uC5D0\uC11C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. ex) <Toggle><Toggle.Switch /></Toggle>"
444
+ );
183
445
  }
446
+ return context;
184
447
  };
185
- var fixedStyles = {
186
- 12: {
187
- fontSize: "text-12",
188
- lineHeight: "leading-normal",
189
- fontWeight: "font-medium"
190
- },
191
- 14: {
192
- fontSize: "text-14",
193
- lineHeight: "leading-normal",
194
- fontWeight: "font-medium"
195
- },
196
- 15: {
197
- fontSize: "text-15",
198
- lineHeight: "leading-normal",
199
- fontWeight: "font-semibold"
200
- },
201
- 16: {
202
- fontSize: "text-16",
203
- lineHeight: "leading-normal",
204
- fontWeight: "font-medium"
205
- },
206
- 18: {
207
- fontSize: "text-18",
208
- lineHeight: "leading-normal",
209
- fontWeight: "font-medium"
448
+ var ToggleRoot = ({
449
+ checked: checkedProp,
450
+ defaultChecked = false,
451
+ onCheckedChange,
452
+ disabled,
453
+ children,
454
+ className,
455
+ ...props
456
+ }) => {
457
+ const [internalChecked, setInternalChecked] = useState(defaultChecked);
458
+ const isChecked = checkedProp !== void 0 ? checkedProp : internalChecked;
459
+ const handleChange = () => {
460
+ if (disabled) return;
461
+ const newChecked = !isChecked;
462
+ if (checkedProp === void 0) {
463
+ setInternalChecked(newChecked);
464
+ }
465
+ onCheckedChange?.(newChecked);
466
+ };
467
+ return /* @__PURE__ */ jsx(ToggleContext.Provider, { value: { checked: isChecked, disabled }, children: /* @__PURE__ */ jsxs(
468
+ "label",
469
+ {
470
+ className: mergeStyles(
471
+ "inline-flex cursor-pointer items-center gap-2",
472
+ disabled && "cursor-not-allowed opacity-50",
473
+ className
474
+ ),
475
+ ...props,
476
+ children: [
477
+ /* @__PURE__ */ jsx(
478
+ "input",
479
+ {
480
+ type: "checkbox",
481
+ checked: isChecked,
482
+ onChange: handleChange,
483
+ disabled,
484
+ className: "sr-only"
485
+ }
486
+ ),
487
+ children
488
+ ]
489
+ }
490
+ ) });
491
+ };
492
+ var ToggleSwitch = () => {
493
+ const { checked } = useToggleContext();
494
+ return /* @__PURE__ */ jsx(
495
+ "span",
496
+ {
497
+ className: mergeStyles(
498
+ "relative inline-flex items-center rounded-full p-1 transition-colors duration-200 ease-in-out",
499
+ "h-7 w-12",
500
+ // 48px x 28px
501
+ checked ? "bg-gray-600" : "bg-gray-200"
502
+ ),
503
+ children: /* @__PURE__ */ jsx(
504
+ "span",
505
+ {
506
+ className: mergeStyles(
507
+ "pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform duration-200 ease-in-out",
508
+ "h-5 w-5",
509
+ // 20px
510
+ checked ? "translate-x-5" : "translate-x-0"
511
+ )
512
+ }
513
+ )
514
+ }
515
+ );
516
+ };
517
+ var ToggleLabel = ({
518
+ children,
519
+ typography = "fixed-16",
520
+ textColor = "gray-700",
521
+ ...props
522
+ }) => {
523
+ const { disabled } = useToggleContext();
524
+ return /* @__PURE__ */ jsx(
525
+ Text,
526
+ {
527
+ typography,
528
+ textColor: disabled ? "gray-400" : textColor,
529
+ ...props,
530
+ children
531
+ }
532
+ );
533
+ };
534
+ ToggleRoot.displayName = "Toggle";
535
+ ToggleSwitch.displayName = "Toggle.Switch";
536
+ ToggleLabel.displayName = "Toggle.Label";
537
+ var Toggle = Object.assign(ToggleRoot, {
538
+ Switch: ToggleSwitch,
539
+ Label: ToggleLabel
540
+ });
541
+ var CheckboxContext = React4.createContext(null);
542
+ var useCheckboxContext = () => {
543
+ const context = React4.useContext(CheckboxContext);
544
+ if (!context) {
545
+ throw new Error(
546
+ "Checkbox \uC11C\uBE0C \uCEF4\uD3EC\uB10C\uD2B8\uB294 <Checkbox> \uCEF4\uD3EC\uB10C\uD2B8 \uB0B4\uBD80\uC5D0\uC11C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. ex) <Checkbox><Checkbox.Indicator /></Checkbox>"
547
+ );
548
+ }
549
+ return context;
550
+ };
551
+ var CheckboxRoot = ({
552
+ checked: checkedProp,
553
+ defaultChecked = false,
554
+ onCheckedChange,
555
+ disabled,
556
+ children,
557
+ className,
558
+ ...props
559
+ }) => {
560
+ const [internalChecked, setInternalChecked] = useState(defaultChecked);
561
+ const isChecked = checkedProp !== void 0 ? checkedProp : internalChecked;
562
+ const handleChange = () => {
563
+ if (disabled) return;
564
+ const newChecked = !isChecked;
565
+ if (checkedProp === void 0) {
566
+ setInternalChecked(newChecked);
567
+ }
568
+ onCheckedChange?.(newChecked);
569
+ };
570
+ return /* @__PURE__ */ jsx(CheckboxContext.Provider, { value: { checked: isChecked, disabled }, children: /* @__PURE__ */ jsxs(
571
+ "label",
572
+ {
573
+ className: mergeStyles(
574
+ "inline-flex cursor-pointer items-center gap-2",
575
+ disabled && "cursor-not-allowed opacity-50",
576
+ className
577
+ ),
578
+ ...props,
579
+ children: [
580
+ /* @__PURE__ */ jsx(
581
+ "input",
582
+ {
583
+ type: "checkbox",
584
+ checked: isChecked,
585
+ onChange: handleChange,
586
+ disabled,
587
+ className: "sr-only"
588
+ }
589
+ ),
590
+ children
591
+ ]
592
+ }
593
+ ) });
594
+ };
595
+ var CheckboxIndicator = () => {
596
+ const { checked } = useCheckboxContext();
597
+ if (checked) {
598
+ return /* @__PURE__ */ jsxs(
599
+ "svg",
600
+ {
601
+ xmlns: "http://www.w3.org/2000/svg",
602
+ width: "18",
603
+ height: "18",
604
+ viewBox: "0 0 18 18",
605
+ fill: "none",
606
+ className: "flex-shrink-0",
607
+ children: [
608
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", rx: "4", fill: "#1E2939" }),
609
+ /* @__PURE__ */ jsx(
610
+ "path",
611
+ {
612
+ d: "M5 9.08333L7.94737 12L13 7",
613
+ stroke: "white",
614
+ strokeWidth: "2",
615
+ strokeLinecap: "round",
616
+ strokeLinejoin: "round"
617
+ }
618
+ )
619
+ ]
620
+ }
621
+ );
622
+ }
623
+ return /* @__PURE__ */ jsx(
624
+ "span",
625
+ {
626
+ className: mergeStyles(
627
+ "flex-shrink-0",
628
+ "aspect-square h-[18px] w-[18px]",
629
+ "rounded border-2 border-gray-200 bg-white"
630
+ )
631
+ }
632
+ );
633
+ };
634
+ var CheckboxLabel = ({
635
+ children,
636
+ typography = "body-sm",
637
+ textColor = "gray-600",
638
+ ...props
639
+ }) => {
640
+ const { disabled } = useCheckboxContext();
641
+ return /* @__PURE__ */ jsx(
642
+ Text,
643
+ {
644
+ typography,
645
+ textColor: disabled ? "gray-400" : textColor,
646
+ ...props,
647
+ children
648
+ }
649
+ );
650
+ };
651
+ CheckboxRoot.displayName = "Checkbox";
652
+ CheckboxIndicator.displayName = "Checkbox.Indicator";
653
+ CheckboxLabel.displayName = "Checkbox.Label";
654
+ var Checkbox = Object.assign(CheckboxRoot, {
655
+ Indicator: CheckboxIndicator,
656
+ Label: CheckboxLabel
657
+ });
658
+
659
+ // src/components/Button/Button.styles.ts
660
+ var baseStyles = "inline-flex items-center justify-center gap-[0.375rem] whitespace-nowrap rounded-[0.5rem] transition-colors duration-150 disabled:opacity-50 disabled:pointer-events-none";
661
+ var sizeStyles = {
662
+ sm: "min-w-[3rem] h-[1.875rem] px-[0.5rem] typo-body2-sm-point",
663
+ md: "h-[2.375rem] px-[0.75rem] typo-body2-sm-point"
664
+ };
665
+ var colorStyles = {
666
+ // base와 active에 대한 설정이 아직 정해지지 않음
667
+ white: {
668
+ base: "bg-white text-gray-400",
669
+ active: "bg-white text-gray-400"
210
670
  },
211
- 20: {
212
- fontSize: "text-20",
213
- lineHeight: "leading-normal",
214
- fontWeight: "font-semibold"
671
+ gray: {
672
+ base: "bg-gray-100 text-gray-400",
673
+ active: "bg-gray-100 text-gray-400"
215
674
  },
216
- 24: {
217
- fontSize: "text-24",
218
- lineHeight: "leading-normal",
219
- fontWeight: "font-bold"
675
+ red: {
676
+ base: "bg-red-100 text-red-400",
677
+ active: "bg-red-100 text-red-400"
220
678
  }
221
679
  };
222
- function textStyles({
223
- variant,
680
+ function buttonStyles({
224
681
  size,
225
- fixedSize,
226
- point,
227
- color
682
+ color,
683
+ active = false,
684
+ disabled = false,
685
+ fullWidth = false
228
686
  }) {
229
- const baseStyles = "font-sans";
230
- const colorClass = colorClasses[color];
231
- let config;
232
- if (variant === "fixed" && fixedSize) {
233
- config = fixedStyles[fixedSize];
234
- } else if (variant !== "fixed") {
235
- const variantConfig = variantStyles[variant][size];
236
- config = point ? variantConfig.point : variantConfig.normal;
237
- } else {
238
- config = fixedStyles[16];
239
- }
240
- return `${baseStyles} ${colorClass} ${config.fontSize} ${config.lineHeight} ${config.fontWeight}`.trim();
687
+ return mergeStyles(
688
+ baseStyles,
689
+ disabled ? "cursor-not-allowed pointer-events-none" : "cursor-pointer",
690
+ sizeStyles[size],
691
+ active ? colorStyles[color].active : colorStyles[color].base,
692
+ fullWidth && "w-full"
693
+ );
241
694
  }
242
- function mergeStyles(...inputs) {
243
- return twMerge(clsx(inputs));
695
+ function Button({
696
+ size = "md",
697
+ color = "gray",
698
+ active = false,
699
+ fullWidth = false,
700
+ disabled = false,
701
+ children,
702
+ ...props
703
+ }) {
704
+ return /* @__PURE__ */ jsx(
705
+ "button",
706
+ {
707
+ className: buttonStyles({
708
+ size,
709
+ color,
710
+ active,
711
+ disabled,
712
+ fullWidth
713
+ }),
714
+ disabled,
715
+ ...props,
716
+ children
717
+ }
718
+ );
244
719
  }
245
720
 
246
- // src/components/Text/Text.tsx
247
- var Text = ({
248
- variant = "body",
249
- size = "sm",
250
- fixedSize,
251
- point = false,
252
- color = "gray-700",
253
- as: Component = "span",
721
+ // src/components/CTAButton/CTAButton.styles.ts
722
+ var baseStyles2 = "inline-flex items-center justify-center h-[3.375rem] px-[0.5rem] rounded-[0.75rem] typo-fixed-15 whitespace-nowrap select-none transition-colors";
723
+ var widthStyles = {
724
+ default: "w-[18rem]",
725
+ full: "w-full"
726
+ };
727
+ var colorStyles2 = {
728
+ blue: "bg-blue-100 text-blue-700",
729
+ red: "bg-red-400 text-white",
730
+ dark: "bg-gray-700 text-white",
731
+ light: "bg-gray-100 text-gray-500",
732
+ white: "bg-white text-gray-500",
733
+ disabled: "bg-gray-200 text-gray-300"
734
+ };
735
+ function ctaButtonStyles({
736
+ color,
737
+ fullWidth = false,
738
+ disabled = false
739
+ }) {
740
+ return mergeStyles(
741
+ baseStyles2,
742
+ fullWidth ? widthStyles.full : widthStyles.default,
743
+ colorStyles2[disabled ? "disabled" : color],
744
+ disabled ? "pointer-events-none" : "cursor-pointer"
745
+ );
746
+ }
747
+ function CTAButton({
748
+ color = "light",
749
+ fullWidth = false,
750
+ disabled = false,
751
+ asChild = false,
752
+ className,
254
753
  children,
754
+ ...props
755
+ }) {
756
+ const Component = asChild ? Slot : "button";
757
+ return /* @__PURE__ */ jsx(
758
+ Component,
759
+ {
760
+ type: asChild ? void 0 : "button",
761
+ disabled,
762
+ className: mergeStyles(
763
+ ctaButtonStyles({ color, fullWidth, disabled }),
764
+ className
765
+ ),
766
+ ...props,
767
+ children
768
+ }
769
+ );
770
+ }
771
+
772
+ // src/components/FloatingActionButton/FloatingActionButton.styles.ts
773
+ var baseStyles3 = "inline-flex items-center justify-center bg-gray-100 border border-gray-200 text-gray-500 typo-body-sm-point h-[2.875rem] rounded-[6.1875rem] select-none whitespace-nowrap transition-colors";
774
+ var paddingStyles = "px-[1rem] py-[0.625rem]";
775
+ var iconGapStyles = {
776
+ left: "gap-[0.25rem]",
777
+ right: "gap-[0.625rem]",
778
+ none: ""
779
+ };
780
+ function floatingActionButtonStyles({
781
+ iconPosition = "none",
782
+ disabled = false
783
+ }) {
784
+ return mergeStyles(
785
+ baseStyles3,
786
+ paddingStyles,
787
+ iconGapStyles[iconPosition],
788
+ disabled ? "opacity-50 pointer-events-none" : "cursor-pointer"
789
+ );
790
+ }
791
+ function FloatingActionButton({
792
+ leftIcon,
793
+ rightIcon,
794
+ disabled = false,
795
+ asChild = false,
796
+ children,
797
+ className,
798
+ ...props
799
+ }) {
800
+ const iconPosition = leftIcon ? "left" : rightIcon ? "right" : "none";
801
+ const Component = asChild ? Slot : "button";
802
+ return /* @__PURE__ */ jsxs(
803
+ Component,
804
+ {
805
+ type: asChild ? void 0 : "button",
806
+ disabled,
807
+ className: mergeStyles(
808
+ floatingActionButtonStyles({ iconPosition, disabled }),
809
+ className
810
+ ),
811
+ ...props,
812
+ children: [
813
+ leftIcon && /* @__PURE__ */ jsx("span", { className: "flex items-center", children: leftIcon }),
814
+ children && /* @__PURE__ */ jsx("span", { children }),
815
+ rightIcon && /* @__PURE__ */ jsx("span", { className: "flex items-center", children: rightIcon })
816
+ ]
817
+ }
818
+ );
819
+ }
820
+
821
+ // src/components/Box/Box.styles.ts
822
+ var paddingClasses = {
823
+ none: "p-0",
824
+ xs: "p-1",
825
+ // 4px
826
+ sm: "p-2",
827
+ // 8px
828
+ md: "p-4",
829
+ // 16px
830
+ lg: "p-6"
831
+ // 24px
832
+ };
833
+ var radiusClasses = {
834
+ none: "rounded-none",
835
+ xs: "rounded-sm",
836
+ sm: "rounded",
837
+ md: "rounded-md",
838
+ lg: "rounded-lg",
839
+ xl: "rounded-xl",
840
+ "2xl": "rounded-2xl",
841
+ "3xl": "rounded-3xl"
842
+ };
843
+ var displayClasses = {
844
+ block: "block",
845
+ flex: "flex",
846
+ grid: "grid",
847
+ "inline-block": "inline-block",
848
+ "inline-flex": "inline-flex",
849
+ none: "hidden"
850
+ };
851
+ var backgroundClasses = {
852
+ default: "",
853
+ subtle: "bg-gray-50",
854
+ inverse: "bg-gray-900 text-white",
855
+ transparent: "bg-transparent"
856
+ };
857
+ function boxStyles({
858
+ padding = "none",
859
+ radius = "none",
860
+ display = "block",
861
+ background = "default"
862
+ }) {
863
+ return mergeStyles([
864
+ paddingClasses[padding],
865
+ radiusClasses[radius],
866
+ displayClasses[display],
867
+ backgroundClasses[background]
868
+ ]);
869
+ }
870
+
871
+ // src/components/Box/Box.tsx
872
+ var Box = ({
873
+ as,
874
+ padding,
875
+ radius,
876
+ display,
877
+ background,
255
878
  className = "",
879
+ children,
256
880
  ...props
257
881
  }) => {
258
- const classes = textStyles({
259
- variant,
260
- size,
261
- fixedSize,
262
- point,
263
- color
264
- });
265
- return React.createElement(
882
+ const Component = as || "div";
883
+ const classes = boxStyles({ padding, radius, display, background });
884
+ return React4.createElement(
266
885
  Component,
267
886
  {
268
887
  className: mergeStyles(classes, className),
@@ -271,6 +890,331 @@ var Text = ({
271
890
  children
272
891
  );
273
892
  };
274
- Text.displayName = "Text";
893
+ Box.displayName = "Box";
894
+
895
+ // src/components/Stack/Stack.styles.ts
896
+ var directionClasses = {
897
+ horizontal: "flex-row",
898
+ vertical: "flex-col"
899
+ };
900
+ var gapClasses = {
901
+ none: "gap-0",
902
+ xs: "gap-1",
903
+ // 4px
904
+ sm: "gap-2",
905
+ // 8px
906
+ md: "gap-4",
907
+ // 16px
908
+ lg: "gap-6",
909
+ // 24px
910
+ xl: "gap-8"
911
+ // 32px
912
+ };
913
+ var alignClasses2 = {
914
+ start: "items-start",
915
+ center: "items-center",
916
+ end: "items-end",
917
+ stretch: "items-stretch"
918
+ };
919
+ var justifyClasses = {
920
+ start: "justify-start",
921
+ center: "justify-center",
922
+ end: "justify-end",
923
+ between: "justify-between"
924
+ };
925
+ function stackStyles({
926
+ direction = "vertical",
927
+ gap = "md",
928
+ align = "stretch",
929
+ justify = "start"
930
+ }) {
931
+ return mergeStyles([
932
+ "flex",
933
+ // Base style
934
+ directionClasses[direction],
935
+ gapClasses[gap],
936
+ alignClasses2[align],
937
+ justifyClasses[justify]
938
+ ]);
939
+ }
940
+
941
+ // src/components/Stack/Stack.tsx
942
+ var Stack = ({
943
+ as,
944
+ direction,
945
+ gap,
946
+ align,
947
+ justify,
948
+ className = "",
949
+ children,
950
+ ...props
951
+ }) => {
952
+ const Component = as || "div";
953
+ const classes = stackStyles({ direction, gap, align, justify });
954
+ return React4.createElement(
955
+ Component,
956
+ {
957
+ className: mergeStyles(classes, className),
958
+ ...props
959
+ },
960
+ children
961
+ );
962
+ };
963
+ Stack.displayName = "Stack";
964
+ var VStack = ({
965
+ ...props
966
+ }) => {
967
+ return /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
968
+ };
969
+ VStack.displayName = "VStack";
970
+ var HStack = ({
971
+ ...props
972
+ }) => {
973
+ return /* @__PURE__ */ jsx(Stack, { direction: "horizontal", ...props });
974
+ };
975
+ HStack.displayName = "HStack";
976
+
977
+ // src/components/Flex/Flex.styles.ts
978
+ var directionClasses2 = {
979
+ row: "flex-row",
980
+ "row-reverse": "flex-row-reverse",
981
+ column: "flex-col",
982
+ "column-reverse": "flex-col-reverse"
983
+ };
984
+ var gapClasses2 = {
985
+ none: "gap-0",
986
+ xs: "gap-1",
987
+ // 4px
988
+ sm: "gap-2",
989
+ // 8px
990
+ md: "gap-4",
991
+ // 16px
992
+ lg: "gap-6",
993
+ // 24px
994
+ xl: "gap-8"
995
+ // 32px
996
+ };
997
+ var alignClasses3 = {
998
+ start: "items-start",
999
+ center: "items-center",
1000
+ end: "items-end",
1001
+ stretch: "items-stretch",
1002
+ baseline: "items-baseline"
1003
+ };
1004
+ var justifyClasses2 = {
1005
+ start: "justify-start",
1006
+ center: "justify-center",
1007
+ end: "justify-end",
1008
+ between: "justify-between",
1009
+ around: "justify-around",
1010
+ evenly: "justify-evenly"
1011
+ };
1012
+ var wrapClasses = {
1013
+ nowrap: "flex-nowrap",
1014
+ wrap: "flex-wrap",
1015
+ "wrap-reverse": "flex-wrap-reverse"
1016
+ };
1017
+ function flexStyles({
1018
+ direction = "row",
1019
+ gap = "md",
1020
+ align = "stretch",
1021
+ justify = "start",
1022
+ wrap = "nowrap"
1023
+ }) {
1024
+ return mergeStyles([
1025
+ "flex",
1026
+ // Base style
1027
+ directionClasses2[direction],
1028
+ gapClasses2[gap],
1029
+ alignClasses3[align],
1030
+ justifyClasses2[justify],
1031
+ wrapClasses[wrap]
1032
+ ]);
1033
+ }
1034
+
1035
+ // src/components/Flex/Flex.tsx
1036
+ var Flex = ({
1037
+ as,
1038
+ direction,
1039
+ gap,
1040
+ align,
1041
+ justify,
1042
+ wrap,
1043
+ className = "",
1044
+ children,
1045
+ ...props
1046
+ }) => {
1047
+ const Component = as || "div";
1048
+ const classes = flexStyles({ direction, gap, align, justify, wrap });
1049
+ return React4.createElement(
1050
+ Component,
1051
+ {
1052
+ className: mergeStyles(classes, className),
1053
+ ...props
1054
+ },
1055
+ children
1056
+ );
1057
+ };
1058
+ Flex.displayName = "Flex";
1059
+
1060
+ // src/components/Grid/Grid.styles.ts
1061
+ var columnsClasses = {
1062
+ 1: "grid-cols-1",
1063
+ 2: "grid-cols-2",
1064
+ 3: "grid-cols-3",
1065
+ 4: "grid-cols-4",
1066
+ 5: "grid-cols-5",
1067
+ 6: "grid-cols-6",
1068
+ 7: "grid-cols-7",
1069
+ 8: "grid-cols-8",
1070
+ 9: "grid-cols-9",
1071
+ 10: "grid-cols-10",
1072
+ 11: "grid-cols-11",
1073
+ 12: "grid-cols-12",
1074
+ none: "grid-cols-none"
1075
+ };
1076
+ var rowsClasses = {
1077
+ 1: "grid-rows-1",
1078
+ 2: "grid-rows-2",
1079
+ 3: "grid-rows-3",
1080
+ 4: "grid-rows-4",
1081
+ 5: "grid-rows-5",
1082
+ 6: "grid-rows-6",
1083
+ none: "grid-rows-none"
1084
+ };
1085
+ var gapClasses3 = {
1086
+ none: "gap-0",
1087
+ xs: "gap-1",
1088
+ // 4px
1089
+ sm: "gap-2",
1090
+ // 8px
1091
+ md: "gap-4",
1092
+ // 16px
1093
+ lg: "gap-6",
1094
+ // 24px
1095
+ xl: "gap-8"
1096
+ // 32px
1097
+ };
1098
+ var flowClasses = {
1099
+ row: "grid-flow-row",
1100
+ col: "grid-flow-col",
1101
+ "row-dense": "grid-flow-row-dense",
1102
+ "col-dense": "grid-flow-col-dense"
1103
+ };
1104
+ function gridStyles({
1105
+ columns = "none",
1106
+ rows = "none",
1107
+ gap = "md",
1108
+ flow = "row"
1109
+ }) {
1110
+ return mergeStyles([
1111
+ "grid",
1112
+ columnsClasses[columns],
1113
+ rowsClasses[rows],
1114
+ gapClasses3[gap],
1115
+ flowClasses[flow]
1116
+ ]);
1117
+ }
1118
+
1119
+ // src/components/Grid/Grid.tsx
1120
+ var Grid = ({
1121
+ as,
1122
+ columns,
1123
+ rows,
1124
+ gap,
1125
+ flow,
1126
+ className = "",
1127
+ children,
1128
+ ...props
1129
+ }) => {
1130
+ const Component = as || "div";
1131
+ const classes = gridStyles({ columns, rows, gap, flow });
1132
+ return React4.createElement(
1133
+ Component,
1134
+ {
1135
+ className: mergeStyles(classes, className),
1136
+ ...props
1137
+ },
1138
+ children
1139
+ );
1140
+ };
1141
+ Grid.displayName = "Grid";
1142
+
1143
+ // src/components/Separator/Separator.styles.ts
1144
+ var orientationClasses = {
1145
+ horizontal: "h-px w-full my-2",
1146
+ vertical: "h-full w-px mx-2 self-stretch"
1147
+ };
1148
+ var colorClasses2 = "bg-gray-200";
1149
+ function separatorStyles({
1150
+ orientation = "horizontal"
1151
+ }) {
1152
+ return mergeStyles([colorClasses2, orientationClasses[orientation]]);
1153
+ }
1154
+
1155
+ // src/components/Separator/Separator.tsx
1156
+ var Separator = ({
1157
+ as,
1158
+ orientation = "horizontal",
1159
+ className = "",
1160
+ ...props
1161
+ }) => {
1162
+ const Component = as || "div";
1163
+ const classes = separatorStyles({ orientation });
1164
+ return React4.createElement(Component, {
1165
+ role: "separator",
1166
+ "aria-orientation": orientation,
1167
+ className: mergeStyles(classes, className),
1168
+ ...props
1169
+ });
1170
+ };
1171
+ Separator.displayName = "Separator";
1172
+
1173
+ // src/components/Spacer/Spacer.styles.ts
1174
+ var sizeClasses = {
1175
+ 1: "w-1 h-1",
1176
+ // 4px
1177
+ 2: "w-2 h-2",
1178
+ // 8px
1179
+ 4: "w-4 h-4",
1180
+ // 16px
1181
+ 6: "w-6 h-6",
1182
+ // 24px
1183
+ 8: "w-8 h-8",
1184
+ // 32px
1185
+ 10: "w-10 h-10",
1186
+ // 40px
1187
+ 12: "w-12 h-12",
1188
+ // 48px
1189
+ 16: "w-16 h-16",
1190
+ // 64px
1191
+ 20: "w-20 h-20",
1192
+ // 80px
1193
+ 24: "w-24 h-24"
1194
+ // 96px
1195
+ };
1196
+ function spacerStyles({ size = "auto" }) {
1197
+ if (size === "auto") {
1198
+ return "flex-1";
1199
+ }
1200
+ return mergeStyles(["flex-none", sizeClasses[size]]);
1201
+ }
1202
+
1203
+ // src/components/Spacer/Spacer.tsx
1204
+ var Spacer = ({
1205
+ as,
1206
+ size,
1207
+ className = "",
1208
+ ...props
1209
+ }) => {
1210
+ const Component = as || "div";
1211
+ const classes = spacerStyles({ size });
1212
+ return React4.createElement(Component, {
1213
+ "aria-hidden": "true",
1214
+ className: mergeStyles(classes, className),
1215
+ ...props
1216
+ });
1217
+ };
1218
+ Spacer.displayName = "Spacer";
275
1219
 
276
- export { Text, mergeStyles };
1220
+ export { Box, Button, CTAButton, Checkbox, Field, Flex, FloatingActionButton, Grid, HStack, Radio, RadioGroup, Separator, Spacer, Stack, Text, TextArea, TextInput, Toggle, VStack, mergeStyles, useRadioGroupContext };