@designbasekorea/figma-ui 0.6.3 → 0.6.4

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.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
+ var react = require('@designbasekorea/ui-wc/react');
4
5
  var icons = require('@designbasekorea/icons');
5
- var ui = require('@designbasekorea/ui');
6
6
 
7
7
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
8
8
 
@@ -12,10 +12,20 @@ function resolveText(t, input, fallback) {
12
12
  if (typeof input === 'string') {
13
13
  return input;
14
14
  }
15
- return t ? t(input.key, input.values) : input.key;
15
+ if (t) {
16
+ const translated = t(input.key, input.values);
17
+ if (translated && translated !== input.key) {
18
+ return translated;
19
+ }
20
+ }
21
+ return fallback ?? input.key;
16
22
  }
17
23
 
18
- const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', text = { key: 'donation.buy_me_a_coffee' }, iconType = 'heart', size = 's', variant = 'tertiary', fullWidth = false, disabled = false, showPrompt = false, promptText = { key: 'donation.prompt' }, className, onClick, t }) => {
24
+ const DONATION_ICON_NAMES = {
25
+ heart: 'star-filled',
26
+ coffee: 'cart',
27
+ };
28
+ const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', text = { key: 'donation.buy_me_a_coffee' }, iconType = 'heart', size = 's', variant = 'tertiary', fullWidth = false, iconOnly = false, disabled = false, showPrompt = false, promptText = { key: 'donation.prompt' }, className, onClick, t }) => {
19
29
  const handleClick = () => {
20
30
  if (onClick) {
21
31
  onClick();
@@ -24,15 +34,12 @@ const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', te
24
34
  window.open(donationUrl, '_blank', 'noopener,noreferrer');
25
35
  }
26
36
  };
27
- const Icon = iconType === 'heart' ? icons.HeartFilledIcon : icons.CoffeeFilledIcon;
28
37
  const displayText = resolveText(t, text, 'Buy me a coffee');
29
38
  const displayPromptText = resolveText(t, promptText, '도움이 되었다면 커피 한 잔 사주세요!');
30
39
  const buttonSize = size;
31
40
  return (React.createElement("div", { className: clsx('designbase-figma-donation-badge-container', className) },
32
- showPrompt && (React.createElement("div", { className: "designbase-figma-donation-badge__prompt" }, displayPromptText)),
33
- React.createElement(ui.Button, { variant: variant, size: buttonSize, fullWidth: fullWidth, disabled: disabled, onPress: handleClick, startIcon: Icon, className: clsx('designbase-figma-donation-badge', `designbase-figma-donation-badge--${iconType}`), "aria-label": displayText, style: {
34
- '--designbase-figma-donation-badge-icon-color': 'var(--db-brand-primary)'
35
- } }, displayText)));
41
+ showPrompt && !iconOnly && (React.createElement("div", { className: "designbase-figma-donation-badge__prompt" }, displayPromptText)),
42
+ React.createElement(react.Button, { variant: variant, size: buttonSize, fullWidth: fullWidth, disabled: disabled, onPress: handleClick, iconOnly: iconOnly, startIcon: DONATION_ICON_NAMES[iconType], className: clsx('designbase-figma-donation-badge', `designbase-figma-donation-badge--${iconType}`), "aria-label": displayText }, iconOnly ? undefined : displayText)));
36
43
  };
37
44
  DonationBadge.displayName = 'DonationBadge';
38
45
 
@@ -70,10 +77,11 @@ const FigmaHeader = ({ children, actions = [], searchBar, sticky = true, classNa
70
77
  'designbase-figma-header--with-search': !!searchBar,
71
78
  'designbase-figma-header--with-actions': actions.length > 0,
72
79
  }, className);
80
+ const hasToolbar = !!children || actions.length > 0;
73
81
  return (React.createElement("header", { className: classes },
74
- React.createElement("div", { className: "designbase-figma-header__container" },
82
+ hasToolbar && (React.createElement("div", { className: "designbase-figma-header__container" },
75
83
  children && (React.createElement("div", { className: "designbase-figma-header__center" }, children)),
76
- actions.length > 0 && (React.createElement("div", { className: "designbase-figma-header__right" }, actions.map((action, index) => (React.createElement(ui.Button, { key: index, variant: "tertiary", size: "s", iconOnly: true, "aria-label": `액션 ${index + 1}` }, action)))))),
84
+ actions.length > 0 && (React.createElement("div", { className: "designbase-figma-header__right" }, actions.map((action, index) => (React.createElement(react.Button, { key: `${action.startIcon}-${index}`, variant: "tertiary", size: "s", iconOnly: true, startIcon: action.startIcon, "aria-label": action.ariaLabel, onPress: action.onPress }))))))),
77
85
  searchBar && (React.createElement("div", { className: "designbase-figma-header__search-container" }, searchBar))));
78
86
  };
79
87
  FigmaHeader.displayName = 'FigmaHeader';
@@ -82,22 +90,24 @@ const FigmaPageHead = ({ onBack, title, description, actions = [], moreActions =
82
90
  const classes = clsx('designbase-figma-page-head', className);
83
91
  const displayTitle = resolveText(t, title);
84
92
  const displayDescription = description ? resolveText(t, description) : undefined;
85
- const dropdownItems = moreActions.map(action => ({
93
+ const dropdownItems = moreActions.map((action) => ({
86
94
  id: action.id,
87
95
  label: resolveText(t, action.label),
88
- onClick: action.onClick
89
96
  }));
97
+ const handleDropdownChange = (event) => {
98
+ const actionId = event.detail?.id ?? event.detail?.value;
99
+ const action = moreActions.find((item) => item.id === actionId);
100
+ action?.onClick();
101
+ };
90
102
  return (React.createElement("div", { className: classes },
91
103
  React.createElement("div", { className: "designbase-figma-page-head__left" },
92
- React.createElement(ui.Button, { variant: "tertiary", size: "s", iconOnly: true, onPress: onBack, "aria-label": "\uB4A4\uB85C\uAC00\uAE30" },
93
- React.createElement(icons.ChevronLeftIcon, { size: 14 })),
104
+ React.createElement(react.Button, { variant: "tertiary", size: "s", iconOnly: true, startIcon: "chevron-left", onPress: onBack, "aria-label": "\uB4A4\uB85C\uAC00\uAE30" }),
94
105
  React.createElement("div", { className: "designbase-figma-page-head__titles" },
95
106
  React.createElement("h2", null, displayTitle),
96
107
  displayDescription && React.createElement("p", null, displayDescription))),
97
108
  React.createElement("div", { className: "designbase-figma-page-head__actions" },
98
109
  actions.map((action, index) => (React.createElement(React.Fragment, { key: index }, action))),
99
- moreActions.length > 0 && (React.createElement(ui.Dropdown, { trigger: React.createElement("button", { type: "button", className: "designbase-figma-page-head__more-button", "aria-label": "\uB354\uBCF4\uAE30" },
100
- React.createElement(icons.MoreHorizontalIcon, { size: 16 })), items: dropdownItems, placement: "bottom-right", size: "s" })))));
110
+ moreActions.length > 0 && (React.createElement(react.Dropdown, { items: dropdownItems, triggerIcon: "more-horizontal", iconOnly: true, triggerVariant: "tertiary", placement: "bottom-right", size: "s", onChange: handleDropdownChange })))));
101
111
  };
102
112
  FigmaPageHead.displayName = 'FigmaPageHead';
103
113
 
@@ -223,12 +233,12 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
223
233
  typeof title === 'string' || (typeof title === 'object' && 'key' in title)
224
234
  ? resolveText(t, title)
225
235
  : title,
226
- badge && (React.createElement(ui.Badge, { variant: "secondary", size: "s" }, badge)))),
236
+ badge && (React.createElement(react.Badge, { variant: "secondary", size: "s" }, badge)))),
227
237
  React.createElement("div", { className: "designbase-figma-section__controls", onClick: (e) => e.stopPropagation() },
228
238
  iconButton,
229
239
  collapsible && (React.createElement("span", { className: `designbase-figma-section__collapse-icon ${collapsed ? 'designbase-figma-section__collapse-icon--collapsed' : ''}` },
230
240
  React.createElement(icons.ChevronDownIcon, { size: 16 }))),
231
- onToggle && (React.createElement(ui.Toggle, { checked: isEnabled, onChange: () => onToggle(dataCategory), size: "s" }))))),
241
+ onToggle && (React.createElement(react.Toggle, { checked: isEnabled, onChange: () => onToggle(dataCategory), size: "s" }))))),
232
242
  React.createElement("div", { className: `designbase-figma-section__content ${!isEnabled ? 'designbase-figma-section__content--hidden' : ''}` },
233
243
  React.createElement("div", { ref: clipRef, className: "designbase-figma-section__content-clip" },
234
244
  React.createElement("div", { ref: innerRef, className: `designbase-figma-section__content-inner ${collapsible && contentHidden ? 'is-collapsed' : ''}` }, children)))));
@@ -385,7 +395,7 @@ const PaymentBadge = ({ isActive, onClick, isLoading = false, text, t = (key) =>
385
395
  const getBadgeVariant = () => {
386
396
  return isActive ? 'success' : 'secondary';
387
397
  };
388
- return (React.createElement("div", { className: `designbase-figma-payment-badge ${className || ''} ${isActive ? 'active' : 'free'}`, onClick: onClick, style: { cursor: onClick ? 'pointer' : 'default' } }, isLoading ? (React.createElement(ui.Spinner, { size: "s" })) : (React.createElement(ui.Badge, { variant: getBadgeVariant(), size: "s", className: "designbase-figma-payment-badge__badge" }, getBadgeText()))));
398
+ return (React.createElement("div", { className: `designbase-figma-payment-badge ${className || ''} ${isActive ? 'active' : 'free'}`, onClick: onClick, style: { cursor: onClick ? 'pointer' : 'default' } }, isLoading ? (React.createElement(react.Spinner, { size: "s" })) : (React.createElement(react.Badge, { variant: getBadgeVariant(), size: "s", className: "designbase-figma-payment-badge__badge" }, getBadgeText()))));
389
399
  };
390
400
  PaymentBadge.displayName = 'PaymentBadge';
391
401
 
@@ -414,10 +424,15 @@ const LanguageSelector = ({ currentLanguage, languages = DEFAULT_LANGUAGES, onLa
414
424
  const segmentOptions = languages.map((language) => ({
415
425
  value: language.code,
416
426
  label: resolveText(t, language.label),
417
- disabled: false
427
+ disabled: false,
418
428
  }));
419
429
  return (React.createElement("div", { className: `designbase-figma-language-selector ${className || ''}` },
420
- React.createElement(ui.SegmentControl, { options: segmentOptions, value: activeLanguage, onChange: handleLanguageChange, size: size, className: "designbase-figma-language-selector__segment" })));
430
+ React.createElement(react.SegmentControl, { options: segmentOptions, value: activeLanguage, onChange: (event) => {
431
+ const value = event.detail?.value;
432
+ if (value) {
433
+ handleLanguageChange(value);
434
+ }
435
+ }, size: size, className: "designbase-figma-language-selector__segment" })));
421
436
  };
422
437
  LanguageSelector.displayName = 'LanguageSelector';
423
438
 
@@ -473,7 +488,7 @@ const LogoDropdown = ({ logoSrc, logoAlt = 'DesignBase', logoType = 'designbase'
473
488
  return (React.createElement("img", { className: "designbase-figma-logo-dropdown__logo", src: logoSrc, alt: logoAlt, onClick: toggleDropdown }));
474
489
  }
475
490
  return (React.createElement("div", { className: "designbase-figma-logo-dropdown__logo", onClick: toggleDropdown },
476
- React.createElement(ui.Logo, { type: logoType, size: logoSize, variant: "default" })));
491
+ React.createElement(react.Logo, { type: logoType, size: logoSize, variant: "default" })));
477
492
  };
478
493
  return (React.createElement("div", { className: classes },
479
494
  renderLogo(),
@@ -507,22 +522,29 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
507
522
  React.createElement("div", { className: "designbase-figma-footer__left" },
508
523
  React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, t: t }),
509
524
  showLanguageSelector && (React.createElement(LanguageSelector, { currentLanguage: currentLanguage, languages: languages, onLanguageChange: onLanguageChange, size: "s" }))),
510
- showPaymentStatus && (React.createElement("div", { className: "designbase-figma-footer__payment-states" },
511
- resolvedShowUsageInfo && (React.createElement("div", { className: "designbase-figma-footer__usage-info" }, isActive ? (React.createElement("span", { className: "designbase-figma-footer__unlimited-usage designbase-figma-footer__unlimited-usage--tooltip", title: t('unlimitedUsageTooltip') }, t('unlimitedUsage'))) : (React.createElement(React.Fragment, null,
512
- React.createElement("span", { className: "designbase-figma-footer__usage-info designbase-figma-footer__usage-info--tooltip", title: t('resetsDaily') },
513
- React.createElement("span", { className: "designbase-figma-footer__usage-count" }, usageCount),
514
- React.createElement("span", { className: "designbase-figma-footer__max-daily-usage" },
515
- "/",
516
- maxDailyUsage,
517
- " ",
518
- t('perDay'))))))),
519
- resolvedShowPaymentBadge && (React.createElement(PaymentBadge, { isActive: isActive, onClick: isBeta ? undefined : onLicensePageClick, isLoading: isLoading, text: isBeta ? (t('betaStatus') || 'BETA') : undefined, t: t })))),
520
- showDonation && (React.createElement("div", { className: "designbase-figma-footer__donation" },
521
- React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", showPrompt: showDonationText && !isActive, promptText: donationPromptText, t: t })))),
525
+ React.createElement("div", { className: "designbase-figma-footer__right" },
526
+ showPaymentStatus && resolvedShowUsageInfo && (React.createElement("div", { className: "designbase-figma-footer__usage-info" }, isActive ? (React.createElement("span", { className: "designbase-figma-footer__unlimited-usage designbase-figma-footer__unlimited-usage--tooltip", title: t('unlimitedUsageTooltip') }, t('unlimitedUsage'))) : (React.createElement("span", { className: "designbase-figma-footer__usage-info designbase-figma-footer__usage-info--tooltip", title: t('resetsDaily') },
527
+ React.createElement("span", { className: "designbase-figma-footer__usage-count" }, usageCount),
528
+ React.createElement("span", { className: "designbase-figma-footer__max-daily-usage" },
529
+ "/",
530
+ maxDailyUsage,
531
+ " ",
532
+ t('perDay')))))),
533
+ showPaymentStatus && resolvedShowPaymentBadge && (React.createElement(PaymentBadge, { isActive: isActive, onClick: isBeta ? undefined : onLicensePageClick, isLoading: isLoading, text: isBeta ? (t('betaStatus') || 'BETA') : undefined, t: t })),
534
+ showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: t })))),
522
535
  children));
523
536
  };
524
537
  FigmaFooter.displayName = 'FigmaFooter';
525
538
 
539
+ const FigmaToastStack = ({ toasts, position, maxToasts, onRemoveToast, }) => {
540
+ const visibleToasts = [...toasts]
541
+ .sort((a, b) => b.createdAt - a.createdAt)
542
+ .slice(0, maxToasts);
543
+ if (visibleToasts.length === 0)
544
+ return null;
545
+ return (React.createElement("div", { className: `figma-toast-container figma-toast-container--${position}` }, visibleToasts.map((toast) => (React.createElement("div", { key: toast.id, className: "figma-toast-container__item" },
546
+ React.createElement(react.Toast, { toastId: toast.id, title: toast.title, description: toast.description, status: toast.status, duration: toast.duration, showProgress: toast.showProgress, showClose: toast.showCloseButton, onClose: () => onRemoveToast(toast.id) }))))));
547
+ };
526
548
  const ToastContext = React.createContext(null);
527
549
  const useToast = () => {
528
550
  const context = React.useContext(ToastContext);
@@ -540,13 +562,13 @@ const FigmaToastProvider = ({ children, position = 'top-right', maxToasts = 5, }
540
562
  id,
541
563
  createdAt: Date.now(),
542
564
  };
543
- setToasts(prev => {
565
+ setToasts((prev) => {
544
566
  const updated = [newToast, ...prev];
545
567
  return updated.slice(0, maxToasts);
546
568
  });
547
569
  }, [maxToasts]);
548
570
  const removeToast = React.useCallback((id) => {
549
- setToasts(prev => prev.filter(toast => toast.id !== id));
571
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
550
572
  }, []);
551
573
  const showToast = React.useCallback((message, options = {}) => {
552
574
  addToast({
@@ -565,17 +587,17 @@ const FigmaToastProvider = ({ children, position = 'top-right', maxToasts = 5, }
565
587
  };
566
588
  return (React.createElement(ToastContext.Provider, { value: contextValue },
567
589
  children,
568
- React.createElement(ui.ToastContainer, { toasts: toasts, onRemoveToast: removeToast, position: position, maxToasts: maxToasts })));
590
+ React.createElement(FigmaToastStack, { toasts: toasts, onRemoveToast: removeToast, position: position, maxToasts: maxToasts })));
569
591
  };
570
592
  const FigmaToast = ({ message, isVisible, onClose, type = 'info', duration = 3000, className, }) => {
571
593
  if (!isVisible)
572
594
  return null;
573
595
  return (React.createElement("div", { className: `figma-toast-fixed-wrap ${className || ''}` },
574
- React.createElement(ui.Toast, { id: "figma-toast-simple", title: message, status: type, duration: duration, showProgress: false, showCloseButton: true, onClose: onClose, position: "top-right" })));
596
+ React.createElement(react.Toast, { toastId: "figma-toast-simple", title: message, status: type, duration: duration, showProgress: false, showClose: true, onClose: onClose })));
575
597
  };
576
598
  const useFigmaToast = () => {
577
599
  const [toast, setToast] = React.useState({ message: '', isVisible: false });
578
- const showToast = React.useCallback((message, type = 'info') => {
600
+ const showToast = React.useCallback((message, _type = 'info') => {
579
601
  setToast({ message, isVisible: true });
580
602
  setTimeout(() => setToast({ message: '', isVisible: false }), 5000);
581
603
  }, []);
@@ -606,8 +628,13 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
606
628
  return (React.createElement("form", { className: `designbase-figma-form-with-submit ${className || ''}`, onSubmit: handleSubmit },
607
629
  React.createElement("div", { className: "designbase-figma-form-with-submit__field" },
608
630
  React.createElement("label", { className: "designbase-figma-form-with-submit__label" }, displayLabel),
609
- React.createElement(ui.Input, { value: inputValue, onChange: handleChange, placeholder: displayPlaceholder, helperText: displayHelperText, disabled: disabled || isSubmitting, size: "m" })),
610
- React.createElement(ui.Button, { type: "submit", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true }, isSubmitting ? displaySubmittingText : displaySubmitText)));
631
+ React.createElement(react.Input, { value: inputValue, onChange: (event) => {
632
+ const value = event.detail?.value;
633
+ if (value !== undefined) {
634
+ handleChange(value);
635
+ }
636
+ }, placeholder: displayPlaceholder, helperText: displayHelperText, disabled: disabled || isSubmitting, size: "m" })),
637
+ React.createElement(react.Button, { type: "submit", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true }, isSubmitting ? displaySubmittingText : displaySubmitText)));
611
638
  };
612
639
  FormWithSubmit.displayName = 'FormWithSubmit';
613
640
 
@@ -620,7 +647,7 @@ const InteractionFeedback = ({ status = 'default', message, statusMessage, leftC
620
647
  return (React.createElement("div", { className: feedbackClasses },
621
648
  React.createElement("div", { className: "designbase-figma-interaction__content" },
622
649
  React.createElement("div", { className: "designbase-figma-interaction__left" }, leftContent || (React.createElement("div", { className: "designbase-figma-interaction__message" },
623
- status === 'loading' && (React.createElement(ui.Spinner, { size: "s", type: "circular", label: "\uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4...", showLabel: false })),
650
+ status === 'loading' && (React.createElement(react.Spinner, { size: "s", type: "circular", label: "\uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4...", showLabel: false })),
624
651
  (message || status === 'loading') && (React.createElement("span", { className: "designbase-figma-interaction__text" }, resolveText(t, message || '불러오는 중입니다...'))),
625
652
  statusMessage && (React.createElement("span", { className: "designbase-figma-interaction__status-text" }, resolveText(t, statusMessage)))))),
626
653
  rightAction && (React.createElement("div", { className: "designbase-figma-interaction__right" }, rightAction)))));
@@ -659,18 +686,17 @@ const PricingComparison = ({ features = defaultFeatures, pricing = defaultPricin
659
686
  };
660
687
  return (React.createElement("div", { className: `designbase-figma-pricing-comparison ${className || ''}` },
661
688
  paymentType === 'subscription' && (React.createElement("div", { className: "designbase-figma-pricing-comparison__billing-toggle" },
662
- React.createElement(ui.SegmentControl, { value: isYearly ? 'yearly' : 'monthly', onChange: (value) => setIsYearly(value === 'yearly'), options: [
689
+ React.createElement(react.SegmentControl, { value: isYearly ? 'yearly' : 'monthly', onChange: (event) => {
690
+ const value = event.detail?.value;
691
+ setIsYearly(value === 'yearly');
692
+ }, options: [
663
693
  {
664
694
  value: 'monthly',
665
695
  label: t('monthlyBilling') || '월간 결제',
666
696
  },
667
697
  {
668
698
  value: 'yearly',
669
- label: (React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
670
- t('yearlyBilling') || '연간 결제',
671
- React.createElement("span", { className: "designbase-figma-pricing-comparison__discount-badge" },
672
- getDiscountPercentage(),
673
- "% \uC808\uC57D"))),
699
+ label: `${t('yearlyBilling') || '연간 결제'} (${getDiscountPercentage()}% 절약)`,
674
700
  },
675
701
  ], size: "s" }))),
676
702
  paymentType === 'lifetime' && (React.createElement("div", { className: "designbase-figma-pricing-comparison__lifetime-info" },
@@ -698,124 +724,307 @@ const PricingComparison = ({ features = defaultFeatures, pricing = defaultPricin
698
724
  };
699
725
  PricingComparison.displayName = 'PricingComparison';
700
726
 
701
- const PageLicense = ({ status: initialStatus, onClose, usageCount: initialUsageCount = 0, onLicenseSubmit, licenseKey: initialLicenseKey = '', setPaymentStatus, setUsageCount, setShowLicensePage, paymentPageUrl, pricingFeatures, pricing, paymentType = 'subscription', t, className, }) => {
702
- const [isSubmitting, setIsSubmitting] = React.useState(false);
727
+ function postPluginMessage(message) {
728
+ if (typeof parent === 'undefined') {
729
+ return;
730
+ }
731
+ parent.postMessage({ pluginMessage: message }, '*');
732
+ }
733
+ function openExternalUrl(url) {
734
+ if (!url)
735
+ return;
736
+ postPluginMessage({ type: 'open-external-url', url });
737
+ if (typeof window !== 'undefined') {
738
+ window.open(url, '_blank', 'noopener,noreferrer');
739
+ }
740
+ }
741
+
742
+ const DEFAULT_LICENSE_MESSAGE_TYPES = {
743
+ initialize: 'initialize',
744
+ verifyLicense: 'verify-license',
745
+ deactivateLicense: 'deactivate-license',
746
+ updateStatus: 'update-plugin-status',
747
+ verifyResult: 'license-verification-result',
748
+ deactivateResult: 'license-deactivation-result',
749
+ };
750
+ const START_DESIGNBASE_AUTH_MESSAGE = 'start-designbase-auth';
751
+ const INITIAL_LICENSE_PAGE_STATE = {
752
+ paymentStatus: 'FREE',
753
+ licenseKey: '',
754
+ planTier: 'FREE',
755
+ hasLicenseKey: false,
756
+ isLicenseRegistered: false,
757
+ activationLimit: 0,
758
+ activationUsage: 0,
759
+ usageCount: 0,
760
+ remainingUsage: 0,
761
+ usageUsed: 0,
762
+ usageLimit: 0,
763
+ usageReset: 'none',
764
+ canUseFeature: true,
765
+ };
766
+
767
+ function readString(data, keys) {
768
+ for (const key of keys) {
769
+ const value = data[key];
770
+ if (typeof value === 'string') {
771
+ return value;
772
+ }
773
+ }
774
+ return '';
775
+ }
776
+ function readNumber(data, keys) {
777
+ for (const key of keys) {
778
+ const value = data[key];
779
+ if (typeof value === 'number' && Number.isFinite(value)) {
780
+ return value;
781
+ }
782
+ }
783
+ return undefined;
784
+ }
785
+ function readBoolean(data, keys) {
786
+ for (const key of keys) {
787
+ const value = data[key];
788
+ if (typeof value === 'boolean') {
789
+ return value;
790
+ }
791
+ }
792
+ return undefined;
793
+ }
794
+ function parseLicenseMessage(data) {
795
+ const paymentStatus = readString(data, ['paymentStatus', 'status']);
796
+ const usageLimitRaw = data.usageLimit;
797
+ return {
798
+ ...(paymentStatus ? { paymentStatus } : {}),
799
+ licenseKey: readString(data, ['licenseKey']) || undefined,
800
+ planTier: readString(data, ['planTier']) || undefined,
801
+ hasLicenseKey: readBoolean(data, ['hasLicenseKey']),
802
+ isLicenseRegistered: readBoolean(data, ['isLicenseRegistered']),
803
+ activationLimit: readNumber(data, ['activationLimit']),
804
+ activationUsage: readNumber(data, ['activationUsage']),
805
+ usageCount: readNumber(data, ['usageCount']),
806
+ remainingUsage: readNumber(data, ['remainingUsage']),
807
+ usageUsed: readNumber(data, ['usageUsed']),
808
+ usageLimit: usageLimitRaw === 'unlimited' ? 'unlimited' : readNumber(data, ['usageLimit']),
809
+ usageReset: readString(data, ['usageReset']) || undefined,
810
+ canUseFeature: readBoolean(data, ['canUseFeature']),
811
+ usageReason: readString(data, ['usageReason']) || undefined,
812
+ lastMessage: readString(data, ['message']) || undefined,
813
+ lastErrorCode: readString(data, ['errorCode']) || undefined,
814
+ };
815
+ }
816
+ function useFigmaLicenseBridge(options = {}) {
817
+ const messageTypes = React.useMemo(() => ({ ...DEFAULT_LICENSE_MESSAGE_TYPES, ...options.messageTypes }), [options.messageTypes]);
818
+ const [state, setState] = React.useState({
819
+ ...INITIAL_LICENSE_PAGE_STATE,
820
+ ...options.initialState,
821
+ });
822
+ const [isVerifying, setIsVerifying] = React.useState(false);
703
823
  const [isDeactivating, setIsDeactivating] = React.useState(false);
704
- const [licenseKey, setLicenseKey] = React.useState(initialLicenseKey);
705
- const [status, setStatus] = React.useState(initialStatus);
706
- const [usageCount, setLocalUsageCount] = React.useState(initialUsageCount);
707
- const [activationLimit, setActivationLimit] = React.useState(0);
708
- const [activationUsage, setActivationUsage] = React.useState(0);
709
- const [showDetails, setShowDetails] = React.useState(false);
824
+ const [isStartingAuth, setIsStartingAuth] = React.useState(false);
825
+ const optionsRef = React.useRef(options);
826
+ optionsRef.current = options;
827
+ const applyPatch = React.useCallback((patch) => {
828
+ setState((prev) => {
829
+ const next = {
830
+ ...prev,
831
+ ...Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined)),
832
+ };
833
+ optionsRef.current.onStateChange?.(next);
834
+ if (patch.paymentStatus) {
835
+ optionsRef.current.onPaymentStatusChange?.(patch.paymentStatus);
836
+ }
837
+ if (patch.usageCount !== undefined) {
838
+ optionsRef.current.onUsageCountChange?.(patch.usageCount);
839
+ }
840
+ return next;
841
+ });
842
+ }, []);
710
843
  React.useEffect(() => {
711
844
  const handleMessage = (event) => {
712
- const { type, paymentStatus, licenseKey, activationLimit, activationUsage, success, message, usageCount } = event.data.pluginMessage || {};
713
- if (type === 'update-plugin-status' || type === 'license-verification-result') {
714
- if (paymentStatus)
715
- setStatus(paymentStatus);
716
- if (licenseKey)
717
- setLicenseKey(licenseKey);
718
- if (activationLimit !== undefined)
719
- setActivationLimit(activationLimit);
720
- if (activationUsage !== undefined)
721
- setActivationUsage(activationUsage);
722
- if (paymentStatus)
723
- setPaymentStatus(paymentStatus);
724
- if (usageCount !== undefined) {
725
- setLocalUsageCount(usageCount);
726
- setUsageCount(usageCount);
727
- }
845
+ const data = event.data?.pluginMessage;
846
+ if (!data || typeof data !== 'object')
847
+ return;
848
+ const payload = data;
849
+ const type = typeof payload.type === 'string' ? payload.type : '';
850
+ if (type === messageTypes.updateStatus) {
851
+ applyPatch(parseLicenseMessage(payload));
728
852
  }
729
- if (type === 'license-verification-result') {
730
- setIsSubmitting(false);
731
- if (message)
732
- console.log('License verification:', message);
733
- if (success) {
734
- setStatus('PAID');
735
- setPaymentStatus('PAID');
853
+ if (type === messageTypes.verifyResult) {
854
+ setIsVerifying(false);
855
+ setIsStartingAuth(false);
856
+ applyPatch(parseLicenseMessage(payload));
857
+ if (payload.success === true) {
858
+ applyPatch({ paymentStatus: 'PAID', isLicenseRegistered: true });
736
859
  }
737
860
  }
738
- if (type === 'license-deactivation-result') {
861
+ if (type === messageTypes.deactivateResult) {
739
862
  setIsDeactivating(false);
740
- if (message)
741
- console.log('License deactivation:', message);
742
- if (success) {
743
- setStatus('UNPAID');
744
- setPaymentStatus('UNPAID');
745
- setLicenseKey('');
746
- setLocalUsageCount(20);
747
- setActivationLimit(0);
748
- setActivationUsage(0);
863
+ applyPatch(parseLicenseMessage(payload));
864
+ if (payload.success === true) {
865
+ applyPatch({
866
+ paymentStatus: 'UNPAID',
867
+ licenseKey: '',
868
+ hasLicenseKey: false,
869
+ isLicenseRegistered: false,
870
+ activationLimit: 0,
871
+ activationUsage: 0,
872
+ });
873
+ }
874
+ }
875
+ if (type === 'designbase-auth-result') {
876
+ setIsStartingAuth(false);
877
+ if (payload.success === true) {
878
+ applyPatch(parseLicenseMessage(payload));
879
+ }
880
+ else if (typeof payload.message === 'string') {
881
+ applyPatch({ lastMessage: payload.message });
749
882
  }
750
883
  }
751
884
  };
752
885
  window.addEventListener('message', handleMessage);
753
- if (typeof parent !== 'undefined') {
754
- parent.postMessage({ pluginMessage: { type: 'initialize' } }, '*');
755
- }
886
+ postPluginMessage({ type: messageTypes.initialize });
756
887
  return () => window.removeEventListener('message', handleMessage);
757
- }, [setPaymentStatus, setUsageCount]);
888
+ }, [applyPatch, messageTypes]);
889
+ const verifyLicense = React.useCallback((licenseKey) => {
890
+ setIsVerifying(true);
891
+ postPluginMessage({
892
+ type: messageTypes.verifyLicense,
893
+ licenseKey,
894
+ });
895
+ }, [messageTypes.verifyLicense]);
896
+ const deactivateLicense = React.useCallback(() => {
897
+ setIsDeactivating(true);
898
+ postPluginMessage({ type: messageTypes.deactivateLicense });
899
+ }, [messageTypes.deactivateLicense]);
900
+ const startDesignbaseAuth = React.useCallback(() => {
901
+ setIsStartingAuth(true);
902
+ postPluginMessage({ type: START_DESIGNBASE_AUTH_MESSAGE });
903
+ }, []);
904
+ return {
905
+ state,
906
+ isVerifying,
907
+ isDeactivating,
908
+ isStartingAuth,
909
+ verifyLicense,
910
+ deactivateLicense,
911
+ startDesignbaseAuth,
912
+ setLicenseKeyInput: (licenseKey) => applyPatch({ licenseKey }),
913
+ };
914
+ }
915
+
916
+ function formatUsageLabel(state, t) {
917
+ const { remainingUsage, usageUsed, usageLimit, usageReset } = state;
918
+ if (usageLimit === 'unlimited') {
919
+ return resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음');
920
+ }
921
+ const limit = typeof usageLimit === 'number' ? usageLimit : remainingUsage + usageUsed;
922
+ const remaining = remainingUsage ?? Math.max(0, limit - usageUsed);
923
+ if (usageReset === 'daily') {
924
+ const fallback = `오늘 남은 횟수 ${remaining}/${limit}`;
925
+ const translated = resolveText(t, { key: 'license.usage_daily' }, fallback);
926
+ return translated.includes(String(remaining)) ? translated : fallback;
927
+ }
928
+ if (usageReset === 'monthly') {
929
+ const fallback = `이번 달 남은 횟수 ${remaining}/${limit}`;
930
+ const translated = resolveText(t, { key: 'license.usage_monthly' }, fallback);
931
+ return translated.includes(String(remaining)) ? translated : fallback;
932
+ }
933
+ return `남은 횟수 ${remaining}/${limit}`;
934
+ }
935
+ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', wordpressLinks, paymentPageUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, className, }) => {
936
+ const links = React.useMemo(() => ({
937
+ purchaseUrl: wordpressLinks?.purchaseUrl ?? paymentPageUrl,
938
+ accountUrl: wordpressLinks?.accountUrl,
939
+ helpUrl: wordpressLinks?.helpUrl,
940
+ }), [wordpressLinks, paymentPageUrl]);
941
+ const { state, isVerifying, isDeactivating, isStartingAuth, verifyLicense, deactivateLicense, startDesignbaseAuth, setLicenseKeyInput, } = useFigmaLicenseBridge({
942
+ messageTypes,
943
+ initialState: {
944
+ paymentStatus: initialStatus,
945
+ licenseKey: initialLicenseKey,
946
+ usageCount: initialUsageCount,
947
+ },
948
+ onStateChange,
949
+ onPaymentStatusChange: setPaymentStatus,
950
+ onUsageCountChange: setUsageCount,
951
+ });
952
+ const [showDetails, setShowDetails] = React.useState(false);
953
+ const [licenseKeyDraft, setLicenseKeyDraft] = React.useState(initialLicenseKey);
954
+ const isPaid = state.isLicenseRegistered || state.paymentStatus === 'PAID';
955
+ const usageLabel = formatUsageLabel(state, t);
758
956
  const handleLicenseSubmit = async (submittedLicenseKey) => {
759
- setIsSubmitting(true);
760
- if (typeof parent !== 'undefined') {
761
- parent.postMessage({
762
- pluginMessage: {
763
- type: 'verify-license',
764
- licenseKey: submittedLicenseKey
765
- }
766
- }, '*');
957
+ if (onLicenseSubmit) {
958
+ await onLicenseSubmit(submittedLicenseKey);
959
+ return;
767
960
  }
961
+ verifyLicense(submittedLicenseKey);
768
962
  };
769
- const handleDeactivateLicense = () => {
770
- setIsDeactivating(true);
771
- if (typeof parent !== 'undefined') {
772
- parent.postMessage({
773
- pluginMessage: { type: 'deactivate-license' }
774
- }, '*');
775
- }
963
+ const handleLicenseKeyChange = (value) => {
964
+ setLicenseKeyDraft(value);
965
+ setLicenseKeyInput(value);
776
966
  };
777
- const isPaid = status === 'PAID';
778
967
  return (React.createElement("div", { className: `designbase-figma-page-license ${className || ''}` },
779
968
  React.createElement("div", { className: "designbase-figma-page-license__content" },
780
969
  React.createElement("div", { className: "designbase-figma-page-license__header" },
781
970
  React.createElement("div", { className: "designbase-figma-page-license__title" },
782
- React.createElement("h2", null, isPaid ? resolveText(t, { key: 'license.pro_account' }, '프로 계정') : resolveText(t, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드'))),
971
+ React.createElement("h2", null, isPaid
972
+ ? resolveText(t, { key: 'license.pro_account' }, '프로 계정')
973
+ : resolveText(t, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드')),
974
+ state.planTier && state.planTier !== 'FREE' && (React.createElement("span", { className: "designbase-figma-page-license__tier" }, state.planTier))),
783
975
  React.createElement("p", { className: "designbase-figma-page-license__description" }, isPaid
784
976
  ? resolveText(t, { key: 'license.all_features_available' }, '모든 기능을 사용할 수 있습니다.')
785
- : resolveText(t, { key: 'license.purchase_for_unlimited' }, '라이선스 구매 무제한 접근이 가능합니다.'))),
977
+ : resolveText(t, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
978
+ !isPaid && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
786
979
  React.createElement(PricingComparison, { features: pricingFeatures, pricing: pricing, paymentType: paymentType, t: t }),
980
+ state.lastMessage && (React.createElement("p", { className: `designbase-figma-page-license__feedback ${state.lastErrorCode ? 'designbase-figma-page-license__feedback--error' : ''}` }, state.lastMessage)),
787
981
  isPaid && (React.createElement("div", { className: "designbase-figma-page-license__section" },
788
982
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
789
983
  React.createElement("h3", null, resolveText(t, { key: 'license.activated' }, '라이선스 활성화됨')),
790
- React.createElement(ui.Button, { onClick: () => setShowDetails(!showDetails), variant: "tertiary", size: "s", iconOnly: true },
984
+ React.createElement(react.Button, { onClick: () => setShowDetails(!showDetails), variant: "tertiary", size: "s", iconOnly: true },
791
985
  React.createElement(icons.MoreHorizontalIcon, { size: 16 }))),
792
- React.createElement("div", { className: "designbase-figma-page-license__license-key" },
986
+ state.licenseKey && (React.createElement("div", { className: "designbase-figma-page-license__license-key" },
793
987
  resolveText(t, { key: 'license.key_label' }, '라이선스 키'),
794
988
  ": ",
795
- React.createElement("span", null, licenseKey)),
989
+ React.createElement("span", null, state.licenseKey))),
990
+ React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel),
796
991
  showDetails && (React.createElement("div", { className: "designbase-figma-page-license__details" },
797
992
  React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
798
993
  React.createElement("div", { className: "designbase-figma-page-license__remaining" },
799
- activationLimit - activationUsage,
800
- " ",
994
+ Math.max(0, state.activationLimit - state.activationUsage),
995
+ ' ',
801
996
  resolveText(t, { key: 'license.activations_remaining' }, '활성'),
802
- " ",
997
+ ' ',
803
998
  resolveText(t, { key: 'license.spots_remaining' }, '자리 남음')),
804
- React.createElement("div", { className: "designbase-figma-page-license__usage" },
805
- activationUsage,
999
+ React.createElement("div", { className: "designbase-figma-page-license__usage-count" },
1000
+ state.activationUsage,
806
1001
  "/",
807
- activationLimit)),
808
- React.createElement(ui.Button, { onClick: handleDeactivateLicense, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
809
- ? resolveText(t, { key: 'license.deactivating' }, '비활성화중...')
1002
+ state.activationLimit)),
1003
+ React.createElement(react.Button, { onClick: deactivateLicense, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
1004
+ ? resolveText(t, { key: 'license.deactivating' }, '비활성화 중...')
810
1005
  : resolveText(t, { key: 'license.deactivate' }, '라이선스 비활성화')))))),
811
- !isPaid && (React.createElement("div", { className: "designbase-figma-page-license__section" },
812
- React.createElement("div", { className: "designbase-figma-page-license__section-header" },
813
- React.createElement("h3", null, resolveText(t, { key: 'license.enter_key' }, '라이선스 키 입력')),
814
- paymentPageUrl && (React.createElement(ui.Button, { onClick: () => window.open(paymentPageUrl, '_blank'), variant: "primary", size: "s" },
815
- React.createElement("span", null, resolveText(t, { key: 'license.purchase' }, '라이선스 구매')),
816
- React.createElement(icons.ExternalLinkIcon, { size: 16 })))),
817
- React.createElement(FormWithSubmit, { onLicenseSubmit: handleLicenseSubmit, disabled: false, isSubmitting: isSubmitting, value: licenseKey, onValueChange: setLicenseKey, label: { key: 'license.key' }, submitText: { key: 'license.submit' }, submittingText: { key: 'license.verifying' }, helperText: { key: 'license.enter_from_email' }, t: t })))),
818
- React.createElement(ui.Button, { className: "designbase-figma-page-license__close", onPress: onClose, variant: "tertiary", size: "s", "aria-label": "Close" },
1006
+ !isPaid && (React.createElement(React.Fragment, null,
1007
+ (enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
1008
+ React.createElement("div", { className: "designbase-figma-page-license__section-header" },
1009
+ React.createElement("h3", null, resolveText(t, { key: 'license.designbase_account' }, '디자인베이스 계정'))),
1010
+ React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(t, { key: 'license.designbase_account_hint' }, 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.')),
1011
+ React.createElement("div", { className: "designbase-figma-page-license__actions" },
1012
+ enableAccountAuth && (React.createElement(react.Button, { onClick: startDesignbaseAuth, variant: "primary", size: "m", disabled: isStartingAuth || isVerifying, fullWidth: true }, isStartingAuth
1013
+ ? resolveText(t, { key: 'license.authenticating' }, '인증 중...')
1014
+ : resolveText(t, { key: 'license.login_with_designbase' }, '디자인베이스로 로그인'))),
1015
+ links.purchaseUrl && (React.createElement(react.Button, { onClick: () => openExternalUrl(links.purchaseUrl), variant: "secondary", size: "m", fullWidth: true },
1016
+ React.createElement("span", null, resolveText(t, { key: 'license.purchase_membership' }, '멤버십 구매')),
1017
+ React.createElement(icons.ExternalLinkIcon, { size: 16 }))),
1018
+ links.accountUrl && (React.createElement(react.Button, { onClick: () => openExternalUrl(links.accountUrl), variant: "tertiary", size: "s", fullWidth: true },
1019
+ React.createElement("span", null, resolveText(t, { key: 'license.manage_account' }, '계정·멤버십 관리')),
1020
+ React.createElement(icons.ExternalLinkIcon, { size: 16 })))))),
1021
+ showLicenseKeyInput && (React.createElement("div", { className: "designbase-figma-page-license__section" },
1022
+ React.createElement("div", { className: "designbase-figma-page-license__section-header" },
1023
+ React.createElement("h3", null, resolveText(t, { key: 'license.enter_key' }, '라이선스 키 입력'))),
1024
+ React.createElement(FormWithSubmit, { onLicenseSubmit: handleLicenseSubmit, disabled: false, isSubmitting: isVerifying, value: licenseKeyDraft, onValueChange: handleLicenseKeyChange, label: { key: 'license.key' }, submitText: { key: 'license.submit' }, submittingText: { key: 'license.verifying' }, helperText: { key: 'license.enter_from_email' }, t: t }))))),
1025
+ links.helpUrl && (React.createElement("p", { className: "designbase-figma-page-license__disclaimer" },
1026
+ React.createElement("button", { type: "button", className: "designbase-figma-page-license__link", onClick: () => openExternalUrl(links.helpUrl) }, resolveText(t, { key: 'license.help_link' }, '라이선스·결제 도움말'))))),
1027
+ React.createElement(react.Button, { className: "designbase-figma-page-license__close", onPress: onClose, variant: "tertiary", size: "s", "aria-label": "Close" },
819
1028
  React.createElement(icons.CloseIcon, { size: 20 }))));
820
1029
  };
821
1030
  PageLicense.displayName = 'PageLicense';
@@ -839,7 +1048,7 @@ const PaymentStatusSection = ({ status, usageCount, activationLimit, activationU
839
1048
  activationUsage,
840
1049
  "/",
841
1050
  activationLimit)),
842
- React.createElement(ui.Button, { onClick: onDeactivate, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
1051
+ React.createElement(react.Button, { onClick: onDeactivate, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
843
1052
  ? resolveText(t, { key: 'payment.deactivating' }, '비활성화중...')
844
1053
  : resolveText(t, { key: 'payment.deactivate_license' }, '라이선스 비활성화'))))));
845
1054
  };
@@ -880,16 +1089,16 @@ const ProgressModal = ({ isOpen, onClose, progress, title = { key: 'progress.wor
880
1089
  const displayStopText = resolveText(t, stopButtonText, '중지');
881
1090
  const displayConfirmText = resolveText(t, confirmButtonText, '확인');
882
1091
  const displayHelpText = resolveText(t, helpText);
883
- return (React.createElement(ui.Modal, { isOpen: isOpen, onClose: isCompleted ? onClose : undefined, title: displayTitle, size: "s", className: modalClasses, showCloseButton: false },
1092
+ return (React.createElement(react.Modal, { isOpen: isOpen, onClose: isCompleted ? onClose : undefined, title: displayTitle, size: "s", className: modalClasses, showCloseButton: false },
884
1093
  React.createElement("div", { className: "designbase-figma-progress-modal__content" },
885
1094
  React.createElement("div", { className: "designbase-figma-progress-modal__icon", "aria-hidden": "true" }, isCompleted ? (completeIcon || (React.createElement("div", { className: "designbase-figma-progress-modal__icon-success" },
886
1095
  React.createElement(icons.CircleCheckFilledIcon, null)))) : (loadingIcon || (React.createElement("div", { className: "designbase-figma-progress-modal__icon-loading" },
887
- React.createElement(ui.Spinner, { size: "m" }))))),
1096
+ React.createElement(react.Spinner, { size: "m" }))))),
888
1097
  React.createElement("p", { className: "designbase-figma-progress-modal__message" }, displayMessage),
889
1098
  React.createElement("div", { className: "designbase-figma-progress-modal__status" }, `${processedNodes} / ${totalNodes} (${progressPercentage.toFixed(1)}%)`),
890
- React.createElement(ui.Progressbar, { value: progressPercentage, size: "m", variant: isCompleted ? 'success' : 'primary', style: "animated", fullWidth: true }),
1099
+ React.createElement(react.Progressbar, { value: progressPercentage, size: "m", variant: isCompleted ? 'success' : 'primary', style: "animated", fullWidth: true }),
891
1100
  displayHelpText && !isCompleted && (React.createElement("p", { className: "designbase-figma-progress-modal__help-text" }, displayHelpText)),
892
- React.createElement("div", { className: "designbase-figma-progress-modal__actions" }, isCompleted ? (React.createElement(ui.Button, { onPress: handleConfirm, variant: "primary", size: "m", fullWidth: true }, displayConfirmText)) : (React.createElement(ui.Button, { onPress: handleStop, variant: "secondary", size: "m", fullWidth: true }, displayStopText))))));
1101
+ React.createElement("div", { className: "designbase-figma-progress-modal__actions" }, isCompleted ? (React.createElement(react.Button, { onPress: handleConfirm, variant: "primary", size: "m", fullWidth: true }, displayConfirmText)) : (React.createElement(react.Button, { onPress: handleStop, variant: "secondary", size: "m", fullWidth: true }, displayStopText))))));
893
1102
  };
894
1103
  ProgressModal.displayName = 'ProgressModal';
895
1104
 
@@ -1028,7 +1237,7 @@ const SettingsModal = ({ isOpen, onClose, categories: initialCategories, categor
1028
1237
  const modalClasses = clsx('designbase-figma-settings-modal', className);
1029
1238
  const displayTitle = resolveText(t, title, '목록 변경');
1030
1239
  const displayDescription = resolveText(t, description, '드래그하여 순서를 변경하거나, 토글하여 카테고리를 숨길 수 있습니다.');
1031
- return (React.createElement(ui.Modal, { isOpen: isOpen, onClose: onClose, title: displayTitle, size: "m", className: modalClasses },
1240
+ return (React.createElement(react.Modal, { isOpen: isOpen, onClose: onClose, title: displayTitle, size: "m", className: modalClasses },
1032
1241
  React.createElement("div", { className: "designbase-figma-settings-modal__content" },
1033
1242
  displayDescription && (React.createElement("p", { className: "designbase-figma-settings-modal__description" }, displayDescription)),
1034
1243
  React.createElement("ul", { className: "designbase-figma-settings-modal__list" }, tempCategories.map((category, index) => (React.createElement("li", { key: category.id, draggable: true, onDragStart: (e) => handleDragStart(e, index), onDragOver: handleDragOver, onDrop: (e) => handleDrop(e, index), onDragEnd: handleDragEnd, className: clsx('designbase-figma-settings-modal__item', {
@@ -1040,12 +1249,12 @@ const SettingsModal = ({ isOpen, onClose, categories: initialCategories, categor
1040
1249
  React.createElement(icons.GripVerticalIcon, { size: 16 })),
1041
1250
  category.icon && (React.createElement("span", { className: "designbase-figma-settings-modal__category-icon" }, category.icon)),
1042
1251
  React.createElement("span", { className: "designbase-figma-settings-modal__category-title" }, resolveText(t, category.title))),
1043
- React.createElement(ui.Toggle, { checked: category.enabled, onChange: () => handleToggle(category.id), size: "s" })))))),
1252
+ React.createElement(react.Toggle, { checked: category.enabled, onChange: () => handleToggle(category.id), size: "s" })))))),
1044
1253
  React.createElement("div", { className: "designbase-figma-settings-modal__footer" },
1045
- onReset && (React.createElement(ui.Button, { onPress: handleReset, variant: "tertiary", size: "s" }, resolveText(t, { key: 'settings.reset' }, '초기화'))),
1254
+ onReset && (React.createElement(react.Button, { onPress: handleReset, variant: "tertiary", size: "s" }, resolveText(t, { key: 'settings.reset' }, '초기화'))),
1046
1255
  React.createElement("div", { className: "designbase-figma-settings-modal__footer-right" },
1047
- React.createElement(ui.Button, { onPress: handleCancel, variant: "tertiary", size: "s" }, resolveText(t, { key: 'settings.cancel' }, '취소')),
1048
- React.createElement(ui.Button, { onPress: handleSave, variant: "primary", size: "s" }, resolveText(t, { key: 'settings.save' }, '저장'))))));
1256
+ React.createElement(react.Button, { onPress: handleCancel, variant: "tertiary", size: "s" }, resolveText(t, { key: 'settings.cancel' }, '취소')),
1257
+ React.createElement(react.Button, { onPress: handleSave, variant: "primary", size: "s" }, resolveText(t, { key: 'settings.save' }, '저장'))))));
1049
1258
  };
1050
1259
  SettingsModal.displayName = 'SettingsModal';
1051
1260
 
@@ -1088,12 +1297,13 @@ const UpgradeBanner = ({ onClick, variant = 'button', isLoading = false, title =
1088
1297
  React.createElement("div", { className: "designbase-figma-upgrade-banner__text-wrap" },
1089
1298
  React.createElement("h3", { className: "designbase-figma-upgrade-banner__title" }, displayTitle),
1090
1299
  React.createElement("p", { className: "designbase-figma-upgrade-banner__text" }, displayDescription)),
1091
- variant === 'button' ? (React.createElement(ui.Button, { onClick: onClick, variant: "primary", size: "m", disabled: isLoading }, displayButtonText)) : (React.createElement("div", { className: "designbase-figma-upgrade-banner__icon" },
1300
+ variant === 'button' ? (React.createElement(react.Button, { onPress: onClick, variant: "primary", size: "m", disabled: isLoading }, displayButtonText)) : (React.createElement("div", { className: "designbase-figma-upgrade-banner__icon" },
1092
1301
  React.createElement(icons.ChevronRightIcon, { size: 20 })))));
1093
- return (React.createElement("div", { className: `designbase-figma-upgrade-banner designbase-figma-upgrade-banner--${variant} ${className || ''}` }, useGradient ? (React.createElement(ui.RandomGradient, { scheme: gradientScheme, tone: gradientTone, animated: gradientAnimated, height: "100%", width: "100%", className: "designbase-figma-upgrade-banner__gradient-bg" }, bannerContent)) : (bannerContent)));
1302
+ return (React.createElement("div", { className: `designbase-figma-upgrade-banner designbase-figma-upgrade-banner--${variant} ${className || ''}` }, useGradient ? (React.createElement(react.RandomGradient, { scheme: gradientScheme, tone: gradientTone, animated: gradientAnimated, height: "100%", width: "100%", className: "designbase-figma-upgrade-banner__gradient-bg" }, bannerContent)) : (bannerContent)));
1094
1303
  };
1095
1304
  UpgradeBanner.displayName = 'UpgradeBanner';
1096
1305
 
1306
+ exports.DEFAULT_LICENSE_MESSAGE_TYPES = DEFAULT_LICENSE_MESSAGE_TYPES;
1097
1307
  exports.DonationBadge = DonationBadge;
1098
1308
  exports.FigmaContainer = FigmaContainer;
1099
1309
  exports.FigmaFooter = FigmaFooter;
@@ -1113,18 +1323,20 @@ exports.PaymentStatusSection = PaymentStatusSection;
1113
1323
  exports.PricingComparison = PricingComparison;
1114
1324
  exports.ProgressModal = ProgressModal;
1115
1325
  exports.ResizablePlugin = ResizablePlugin;
1326
+ exports.START_DESIGNBASE_AUTH_MESSAGE = START_DESIGNBASE_AUTH_MESSAGE;
1116
1327
  exports.SettingsModal = SettingsModal;
1117
1328
  exports.TitleDescription = TitleDescription;
1118
1329
  exports.UpgradeBanner = UpgradeBanner;
1119
1330
  exports.getActiveSection = getActiveSection;
1120
1331
  exports.resolveText = resolveText;
1121
1332
  exports.scrollToSection = scrollToSection;
1333
+ exports.useFigmaLicenseBridge = useFigmaLicenseBridge;
1122
1334
  exports.useFigmaToast = useFigmaToast;
1123
1335
  exports.useToast = useToast;
1124
- Object.keys(ui).forEach(function (k) {
1336
+ Object.keys(react).forEach(function (k) {
1125
1337
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1126
1338
  enumerable: true,
1127
- get: function () { return ui[k]; }
1339
+ get: function () { return react[k]; }
1128
1340
  });
1129
1341
  });
1130
1342
  //# sourceMappingURL=index.js.map