@designbasekorea/figma-ui 0.6.4 → 0.6.8

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
@@ -6,6 +6,14 @@ var icons = require('@designbasekorea/icons');
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
 
9
+ function interpolateText(template, values) {
10
+ if (!values)
11
+ return template;
12
+ return Object.entries(values).reduce((result, [key, value]) => {
13
+ const replacement = value == null ? '' : String(value);
14
+ return result.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), replacement);
15
+ }, template);
16
+ }
9
17
  function resolveText(t, input, fallback) {
10
18
  if (input == null)
11
19
  return fallback;
@@ -15,10 +23,13 @@ function resolveText(t, input, fallback) {
15
23
  if (t) {
16
24
  const translated = t(input.key, input.values);
17
25
  if (translated && translated !== input.key) {
18
- return translated;
26
+ return interpolateText(translated, input.values);
19
27
  }
20
28
  }
21
- return fallback ?? input.key;
29
+ if (fallback) {
30
+ return interpolateText(fallback, input.values);
31
+ }
32
+ return input.key;
22
33
  }
23
34
 
24
35
  const DONATION_ICON_NAMES = {
@@ -384,58 +395,63 @@ const FigmaSidebar = ({ categories, categoryGroups = {}, categoryLabels = {}, ac
384
395
  };
385
396
  FigmaSidebar.displayName = 'FigmaSidebar';
386
397
 
387
- const PaymentBadge = ({ isActive, onClick, isLoading = false, text, t = (key) => key, className, }) => {
388
- const getBadgeText = () => {
389
- if (text)
390
- return text;
391
- return isActive
392
- ? (t('proUser') || '프로 계정')
393
- : (t('usingFree') || '무료 사용');
394
- };
395
- const getBadgeVariant = () => {
396
- return isActive ? 'success' : 'secondary';
397
- };
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()))));
399
- };
400
- PaymentBadge.displayName = 'PaymentBadge';
401
-
402
- let useTranslation = null;
398
+ let useTranslation$2 = null;
403
399
  try {
404
400
  const reactI18next = require('react-i18next');
405
- useTranslation = reactI18next.useTranslation;
401
+ useTranslation$2 = reactI18next.useTranslation;
406
402
  }
407
403
  catch (e) {
408
404
  }
409
- const DEFAULT_LANGUAGES = [
410
- { code: 'ko', label: 'KO' },
411
- { code: 'en', label: 'EN' },
405
+ const DEFAULT_LANGUAGES$1 = [
406
+ { code: 'ko', label: '한국어' },
407
+ { code: 'en', label: 'English' },
408
+ { code: 'ja', label: '日本語' },
412
409
  ];
413
- const LanguageSelector = ({ currentLanguage, languages = DEFAULT_LANGUAGES, onLanguageChange, size = 's', className, t }) => {
414
- const i18n = useTranslation ? useTranslation().i18n : null;
415
- const activeLanguage = currentLanguage || (i18n?.language) || 'ko';
416
- const handleLanguageChange = (languageCode) => {
410
+ const defaultT$2 = (key) => {
411
+ const translations = {
412
+ languageSettings: '언어 설정',
413
+ languageSettingsDescription: '플러그인에 표시할 언어를 선택하세요.',
414
+ 'language.korean': '한국어',
415
+ 'language.english': 'English',
416
+ 'language.japanese': '日本語',
417
+ };
418
+ return translations[key] || key;
419
+ };
420
+ const LanguageSettingsModal = ({ isOpen, onClose, languages = DEFAULT_LANGUAGES$1, currentLanguage, onLanguageChange, title, description, className, t = defaultT$2, }) => {
421
+ const i18n = useTranslation$2 ? useTranslation$2().i18n : null;
422
+ const activeLanguage = currentLanguage || i18n?.language || languages[0]?.code;
423
+ const translate = (key, fallback) => {
424
+ const translated = t(key);
425
+ return translated && translated !== key ? translated : fallback;
426
+ };
427
+ const handleSelect = (languageCode) => {
417
428
  if (i18n) {
418
429
  i18n.changeLanguage(languageCode);
419
430
  }
420
- if (onLanguageChange) {
421
- onLanguageChange(languageCode);
422
- }
431
+ onLanguageChange?.(languageCode);
432
+ onClose();
423
433
  };
424
- const segmentOptions = languages.map((language) => ({
425
- value: language.code,
426
- label: resolveText(t, language.label),
427
- disabled: false,
428
- }));
429
- return (React.createElement("div", { className: `designbase-figma-language-selector ${className || ''}` },
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" })));
434
+ return (React.createElement(react.Modal, { isOpen: isOpen, onClose: onClose, title: title || translate('languageSettings', '언어 설정'), size: "s", className: clsx('designbase-figma-language-settings-modal', className) },
435
+ React.createElement("div", { className: "designbase-figma-language-settings-modal__content" },
436
+ React.createElement("p", { className: "designbase-figma-language-settings-modal__description" }, description || translate('languageSettingsDescription', '플러그인에 표시할 언어를 선택하세요.')),
437
+ React.createElement("ul", { className: "designbase-figma-language-settings-modal__list", role: "listbox", "aria-label": translate('languageSettings', '언어 설정') }, languages.map((language) => {
438
+ const label = resolveText(t, language.label, language.code.toUpperCase());
439
+ const isActive = language.code === activeLanguage;
440
+ return (React.createElement("li", { key: language.code, role: "presentation" },
441
+ React.createElement("button", { type: "button", className: clsx('designbase-figma-language-settings-modal__option', { 'designbase-figma-language-settings-modal__option--active': isActive }), role: "option", "aria-selected": isActive, onClick: () => handleSelect(language.code) },
442
+ React.createElement("span", { className: "designbase-figma-language-settings-modal__option-label" }, label),
443
+ React.createElement("span", { className: "designbase-figma-language-settings-modal__option-indicator", "aria-hidden": "true" }))));
444
+ })))));
436
445
  };
437
- LanguageSelector.displayName = 'LanguageSelector';
446
+ LanguageSettingsModal.displayName = 'LanguageSettingsModal';
438
447
 
448
+ let useTranslation$1 = null;
449
+ try {
450
+ const reactI18next = require('react-i18next');
451
+ useTranslation$1 = reactI18next.useTranslation;
452
+ }
453
+ catch (e) {
454
+ }
439
455
  const defaultLinks = [
440
456
  {
441
457
  name: 'officialWebsite',
@@ -469,50 +485,219 @@ const defaultTranslations$1 = {
469
485
  instagram: '인스타그램',
470
486
  figmaCommunity: '피그마 커뮤니티',
471
487
  contact: '문의하기',
488
+ languageSettings: '언어 설정',
472
489
  };
473
490
  const defaultT$1 = (key) => defaultTranslations$1[key] || key;
474
- const LogoDropdown = ({ logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', links = defaultLinks, position = 'top-left', className, t = defaultT$1, }) => {
491
+ const defaultLanguages = [
492
+ { code: 'ko', label: '한국어' },
493
+ { code: 'en', label: 'English' },
494
+ { code: 'ja', label: '日本語' },
495
+ ];
496
+ const LogoDropdown = ({ logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', links = defaultLinks, position = 'top-left', className, t = defaultT$1, showLanguageSelector = true, languages = defaultLanguages, currentLanguage, onLanguageChange, }) => {
475
497
  const [isOpen, setIsOpen] = React.useState(false);
476
- const toggleDropdown = () => setIsOpen(!isOpen);
498
+ const [isLanguageModalOpen, setIsLanguageModalOpen] = React.useState(false);
499
+ const i18n = useTranslation$1 ? useTranslation$1().i18n : null;
500
+ const rootRef = React.useRef(null);
501
+ const triggerRef = React.useRef(null);
502
+ const menuId = `designbase-figma-logo-menu-${React.useId().replace(/:/g, '')}`;
503
+ const activeLanguage = currentLanguage || i18n?.language || languages[0]?.code;
504
+ const translate = (key, fallback) => {
505
+ const translated = t(key);
506
+ return translated && translated !== key ? translated : fallback;
507
+ };
508
+ React.useEffect(() => {
509
+ if (!isOpen) {
510
+ return undefined;
511
+ }
512
+ const handlePointerDown = (event) => {
513
+ if (!rootRef.current?.contains(event.target)) {
514
+ setIsOpen(false);
515
+ }
516
+ };
517
+ const handleKeyDown = (event) => {
518
+ if (event.key === 'Escape') {
519
+ setIsOpen(false);
520
+ triggerRef.current?.focus();
521
+ }
522
+ };
523
+ document.addEventListener('mousedown', handlePointerDown);
524
+ document.addEventListener('keydown', handleKeyDown);
525
+ return () => {
526
+ document.removeEventListener('mousedown', handlePointerDown);
527
+ document.removeEventListener('keydown', handleKeyDown);
528
+ };
529
+ }, [isOpen]);
530
+ const toggleDropdown = () => setIsOpen((value) => !value);
477
531
  const handleLinkClick = (url) => {
532
+ setIsOpen(false);
478
533
  if (url.startsWith('mailto:')) {
479
534
  return;
480
535
  }
481
536
  window.open(url, '_blank', 'noopener,noreferrer');
482
537
  };
538
+ const handleLanguageSettingsClick = () => {
539
+ setIsOpen(false);
540
+ setIsLanguageModalOpen(true);
541
+ };
542
+ const handleLanguageChange = (languageCode) => {
543
+ if (i18n) {
544
+ i18n.changeLanguage(languageCode);
545
+ }
546
+ onLanguageChange?.(languageCode);
547
+ };
483
548
  const classes = clsx('designbase-figma-logo-dropdown', `designbase-figma-logo-dropdown--${position}`, {
484
549
  'designbase-figma-logo-dropdown--open': isOpen,
485
550
  }, className);
486
551
  const renderLogo = () => {
487
- if (logoSrc) {
488
- return (React.createElement("img", { className: "designbase-figma-logo-dropdown__logo", src: logoSrc, alt: logoAlt, onClick: toggleDropdown }));
489
- }
490
- return (React.createElement("div", { className: "designbase-figma-logo-dropdown__logo", onClick: toggleDropdown },
491
- React.createElement(react.Logo, { type: logoType, size: logoSize, variant: "default" })));
552
+ return (React.createElement("button", { ref: triggerRef, type: "button", className: "designbase-figma-logo-dropdown__logo", "aria-label": logoAlt, "aria-expanded": isOpen, "aria-controls": menuId, "aria-haspopup": "menu", onClick: toggleDropdown }, logoSrc ? (React.createElement("img", { src: logoSrc, alt: "" })) : (React.createElement(react.Logo, { type: logoType, size: logoSize, variant: "default" }))));
492
553
  };
493
- return (React.createElement("div", { className: classes },
554
+ return (React.createElement("div", { ref: rootRef, className: classes },
494
555
  renderLogo(),
495
- isOpen && (React.createElement("ul", { className: "designbase-figma-logo-dropdown__menu" }, links.map((link, index) => (React.createElement("li", { key: index, className: "designbase-figma-logo-dropdown__item" },
496
- React.createElement("button", { type: "button", className: "designbase-figma-logo-dropdown__link", onClick: () => handleLinkClick(link.url) },
497
- link.icon && (React.createElement("span", { className: "designbase-figma-logo-dropdown__icon" }, link.icon)),
498
- React.createElement("span", { className: "designbase-figma-logo-dropdown__text" }, t(link.name)),
499
- React.createElement(icons.ExternalLinkIcon, { size: 16, className: "designbase-figma-logo-dropdown__arrow" })))))))));
556
+ isOpen && (React.createElement("ul", { id: menuId, className: "designbase-figma-logo-dropdown__menu", role: "menu" },
557
+ links.map((link, index) => (React.createElement("li", { key: index, className: "designbase-figma-logo-dropdown__item", role: "none" },
558
+ React.createElement("button", { type: "button", className: "designbase-figma-logo-dropdown__link", role: "menuitem", onClick: () => handleLinkClick(link.url) },
559
+ link.icon && (React.createElement("span", { className: "designbase-figma-logo-dropdown__icon" }, link.icon)),
560
+ React.createElement("span", { className: "designbase-figma-logo-dropdown__text" }, t(link.name)),
561
+ React.createElement(icons.ExternalLinkIcon, { size: 16, className: "designbase-figma-logo-dropdown__arrow" }))))),
562
+ showLanguageSelector && (React.createElement("li", { className: "designbase-figma-logo-dropdown__item designbase-figma-logo-dropdown__language-item", role: "none" },
563
+ React.createElement("button", { type: "button", className: "designbase-figma-logo-dropdown__link", role: "menuitem", onClick: handleLanguageSettingsClick },
564
+ React.createElement("span", { className: "designbase-figma-logo-dropdown__icon" },
565
+ React.createElement(icons.TranslateIcon, { size: 20, "aria-hidden": "true" })),
566
+ React.createElement("span", { className: "designbase-figma-logo-dropdown__text" }, translate('languageSettings', '언어 설정'))))))),
567
+ showLanguageSelector && (React.createElement(LanguageSettingsModal, { isOpen: isLanguageModalOpen, onClose: () => setIsLanguageModalOpen(false), languages: languages, currentLanguage: activeLanguage, onLanguageChange: handleLanguageChange, t: t }))));
500
568
  };
501
569
  LogoDropdown.displayName = 'LogoDropdown';
502
570
 
571
+ const fallbackText = (t, key, fallback) => {
572
+ const translated = t?.(key);
573
+ return translated && translated !== key ? translated : fallback;
574
+ };
575
+ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, t, className, }) => {
576
+ const [isOpen, setIsOpen] = React.useState(false);
577
+ const rootRef = React.useRef(null);
578
+ const triggerRef = React.useRef(null);
579
+ const popoverId = `designbase-figma-usage-popover-${React.useId().replace(/:/g, '')}`;
580
+ const isPaid = paymentStatus === 'PAID';
581
+ const isBeta = paymentStatus === 'BETA';
582
+ const hasDailyLimit = !isPaid && maxDailyUsage > 0;
583
+ const limit = Math.max(1, Math.round(maxDailyUsage));
584
+ const used = Math.min(limit, Math.max(0, Math.round(usageCount)));
585
+ const remaining = Math.max(0, limit - used);
586
+ const usedPercent = hasDailyLimit ? Math.round((used / limit) * 100) : 0;
587
+ const hasControl = showUsage || showPlan;
588
+ const planLabel = isPaid
589
+ ? fallbackText(t, 'proUser', '프로')
590
+ : isBeta
591
+ ? fallbackText(t, 'betaStatus', 'BETA')
592
+ : paymentStatus === 'TRIAL'
593
+ ? fallbackText(t, 'trialPlan', '체험판')
594
+ : fallbackText(t, 'free', '무료');
595
+ const planTitle = isBeta
596
+ ? planLabel
597
+ : `${planLabel} ${fallbackText(t, 'planSuffix', '플랜')}`;
598
+ const triggerLabel = isPaid
599
+ ? `${planLabel}, ${fallbackText(t, 'unlimitedUsage', '무제한 사용 가능')}`
600
+ : isBeta
601
+ ? planLabel
602
+ : hasDailyLimit
603
+ ? `${remaining}/${limit} ${fallbackText(t, 'remainingShort', '남음')}`
604
+ : planLabel;
605
+ const upgradeLabel = isPaid
606
+ ? fallbackText(t, 'managePlan', '플랜 관리')
607
+ : fallbackText(t, 'upgradePlan', '플랜 업그레이드');
608
+ React.useEffect(() => {
609
+ if (!isOpen)
610
+ return undefined;
611
+ const handlePointerDown = (event) => {
612
+ if (!rootRef.current?.contains(event.target)) {
613
+ setIsOpen(false);
614
+ }
615
+ };
616
+ const handleKeyDown = (event) => {
617
+ if (event.key === 'Escape') {
618
+ setIsOpen(false);
619
+ triggerRef.current?.focus();
620
+ }
621
+ };
622
+ document.addEventListener('mousedown', handlePointerDown);
623
+ document.addEventListener('keydown', handleKeyDown);
624
+ return () => {
625
+ document.removeEventListener('mousedown', handlePointerDown);
626
+ document.removeEventListener('keydown', handleKeyDown);
627
+ };
628
+ }, [isOpen]);
629
+ if (!hasControl)
630
+ return null;
631
+ const handleManageClick = () => {
632
+ setIsOpen(false);
633
+ onLicensePageClick?.();
634
+ };
635
+ const togglePopover = () => setIsOpen((value) => !value);
636
+ return (React.createElement("div", { ref: rootRef, className: clsx('designbase-figma-usage-status', {
637
+ 'designbase-figma-usage-status--open': isOpen,
638
+ 'designbase-figma-usage-status--unlimited': isPaid,
639
+ 'designbase-figma-usage-status--loading': isLoading,
640
+ }, className) },
641
+ React.createElement("div", { className: "designbase-figma-usage-status__control" },
642
+ showUsage && (React.createElement("button", { ref: triggerRef, type: "button", className: "designbase-figma-usage-status__trigger", "aria-expanded": isOpen, "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": isLoading ? fallbackText(t, 'loading', '불러오는 중') : triggerLabel, disabled: isLoading, onClick: togglePopover }, isLoading ? (React.createElement("span", { className: "designbase-figma-usage-status__skeleton", "aria-hidden": "true" })) : isPaid ? (React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E")) : hasDailyLimit ? (React.createElement(React.Fragment, null,
643
+ React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
644
+ React.createElement("span", { style: { width: `${usedPercent}%` } })),
645
+ React.createElement("span", { className: "designbase-figma-usage-status__usage-value" },
646
+ React.createElement("strong", null, remaining),
647
+ React.createElement("span", null,
648
+ "/",
649
+ limit)))) : (React.createElement("span", { className: "designbase-figma-usage-status__plan-label" }, planLabel)))),
650
+ showPlan && !isLoading && (React.createElement("button", { type: "button", className: "designbase-figma-usage-status__plan-badge", "aria-expanded": isOpen, "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": planTitle, onClick: togglePopover }, planLabel))),
651
+ isOpen && (React.createElement("div", { id: popoverId, className: "designbase-figma-usage-status__popover", role: "dialog", "aria-label": fallbackText(t, 'usageDetails', '사용량 상세') },
652
+ React.createElement("div", { className: "designbase-figma-usage-status__popover-header" },
653
+ React.createElement("span", { className: "designbase-figma-usage-status__plan-title" }, planTitle),
654
+ !isBeta && (React.createElement(react.Button, { className: "designbase-figma-usage-status__upgrade", variant: isPaid ? 'secondary' : 'primary', size: "s", endIcon: "chevron-right", onPress: handleManageClick }, upgradeLabel))),
655
+ isPaid ? (React.createElement("div", { className: "designbase-figma-usage-status__unlimited-copy" },
656
+ React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E"),
657
+ React.createElement("span", null, fallbackText(t, 'unlimitedUsageTooltip', '모든 기능을 제한 없이 사용할 수 있습니다')))) : isBeta ? (React.createElement("p", { className: "designbase-figma-usage-status__note" }, fallbackText(t, 'betaUsageDescription', '베타 기간에는 사용량 제한이 적용되지 않습니다'))) : hasDailyLimit ? (React.createElement("div", { className: "designbase-figma-usage-status__usage-detail" },
658
+ React.createElement("div", { className: "designbase-figma-usage-status__usage-summary" },
659
+ React.createElement("strong", { className: "designbase-figma-usage-status__usage-count" },
660
+ used,
661
+ React.createElement("span", { className: "designbase-figma-usage-status__usage-divider" }, "/"),
662
+ limit),
663
+ React.createElement("span", { className: "designbase-figma-usage-status__usage-caption" }, fallbackText(t, 'usageCountCaption', '오늘 사용'))),
664
+ React.createElement("div", { className: "designbase-figma-usage-status__progress", role: "progressbar", "aria-label": fallbackText(t, 'usageCountCaption', '오늘 사용'), "aria-valuemin": 0, "aria-valuemax": limit, "aria-valuenow": used, "aria-valuetext": `${used} / ${limit}` },
665
+ React.createElement("span", { style: { width: `${usedPercent}%` } })),
666
+ React.createElement("p", { className: "designbase-figma-usage-status__remaining-copy" }, resolveText(t, { key: 'remainingCopy', values: { count: remaining } }, `${remaining}회 남음 · 매일 리셋`)))) : (React.createElement("p", { className: "designbase-figma-usage-status__note" }, fallbackText(t, 'usageUnavailable', '사용량 제한이 없습니다')))))));
667
+ };
668
+ UsageStatusPopover.displayName = 'UsageStatusPopover';
669
+
503
670
  const defaultTranslations = {
504
671
  unlimitedUsage: '무제한 사용',
672
+ proUser: '프로',
673
+ free: '무료',
674
+ trialPlan: '체험판',
675
+ planSuffix: '플랜',
676
+ usageDetails: '사용량 상세',
677
+ dailyUsage: '오늘 사용량',
678
+ usedToday: '오늘 사용',
679
+ remainingToday: '오늘 남은 사용량',
680
+ remainingUsage: '오늘 남은 사용량',
681
+ managePlan: '플랜 관리',
682
+ upgradePlan: '플랜 업그레이드',
683
+ remainingShort: '남음',
684
+ usageCountCaption: '오늘 사용',
685
+ remainingCopy: '{{count}}회 남음 · 매일 리셋',
686
+ usageUnavailable: '사용량 제한이 없습니다',
687
+ betaUsageDescription: '베타 기간에는 사용량 제한이 적용되지 않습니다',
505
688
  perDay: '일',
506
689
  resetsDaily: '매일 리셋',
507
690
  donationPrompt: '이 플러그인이 유용했나요?',
508
691
  betaStatus: 'BETA',
509
692
  };
510
- const defaultT = (key) => defaultTranslations[key] || key;
511
- const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount = 0, isLoading = false, showPaymentStatus = true, showUsageInfo = true, maxDailyUsage = 20, showPaymentBadge = true, showDonation = true, donationUrl = 'https://buymeacoffee.com/designbase', donationText = 'Buy me a coffee', showDonationText = true, donationPromptText, showLanguageSelector = false, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t = defaultT, children, }) => {
512
- const isActive = paymentStatus === 'PAID';
513
- const isBeta = paymentStatus === 'BETA';
514
- const resolvedShowUsageInfo = showUsageInfo && !isLoading && !isBeta;
693
+ const defaultT = (key, values) => {
694
+ const template = defaultTranslations[key] || key;
695
+ return interpolateText(template, values);
696
+ };
697
+ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount = 0, isLoading = false, showPaymentStatus = true, showUsageInfo = true, maxDailyUsage = 20, showPaymentBadge = true, showDonation = true, donationUrl = 'https://buymeacoffee.com/designbase', donationText = 'Buy me a coffee', showDonationText = true, donationPromptText, showLanguageSelector = true, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t = defaultT, children, }) => {
698
+ const resolvedShowUsageInfo = showPaymentStatus && showUsageInfo;
515
699
  const resolvedShowPaymentBadge = showPaymentStatus && showPaymentBadge;
700
+ const resolvedLicensePageClick = paymentStatus === 'BETA' ? undefined : onLicensePageClick;
516
701
  const hasChildren = React.Children.count(children) > 0;
517
702
  const classes = clsx('designbase-figma-footer', {
518
703
  'designbase-figma-footer--has-children': hasChildren,
@@ -520,17 +705,9 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
520
705
  return (React.createElement("footer", { className: classes },
521
706
  React.createElement("div", { className: "designbase-figma-footer__wrap" },
522
707
  React.createElement("div", { className: "designbase-figma-footer__left" },
523
- React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, t: t }),
524
- showLanguageSelector && (React.createElement(LanguageSelector, { currentLanguage: currentLanguage, languages: languages, onLanguageChange: onLanguageChange, size: "s" }))),
708
+ React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, languages: languages, currentLanguage: currentLanguage, showLanguageSelector: showLanguageSelector, onLanguageChange: onLanguageChange, t: t })),
525
709
  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 })),
710
+ (resolvedShowUsageInfo || resolvedShowPaymentBadge) && (React.createElement(UsageStatusPopover, { paymentStatus: paymentStatus, usageCount: usageCount, maxDailyUsage: maxDailyUsage, showUsage: resolvedShowUsageInfo, showPlan: resolvedShowPaymentBadge, isLoading: isLoading, onLicensePageClick: resolvedLicensePageClick, t: t })),
534
711
  showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: t })))),
535
712
  children));
536
713
  };
@@ -654,6 +831,205 @@ const InteractionFeedback = ({ status = 'default', message, statusMessage, leftC
654
831
  };
655
832
  InteractionFeedback.displayName = 'InteractionFeedback';
656
833
 
834
+ let useTranslation = null;
835
+ try {
836
+ const reactI18next = require('react-i18next');
837
+ useTranslation = reactI18next.useTranslation;
838
+ }
839
+ catch (e) {
840
+ }
841
+ const DEFAULT_LANGUAGES = [
842
+ { code: 'ko', label: 'KO' },
843
+ { code: 'en', label: 'EN' },
844
+ ];
845
+ const LanguageSelector = ({ currentLanguage, languages = DEFAULT_LANGUAGES, onLanguageChange, size = 's', className, t }) => {
846
+ const i18n = useTranslation ? useTranslation().i18n : null;
847
+ const activeLanguage = currentLanguage || (i18n?.language) || 'ko';
848
+ const handleLanguageChange = (languageCode) => {
849
+ if (i18n) {
850
+ i18n.changeLanguage(languageCode);
851
+ }
852
+ if (onLanguageChange) {
853
+ onLanguageChange(languageCode);
854
+ }
855
+ };
856
+ const segmentOptions = languages.map((language) => ({
857
+ value: language.code,
858
+ label: resolveText(t, language.label),
859
+ disabled: false,
860
+ }));
861
+ return (React.createElement("div", { className: `designbase-figma-language-selector ${className || ''}` },
862
+ React.createElement(react.SegmentControl, { options: segmentOptions, value: activeLanguage, onChange: (event) => {
863
+ const detail = event.detail;
864
+ const value = typeof detail === 'object' && detail !== null && 'value' in detail &&
865
+ typeof detail.value === 'string'
866
+ ? detail.value
867
+ : undefined;
868
+ if (value) {
869
+ handleLanguageChange(value);
870
+ }
871
+ }, size: size, className: "designbase-figma-language-selector__segment" })));
872
+ };
873
+ LanguageSelector.displayName = 'LanguageSelector';
874
+
875
+ function postPluginMessage(message) {
876
+ if (typeof parent === 'undefined') {
877
+ return;
878
+ }
879
+ parent.postMessage({ pluginMessage: message }, '*');
880
+ }
881
+ function openExternalUrl(url) {
882
+ if (!url)
883
+ return;
884
+ postPluginMessage({ type: 'open-external-url', url });
885
+ if (typeof window !== 'undefined') {
886
+ window.open(url, '_blank', 'noopener,noreferrer');
887
+ }
888
+ }
889
+
890
+ const LicenseOffer = ({ joinUrl, guideUrl, membershipUrl, t, className, }) => {
891
+ const titleId = `designbase-license-offer-title-${React.useId().replace(/:/g, '')}`;
892
+ const resolvedJoinUrl = joinUrl || membershipUrl;
893
+ const steps = [
894
+ resolveText(t, { key: 'license.youtube_membership_step_1' }, 'Designbase YouTube 채널 멤버십에 가입합니다.'),
895
+ resolveText(t, { key: 'license.youtube_membership_step_2' }, '멤버 전용 커뮤니티에서 이번 달 키를 복사합니다.'),
896
+ resolveText(t, { key: 'license.youtube_membership_step_3' }, '아래 입력창에 키를 붙여 넣고 활성화합니다.'),
897
+ ];
898
+ return (React.createElement("section", { className: `designbase-figma-license-offer ${className || ''}`, "aria-labelledby": titleId },
899
+ React.createElement("h3", { id: titleId, className: "designbase-figma-license-offer__title" }, resolveText(t, { key: 'license.youtube_membership_howto' }, '이용 방법')),
900
+ React.createElement("ol", { className: "designbase-figma-license-offer__steps" }, steps.map((step, index) => (React.createElement("li", { key: index },
901
+ React.createElement("span", { className: "designbase-figma-license-offer__step-index", "aria-hidden": "true" },
902
+ index + 1,
903
+ "."),
904
+ React.createElement("span", null, step))))),
905
+ (resolvedJoinUrl || guideUrl) && (React.createElement("div", { className: "designbase-figma-license-offer__actions" },
906
+ resolvedJoinUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(resolvedJoinUrl), variant: "primary", size: "m", fullWidth: true }, resolveText(t, { key: 'license.youtube_membership_join' }, '멤버십 가입'))),
907
+ guideUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(guideUrl), variant: "secondary", size: "m", fullWidth: true },
908
+ React.createElement("span", null, resolveText(t, { key: 'license.youtube_membership_guide' }, '안내보기')),
909
+ React.createElement(icons.ExternalLinkIcon, { size: 16, "aria-hidden": "true" })))))));
910
+ };
911
+ LicenseOffer.displayName = 'LicenseOffer';
912
+
913
+ function maskLicenseKey(value) {
914
+ if (value.length <= 8)
915
+ return '••••••••';
916
+ return `${value.slice(0, 4)}••••${value.slice(-4)}`;
917
+ }
918
+ function formatDate(value) {
919
+ if (!value)
920
+ return undefined;
921
+ const date = new Date(value);
922
+ if (Number.isNaN(date.getTime()))
923
+ return value;
924
+ return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(date);
925
+ }
926
+ function formatScope(value, t) {
927
+ if (!value)
928
+ return undefined;
929
+ if (value === 'all-products' || value === 'all_products') {
930
+ return resolveText(t, { key: 'license.all_plugins' }, '모든 플러그인');
931
+ }
932
+ return value;
933
+ }
934
+ function formatSource(value, t) {
935
+ if (!value)
936
+ return undefined;
937
+ if (value === 'youtube_membership' || value === 'membership') {
938
+ return resolveText(t, { key: 'license.source_youtube_membership' }, 'YouTube 멤버십');
939
+ }
940
+ if (value === 'lemonsqueezy') {
941
+ return resolveText(t, { key: 'license.source_purchase' }, '구매 라이선스');
942
+ }
943
+ return value;
944
+ }
945
+ const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSource, accessScope, expiresAt, lastVerifiedAt, validationMessage, allowRevealKey = false, t, className, }) => {
946
+ const [isKeyRevealed, setIsKeyRevealed] = React.useState(false);
947
+ const normalizedLicenseStatus = licenseStatus?.toLowerCase();
948
+ const isInactiveStatus = ['expired', 'revoked', 'invalid', 'inactive'].includes(normalizedLicenseStatus || '');
949
+ const isActive = status === 'PAID' && !isInactiveStatus;
950
+ const statusText = isActive
951
+ ? resolveText(t, { key: 'license.status_active' }, 'Active')
952
+ : resolveText(t, { key: 'license.status_inactive' }, 'License check failed');
953
+ const statusClass = isActive ? 'active' : 'inactive';
954
+ return (React.createElement("section", { className: `designbase-figma-license-status-card designbase-figma-license-status-card--${statusClass} ${className || ''}`, "aria-label": statusText },
955
+ React.createElement("div", { className: "designbase-figma-license-status-card__header" },
956
+ React.createElement("div", null,
957
+ React.createElement("div", { className: "designbase-figma-license-status-card__eyebrow" }, isActive
958
+ ? resolveText(t, { key: 'license.activated' }, '라이선스 활성화됨')
959
+ : resolveText(t, { key: 'license.status_label' }, '라이선스 상태')),
960
+ React.createElement("h3", null, statusText)),
961
+ React.createElement("span", { className: "designbase-figma-license-status-card__badge" }, licenseStatus || (isActive ? 'active' : 'inactive'))),
962
+ validationMessage && !isActive && (React.createElement("p", { className: "designbase-figma-license-status-card__message" }, validationMessage)),
963
+ licenseKey && (React.createElement("div", { className: "designbase-figma-license-status-card__key-row" },
964
+ React.createElement("span", null, resolveText(t, { key: 'license.key_label' }, '라이선스 키')),
965
+ React.createElement("code", null, allowRevealKey && isKeyRevealed ? licenseKey : maskLicenseKey(licenseKey)),
966
+ allowRevealKey && (React.createElement(react.Button, { type: "button", onPress: () => setIsKeyRevealed((value) => !value), variant: "tertiary", size: "s" }, isKeyRevealed
967
+ ? resolveText(t, { key: 'license.hide_key' }, '숨기기')
968
+ : resolveText(t, { key: 'license.reveal_key' }, '보기'))))),
969
+ (licenseSource || accessScope || expiresAt || lastVerifiedAt) && (React.createElement("dl", { className: "designbase-figma-license-status-card__meta" },
970
+ formatSource(licenseSource, t) && React.createElement(React.Fragment, null,
971
+ React.createElement("dt", null, resolveText(t, { key: 'license.source' }, '출처')),
972
+ React.createElement("dd", null, formatSource(licenseSource, t))),
973
+ formatScope(accessScope, t) && React.createElement(React.Fragment, null,
974
+ React.createElement("dt", null, resolveText(t, { key: 'license.access' }, '접근 범위')),
975
+ React.createElement("dd", null, formatScope(accessScope, t))),
976
+ expiresAt && React.createElement(React.Fragment, null,
977
+ React.createElement("dt", null, resolveText(t, { key: 'license.expires' }, '만료일')),
978
+ React.createElement("dd", null, formatDate(expiresAt) || expiresAt)),
979
+ lastVerifiedAt && React.createElement(React.Fragment, null,
980
+ React.createElement("dt", null, resolveText(t, { key: 'license.last_checked' }, '최근 확인')),
981
+ React.createElement("dd", null, formatDate(lastVerifiedAt) || lastVerifiedAt))))));
982
+ };
983
+ LicenseStatusCard.displayName = 'LicenseStatusCard';
984
+
985
+ function resolvePaymentFeedbackVariant(errorCode, explicitVariant) {
986
+ if (explicitVariant)
987
+ return explicitVariant;
988
+ if (!errorCode)
989
+ return 'success';
990
+ const normalized = errorCode.toLowerCase();
991
+ if (normalized.includes('network')
992
+ || normalized.includes('server')
993
+ || normalized.includes('rate')
994
+ || normalized.includes('timeout')) {
995
+ return 'warning';
996
+ }
997
+ if (normalized.includes('info')) {
998
+ return 'info';
999
+ }
1000
+ return 'error';
1001
+ }
1002
+ const PaymentStatusSection = ({ activationLimit, activationUsage, licenseKey, onDeactivate, isDeactivating = false, showDetails = false, actionMessage, actionMessageVariant, errorCode, className, t, }) => {
1003
+ const remainingActivations = Math.max(0, activationLimit - activationUsage);
1004
+ const resolvedActionMessage = actionMessage ? resolveText(t, actionMessage) : undefined;
1005
+ const feedbackVariant = resolvedActionMessage
1006
+ ? resolvePaymentFeedbackVariant(errorCode, actionMessageVariant)
1007
+ : undefined;
1008
+ return (React.createElement("div", { className: clsx('designbase-figma-payment-status', className) },
1009
+ React.createElement("div", { className: "designbase-figma-payment-status__license-key" },
1010
+ resolveText(t, { key: 'payment.license_key_label' }, '라이선스 키'),
1011
+ ": ",
1012
+ React.createElement("span", null, licenseKey)),
1013
+ showDetails && (React.createElement("div", { className: "designbase-figma-payment-status__details" },
1014
+ React.createElement("div", { className: "designbase-figma-payment-status__activation-info" },
1015
+ React.createElement("div", { className: "designbase-figma-payment-status__remaining" },
1016
+ remainingActivations,
1017
+ ' ',
1018
+ resolveText(t, { key: 'payment.activations_remaining' }, '활성'),
1019
+ ' ',
1020
+ resolveText(t, { key: 'payment.spots_remaining' }, '자리 남음')),
1021
+ React.createElement("div", { className: "designbase-figma-payment-status__usage" },
1022
+ activationUsage,
1023
+ "/",
1024
+ activationLimit)),
1025
+ React.createElement("div", { className: "designbase-figma-payment-status__action" },
1026
+ React.createElement(react.Button, { onPress: onDeactivate, variant: "secondary", size: "s", fullWidth: true, disabled: isDeactivating }, isDeactivating
1027
+ ? resolveText(t, { key: 'payment.deactivating' }, '비활성화중...')
1028
+ : resolveText(t, { key: 'payment.deactivate_license' }, '라이선스 비활성화')),
1029
+ resolvedActionMessage && feedbackVariant && (React.createElement("p", { className: clsx('designbase-figma-payment-status__feedback', `designbase-figma-payment-status__feedback--${feedbackVariant}`), role: feedbackVariant === 'error' ? 'alert' : 'status', "aria-live": "polite" }, resolvedActionMessage)))))));
1030
+ };
1031
+ PaymentStatusSection.displayName = 'PaymentStatusSection';
1032
+
657
1033
  const defaultFeatures = [
658
1034
  { name: '사용 제한', free: '일일 제한', pro: '무제한' },
659
1035
  { name: '모든 주제 사용', free: false, pro: true },
@@ -687,7 +1063,11 @@ const PricingComparison = ({ features = defaultFeatures, pricing = defaultPricin
687
1063
  return (React.createElement("div", { className: `designbase-figma-pricing-comparison ${className || ''}` },
688
1064
  paymentType === 'subscription' && (React.createElement("div", { className: "designbase-figma-pricing-comparison__billing-toggle" },
689
1065
  React.createElement(react.SegmentControl, { value: isYearly ? 'yearly' : 'monthly', onChange: (event) => {
690
- const value = event.detail?.value;
1066
+ const detail = event.detail;
1067
+ const value = typeof detail === 'object' && detail !== null && 'value' in detail &&
1068
+ typeof detail.value === 'string'
1069
+ ? detail.value
1070
+ : undefined;
691
1071
  setIsYearly(value === 'yearly');
692
1072
  }, options: [
693
1073
  {
@@ -724,21 +1104,6 @@ const PricingComparison = ({ features = defaultFeatures, pricing = defaultPricin
724
1104
  };
725
1105
  PricingComparison.displayName = 'PricingComparison';
726
1106
 
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
1107
  const DEFAULT_LICENSE_MESSAGE_TYPES = {
743
1108
  initialize: 'initialize',
744
1109
  verifyLicense: 'verify-license',
@@ -811,6 +1176,12 @@ function parseLicenseMessage(data) {
811
1176
  usageReason: readString(data, ['usageReason']) || undefined,
812
1177
  lastMessage: readString(data, ['message']) || undefined,
813
1178
  lastErrorCode: readString(data, ['errorCode']) || undefined,
1179
+ licenseStatus: readString(data, ['licenseStatus', 'license_status']) || undefined,
1180
+ licenseSource: readString(data, ['licenseSource', 'license_source', 'source']) || undefined,
1181
+ accessScope: readString(data, ['accessScope', 'access_scope', 'scope']) || undefined,
1182
+ expiresAt: readString(data, ['expiresAt', 'expires_at']) || undefined,
1183
+ lastVerifiedAt: readString(data, ['lastVerifiedAt', 'last_verified_at']) || undefined,
1184
+ validationMessage: readString(data, ['validationMessage', 'validation_message']) || undefined,
814
1185
  };
815
1186
  }
816
1187
  function useFigmaLicenseBridge(options = {}) {
@@ -853,15 +1224,27 @@ function useFigmaLicenseBridge(options = {}) {
853
1224
  if (type === messageTypes.verifyResult) {
854
1225
  setIsVerifying(false);
855
1226
  setIsStartingAuth(false);
856
- applyPatch(parseLicenseMessage(payload));
1227
+ applyPatch({
1228
+ ...parseLicenseMessage(payload),
1229
+ deactivateMessage: '',
1230
+ deactivateErrorCode: '',
1231
+ });
857
1232
  if (payload.success === true) {
858
1233
  applyPatch({ paymentStatus: 'PAID', isLicenseRegistered: true });
859
1234
  }
860
1235
  }
861
1236
  if (type === messageTypes.deactivateResult) {
862
1237
  setIsDeactivating(false);
863
- applyPatch(parseLicenseMessage(payload));
864
- if (payload.success === true) {
1238
+ const parsed = parseLicenseMessage(payload);
1239
+ const isSuccess = payload.success === true;
1240
+ applyPatch({
1241
+ ...parsed,
1242
+ deactivateMessage: parsed.lastMessage,
1243
+ deactivateErrorCode: isSuccess ? undefined : parsed.lastErrorCode,
1244
+ lastMessage: isSuccess ? undefined : parsed.lastMessage,
1245
+ lastErrorCode: isSuccess ? undefined : parsed.lastErrorCode,
1246
+ });
1247
+ if (isSuccess) {
865
1248
  applyPatch({
866
1249
  paymentStatus: 'UNPAID',
867
1250
  licenseKey: '',
@@ -869,6 +1252,8 @@ function useFigmaLicenseBridge(options = {}) {
869
1252
  isLicenseRegistered: false,
870
1253
  activationLimit: 0,
871
1254
  activationUsage: 0,
1255
+ deactivateMessage: parsed.lastMessage || '라이선스가 비활성화되었습니다.',
1256
+ deactivateErrorCode: undefined,
872
1257
  });
873
1258
  }
874
1259
  }
@@ -895,8 +1280,12 @@ function useFigmaLicenseBridge(options = {}) {
895
1280
  }, [messageTypes.verifyLicense]);
896
1281
  const deactivateLicense = React.useCallback(() => {
897
1282
  setIsDeactivating(true);
1283
+ applyPatch({
1284
+ deactivateMessage: '',
1285
+ deactivateErrorCode: '',
1286
+ });
898
1287
  postPluginMessage({ type: messageTypes.deactivateLicense });
899
- }, [messageTypes.deactivateLicense]);
1288
+ }, [applyPatch, messageTypes.deactivateLicense]);
900
1289
  const startDesignbaseAuth = React.useCallback(() => {
901
1290
  setIsStartingAuth(true);
902
1291
  postPluginMessage({ type: START_DESIGNBASE_AUTH_MESSAGE });
@@ -916,28 +1305,29 @@ function useFigmaLicenseBridge(options = {}) {
916
1305
  function formatUsageLabel(state, t) {
917
1306
  const { remainingUsage, usageUsed, usageLimit, usageReset } = state;
918
1307
  if (usageLimit === 'unlimited') {
919
- return resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음');
1308
+ return resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음') ?? '사용 횟수 제한 없음';
920
1309
  }
921
1310
  const limit = typeof usageLimit === 'number' ? usageLimit : remainingUsage + usageUsed;
922
1311
  const remaining = remainingUsage ?? Math.max(0, limit - usageUsed);
923
1312
  if (usageReset === 'daily') {
924
1313
  const fallback = `오늘 남은 횟수 ${remaining}/${limit}`;
925
- const translated = resolveText(t, { key: 'license.usage_daily' }, fallback);
1314
+ const translated = resolveText(t, { key: 'license.usage_daily' }, fallback) ?? fallback;
926
1315
  return translated.includes(String(remaining)) ? translated : fallback;
927
1316
  }
928
1317
  if (usageReset === 'monthly') {
929
1318
  const fallback = `이번 달 남은 횟수 ${remaining}/${limit}`;
930
- const translated = resolveText(t, { key: 'license.usage_monthly' }, fallback);
1319
+ const translated = resolveText(t, { key: 'license.usage_monthly' }, fallback) ?? fallback;
931
1320
  return translated.includes(String(remaining)) ? translated : fallback;
932
1321
  }
933
1322
  return `남은 횟수 ${remaining}/${limit}`;
934
1323
  }
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, }) => {
1324
+ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', wordpressLinks, paymentPageUrl, mode = 'pricing', membershipUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, className, }) => {
936
1325
  const links = React.useMemo(() => ({
937
1326
  purchaseUrl: wordpressLinks?.purchaseUrl ?? paymentPageUrl,
1327
+ membershipUrl: membershipUrl ?? wordpressLinks?.membershipUrl,
938
1328
  accountUrl: wordpressLinks?.accountUrl,
939
1329
  helpUrl: wordpressLinks?.helpUrl,
940
- }), [wordpressLinks, paymentPageUrl]);
1330
+ }), [wordpressLinks, paymentPageUrl, membershipUrl]);
941
1331
  const { state, isVerifying, isDeactivating, isStartingAuth, verifyLicense, deactivateLicense, startDesignbaseAuth, setLicenseKeyInput, } = useFigmaLicenseBridge({
942
1332
  messageTypes,
943
1333
  initialState: {
@@ -951,7 +1341,8 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
951
1341
  });
952
1342
  const [showDetails, setShowDetails] = React.useState(false);
953
1343
  const [licenseKeyDraft, setLicenseKeyDraft] = React.useState(initialLicenseKey);
954
- const isPaid = state.isLicenseRegistered || state.paymentStatus === 'PAID';
1344
+ const isPaid = state.isLicenseRegistered && state.paymentStatus === 'PAID';
1345
+ const isMembershipMode = mode === 'youtube-membership';
955
1346
  const usageLabel = formatUsageLabel(state, t);
956
1347
  const handleLicenseSubmit = async (submittedLicenseKey) => {
957
1348
  if (onLicenseSubmit) {
@@ -964,29 +1355,30 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
964
1355
  setLicenseKeyDraft(value);
965
1356
  setLicenseKeyInput(value);
966
1357
  };
967
- return (React.createElement("div", { className: `designbase-figma-page-license ${className || ''}` },
1358
+ return (React.createElement("div", { className: `designbase-figma-page-license designbase-figma-page-license--${mode} ${className || ''}`, "data-license-mode": mode },
968
1359
  React.createElement("div", { className: "designbase-figma-page-license__content" },
969
1360
  React.createElement("div", { className: "designbase-figma-page-license__header" },
970
1361
  React.createElement("div", { className: "designbase-figma-page-license__title" },
971
- React.createElement("h2", null, isPaid
972
- ? resolveText(t, { key: 'license.pro_account' }, '프로 계정')
973
- : resolveText(t, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드')),
1362
+ React.createElement("h2", null, isMembershipMode
1363
+ ? resolveText(t, { key: 'license.youtube_membership' }, 'YouTube 멤버십')
1364
+ : isPaid
1365
+ ? resolveText(t, { key: 'license.pro_account' }, '프로 계정')
1366
+ : resolveText(t, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드')),
974
1367
  state.planTier && state.planTier !== 'FREE' && (React.createElement("span", { className: "designbase-figma-page-license__tier" }, state.planTier))),
975
1368
  React.createElement("p", { className: "designbase-figma-page-license__description" }, isPaid
976
1369
  ? resolveText(t, { key: 'license.all_features_available' }, '모든 기능을 사용할 수 있습니다.')
977
- : resolveText(t, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
978
- !isPaid && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
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)),
1370
+ : isMembershipMode
1371
+ ? resolveText(t, { key: 'license.youtube_membership_description' }, 'YouTube 멤버십에 가입하면 Designbase 플러그인을 무제한으로 사용할 수 있습니다.')
1372
+ : resolveText(t, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
1373
+ !isPaid && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
1374
+ !isMembershipMode && (React.createElement(PricingComparison, { features: pricingFeatures, pricing: pricing, paymentType: paymentType, t: t })),
1375
+ state.lastMessage && !state.deactivateMessage && (React.createElement("p", { className: `designbase-figma-page-license__feedback ${state.lastErrorCode ? 'designbase-figma-page-license__feedback--error' : ''}`, "aria-live": "polite" }, state.lastMessage)),
981
1376
  isPaid && (React.createElement("div", { className: "designbase-figma-page-license__section" },
982
1377
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
983
1378
  React.createElement("h3", null, resolveText(t, { key: 'license.activated' }, '라이선스 활성화됨')),
984
- React.createElement(react.Button, { onClick: () => setShowDetails(!showDetails), variant: "tertiary", size: "s", iconOnly: true },
1379
+ React.createElement(react.Button, { onPress: () => setShowDetails(!showDetails), variant: "tertiary", size: "s", iconOnly: true },
985
1380
  React.createElement(icons.MoreHorizontalIcon, { size: 16 }))),
986
- state.licenseKey && (React.createElement("div", { className: "designbase-figma-page-license__license-key" },
987
- resolveText(t, { key: 'license.key_label' }, '라이선스 키'),
988
- ": ",
989
- React.createElement("span", null, state.licenseKey))),
1381
+ React.createElement(LicenseStatusCard, { status: state.paymentStatus, licenseKey: state.licenseKey, licenseStatus: state.licenseStatus, licenseSource: state.licenseSource, accessScope: state.accessScope, expiresAt: state.expiresAt, lastVerifiedAt: state.lastVerifiedAt, validationMessage: state.validationMessage, allowRevealKey: false, t: t }),
990
1382
  React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel),
991
1383
  showDetails && (React.createElement("div", { className: "designbase-figma-page-license__details" },
992
1384
  React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
@@ -1000,59 +1392,54 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
1000
1392
  state.activationUsage,
1001
1393
  "/",
1002
1394
  state.activationLimit)),
1003
- React.createElement(react.Button, { onClick: deactivateLicense, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
1004
- ? resolveText(t, { key: 'license.deactivating' }, '비활성화 중...')
1005
- : resolveText(t, { key: 'license.deactivate' }, '라이선스 비활성화')))))),
1395
+ React.createElement("div", { className: "designbase-figma-page-license__action" },
1396
+ React.createElement(react.Button, { onPress: deactivateLicense, variant: "secondary", size: "s", fullWidth: true, disabled: isDeactivating }, isDeactivating
1397
+ ? resolveText(t, { key: 'license.deactivating' }, '비활성화 중...')
1398
+ : resolveText(t, { key: 'license.deactivate' }, '라이선스 비활성화')),
1399
+ state.deactivateMessage && (React.createElement("p", { className: `designbase-figma-page-license__action-feedback designbase-figma-page-license__action-feedback--${resolvePaymentFeedbackVariant(state.deactivateErrorCode)}`, role: state.deactivateErrorCode ? 'alert' : 'status', "aria-live": "polite" }, state.deactivateMessage))))))),
1006
1400
  !isPaid && (React.createElement(React.Fragment, null,
1007
- (enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
1401
+ isMembershipMode && (React.createElement(LicenseOffer, { joinUrl: links.membershipUrl || links.purchaseUrl, guideUrl: links.helpUrl || links.purchaseUrl, t: t })),
1402
+ !isMembershipMode && (enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
1008
1403
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
1009
1404
  React.createElement("h3", null, resolveText(t, { key: 'license.designbase_account' }, '디자인베이스 계정'))),
1010
1405
  React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(t, { key: 'license.designbase_account_hint' }, 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.')),
1011
1406
  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
1407
+ enableAccountAuth && (React.createElement(react.Button, { onPress: startDesignbaseAuth, variant: "primary", size: "m", disabled: isStartingAuth || isVerifying, fullWidth: true }, isStartingAuth
1013
1408
  ? resolveText(t, { key: 'license.authenticating' }, '인증 중...')
1014
1409
  : 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' }, '멤버십 구매')),
1410
+ links.purchaseUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(links.purchaseUrl), variant: "secondary", size: "m", fullWidth: true },
1411
+ React.createElement("span", null, resolveText(t, { key: 'license.purchase_membership' }, '멤버십 안내')),
1017
1412
  React.createElement(icons.ExternalLinkIcon, { size: 16 }))),
1018
- links.accountUrl && (React.createElement(react.Button, { onClick: () => openExternalUrl(links.accountUrl), variant: "tertiary", size: "s", fullWidth: true },
1413
+ links.accountUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(links.accountUrl), variant: "tertiary", size: "s", fullWidth: true },
1019
1414
  React.createElement("span", null, resolveText(t, { key: 'license.manage_account' }, '계정·멤버십 관리')),
1020
1415
  React.createElement(icons.ExternalLinkIcon, { size: 16 })))))),
1021
- showLicenseKeyInput && (React.createElement("div", { className: "designbase-figma-page-license__section" },
1416
+ showLicenseKeyInput && (React.createElement("div", { className: isMembershipMode
1417
+ ? 'designbase-figma-page-license__key-form'
1418
+ : 'designbase-figma-page-license__section' },
1022
1419
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
1023
1420
  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" },
1421
+ 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: isMembershipMode ? 'license.enter_from_youtube' : 'license.enter_from_email' }, t: t }))))),
1422
+ links.helpUrl && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__disclaimer" },
1026
1423
  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" },
1028
- React.createElement(icons.CloseIcon, { size: 20 }))));
1424
+ React.createElement(react.Button, { className: "designbase-figma-page-license__close", onPress: onClose, variant: "tertiary", size: "s", iconOnly: true, "aria-label": "Close" },
1425
+ React.createElement(icons.CloseIcon, { size: 16 }))));
1029
1426
  };
1030
1427
  PageLicense.displayName = 'PageLicense';
1031
1428
 
1032
- const PaymentStatusSection = ({ status, usageCount, activationLimit, activationUsage, licenseKey, onDeactivate, isDeactivating = false, showDetails = false, className, t }) => {
1033
- const remainingActivations = activationLimit - activationUsage;
1034
- return (React.createElement("div", { className: `designbase-figma-payment-status ${className || ''}` },
1035
- React.createElement("div", { className: "designbase-figma-payment-status__license-key" },
1036
- resolveText(t, { key: 'payment.license_key_label' }, '라이선스 키'),
1037
- ": ",
1038
- React.createElement("span", null, licenseKey)),
1039
- showDetails && (React.createElement("div", { className: "designbase-figma-payment-status__details" },
1040
- React.createElement("div", { className: "designbase-figma-payment-status__activation-info" },
1041
- React.createElement("div", { className: "designbase-figma-payment-status__remaining" },
1042
- remainingActivations,
1043
- " ",
1044
- resolveText(t, { key: 'payment.activations_remaining' }, '활성'),
1045
- " ",
1046
- resolveText(t, { key: 'payment.spots_remaining' }, '자리 남음')),
1047
- React.createElement("div", { className: "designbase-figma-payment-status__usage" },
1048
- activationUsage,
1049
- "/",
1050
- activationLimit)),
1051
- React.createElement(react.Button, { onClick: onDeactivate, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
1052
- ? resolveText(t, { key: 'payment.deactivating' }, '비활성화중...')
1053
- : resolveText(t, { key: 'payment.deactivate_license' }, '라이선스 비활성화'))))));
1429
+ const PaymentBadge = ({ isActive, onClick, isLoading = false, text, t = (key) => key, className, }) => {
1430
+ const getBadgeText = () => {
1431
+ if (text)
1432
+ return text;
1433
+ return isActive
1434
+ ? (t('proUser') || '프로 계정')
1435
+ : (t('usingFree') || '무료 사용');
1436
+ };
1437
+ const getBadgeVariant = () => {
1438
+ return isActive ? 'success' : 'secondary';
1439
+ };
1440
+ 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()))));
1054
1441
  };
1055
- PaymentStatusSection.displayName = 'PaymentStatusSection';
1442
+ PaymentBadge.displayName = 'PaymentBadge';
1056
1443
 
1057
1444
  const ProgressModal = ({ isOpen, onClose, progress, title = { key: 'progress.working' }, completedMessage = { key: 'progress.completed' }, processingMessage = { key: 'progress.processing' }, stopButtonText = { key: 'progress.stop' }, confirmButtonText = { key: 'progress.confirm' }, helpText, onStop, onComplete, loadingIcon, completeIcon, className, t, autoComplete = true, autoCloseOnComplete = false }) => {
1058
1445
  const [isCompleted, setIsCompleted] = React.useState(false);
@@ -1096,7 +1483,7 @@ const ProgressModal = ({ isOpen, onClose, progress, title = { key: 'progress.wor
1096
1483
  React.createElement(react.Spinner, { size: "m" }))))),
1097
1484
  React.createElement("p", { className: "designbase-figma-progress-modal__message" }, displayMessage),
1098
1485
  React.createElement("div", { className: "designbase-figma-progress-modal__status" }, `${processedNodes} / ${totalNodes} (${progressPercentage.toFixed(1)}%)`),
1099
- React.createElement(react.Progressbar, { value: progressPercentage, size: "m", variant: isCompleted ? 'success' : 'primary', style: "animated", fullWidth: true }),
1486
+ React.createElement(react.Progressbar, { value: progressPercentage, size: "m", variant: isCompleted ? 'success' : 'primary', barStyle: "animated", fullWidth: true }),
1100
1487
  displayHelpText && !isCompleted && (React.createElement("p", { className: "designbase-figma-progress-modal__help-text" }, displayHelpText)),
1101
1488
  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))))));
1102
1489
  };
@@ -1303,6 +1690,538 @@ const UpgradeBanner = ({ onClick, variant = 'button', isLoading = false, title =
1303
1690
  };
1304
1691
  UpgradeBanner.displayName = 'UpgradeBanner';
1305
1692
 
1693
+ Object.defineProperty(exports, 'Accordion', {
1694
+ enumerable: true,
1695
+ get: function () { return react.Accordion; }
1696
+ });
1697
+ Object.defineProperty(exports, 'ActivityHeatmap', {
1698
+ enumerable: true,
1699
+ get: function () { return react.ActivityHeatmap; }
1700
+ });
1701
+ Object.defineProperty(exports, 'AdBanner', {
1702
+ enumerable: true,
1703
+ get: function () { return react.AdBanner; }
1704
+ });
1705
+ Object.defineProperty(exports, 'AiChat', {
1706
+ enumerable: true,
1707
+ get: function () { return react.AiChat; }
1708
+ });
1709
+ Object.defineProperty(exports, 'AiChatList', {
1710
+ enumerable: true,
1711
+ get: function () { return react.AiChatList; }
1712
+ });
1713
+ Object.defineProperty(exports, 'Alert', {
1714
+ enumerable: true,
1715
+ get: function () { return react.Alert; }
1716
+ });
1717
+ Object.defineProperty(exports, 'AnimationBackground', {
1718
+ enumerable: true,
1719
+ get: function () { return react.AnimationBackground; }
1720
+ });
1721
+ Object.defineProperty(exports, 'AnimationText', {
1722
+ enumerable: true,
1723
+ get: function () { return react.AnimationText; }
1724
+ });
1725
+ Object.defineProperty(exports, 'AppBadge', {
1726
+ enumerable: true,
1727
+ get: function () { return react.AppBadge; }
1728
+ });
1729
+ Object.defineProperty(exports, 'AudioPlayer', {
1730
+ enumerable: true,
1731
+ get: function () { return react.AudioPlayer; }
1732
+ });
1733
+ Object.defineProperty(exports, 'Avatar', {
1734
+ enumerable: true,
1735
+ get: function () { return react.Avatar; }
1736
+ });
1737
+ Object.defineProperty(exports, 'Backdrop', {
1738
+ enumerable: true,
1739
+ get: function () { return react.Backdrop; }
1740
+ });
1741
+ Object.defineProperty(exports, 'Badge', {
1742
+ enumerable: true,
1743
+ get: function () { return react.Badge; }
1744
+ });
1745
+ Object.defineProperty(exports, 'Banner', {
1746
+ enumerable: true,
1747
+ get: function () { return react.Banner; }
1748
+ });
1749
+ Object.defineProperty(exports, 'BottomNavigation', {
1750
+ enumerable: true,
1751
+ get: function () { return react.BottomNavigation; }
1752
+ });
1753
+ Object.defineProperty(exports, 'BottomSheet', {
1754
+ enumerable: true,
1755
+ get: function () { return react.BottomSheet; }
1756
+ });
1757
+ Object.defineProperty(exports, 'Breadcrumbs', {
1758
+ enumerable: true,
1759
+ get: function () { return react.Breadcrumbs; }
1760
+ });
1761
+ Object.defineProperty(exports, 'Button', {
1762
+ enumerable: true,
1763
+ get: function () { return react.Button; }
1764
+ });
1765
+ Object.defineProperty(exports, 'Calendar', {
1766
+ enumerable: true,
1767
+ get: function () { return react.Calendar; }
1768
+ });
1769
+ Object.defineProperty(exports, 'Card', {
1770
+ enumerable: true,
1771
+ get: function () { return react.Card; }
1772
+ });
1773
+ Object.defineProperty(exports, 'Carousel', {
1774
+ enumerable: true,
1775
+ get: function () { return react.Carousel; }
1776
+ });
1777
+ Object.defineProperty(exports, 'ChatComposer', {
1778
+ enumerable: true,
1779
+ get: function () { return react.ChatComposer; }
1780
+ });
1781
+ Object.defineProperty(exports, 'ChatList', {
1782
+ enumerable: true,
1783
+ get: function () { return react.ChatList; }
1784
+ });
1785
+ Object.defineProperty(exports, 'ChatMessage', {
1786
+ enumerable: true,
1787
+ get: function () { return react.ChatMessage; }
1788
+ });
1789
+ Object.defineProperty(exports, 'ChatOrb', {
1790
+ enumerable: true,
1791
+ get: function () { return react.ChatOrb; }
1792
+ });
1793
+ Object.defineProperty(exports, 'ChatRoom', {
1794
+ enumerable: true,
1795
+ get: function () { return react.ChatRoom; }
1796
+ });
1797
+ Object.defineProperty(exports, 'ChatSuggestions', {
1798
+ enumerable: true,
1799
+ get: function () { return react.ChatSuggestions; }
1800
+ });
1801
+ Object.defineProperty(exports, 'ChatTyping', {
1802
+ enumerable: true,
1803
+ get: function () { return react.ChatTyping; }
1804
+ });
1805
+ Object.defineProperty(exports, 'ChatWelcome', {
1806
+ enumerable: true,
1807
+ get: function () { return react.ChatWelcome; }
1808
+ });
1809
+ Object.defineProperty(exports, 'ChatWidget', {
1810
+ enumerable: true,
1811
+ get: function () { return react.ChatWidget; }
1812
+ });
1813
+ Object.defineProperty(exports, 'Checkbox', {
1814
+ enumerable: true,
1815
+ get: function () { return react.Checkbox; }
1816
+ });
1817
+ Object.defineProperty(exports, 'Chip', {
1818
+ enumerable: true,
1819
+ get: function () { return react.Chip; }
1820
+ });
1821
+ Object.defineProperty(exports, 'CodeBlock', {
1822
+ enumerable: true,
1823
+ get: function () { return react.CodeBlock; }
1824
+ });
1825
+ Object.defineProperty(exports, 'ColorPicker', {
1826
+ enumerable: true,
1827
+ get: function () { return react.ColorPicker; }
1828
+ });
1829
+ Object.defineProperty(exports, 'ColorSwatch', {
1830
+ enumerable: true,
1831
+ get: function () { return react.ColorSwatch; }
1832
+ });
1833
+ Object.defineProperty(exports, 'Confirm', {
1834
+ enumerable: true,
1835
+ get: function () { return react.Confirm; }
1836
+ });
1837
+ Object.defineProperty(exports, 'Container', {
1838
+ enumerable: true,
1839
+ get: function () { return react.Container; }
1840
+ });
1841
+ Object.defineProperty(exports, 'ContextMenu', {
1842
+ enumerable: true,
1843
+ get: function () { return react.ContextMenu; }
1844
+ });
1845
+ Object.defineProperty(exports, 'CookieBanner', {
1846
+ enumerable: true,
1847
+ get: function () { return react.CookieBanner; }
1848
+ });
1849
+ Object.defineProperty(exports, 'Countdown', {
1850
+ enumerable: true,
1851
+ get: function () { return react.Countdown; }
1852
+ });
1853
+ Object.defineProperty(exports, 'CursorFollower', {
1854
+ enumerable: true,
1855
+ get: function () { return react.CursorFollower; }
1856
+ });
1857
+ Object.defineProperty(exports, 'DatePicker', {
1858
+ enumerable: true,
1859
+ get: function () { return react.DatePicker; }
1860
+ });
1861
+ Object.defineProperty(exports, 'Divider', {
1862
+ enumerable: true,
1863
+ get: function () { return react.Divider; }
1864
+ });
1865
+ Object.defineProperty(exports, 'DownloadProgress', {
1866
+ enumerable: true,
1867
+ get: function () { return react.DownloadProgress; }
1868
+ });
1869
+ Object.defineProperty(exports, 'Drawer', {
1870
+ enumerable: true,
1871
+ get: function () { return react.Drawer; }
1872
+ });
1873
+ Object.defineProperty(exports, 'Dropdown', {
1874
+ enumerable: true,
1875
+ get: function () { return react.Dropdown; }
1876
+ });
1877
+ Object.defineProperty(exports, 'Dropzone', {
1878
+ enumerable: true,
1879
+ get: function () { return react.Dropzone; }
1880
+ });
1881
+ Object.defineProperty(exports, 'EmailVerify', {
1882
+ enumerable: true,
1883
+ get: function () { return react.EmailVerify; }
1884
+ });
1885
+ Object.defineProperty(exports, 'EmptyState', {
1886
+ enumerable: true,
1887
+ get: function () { return react.EmptyState; }
1888
+ });
1889
+ Object.defineProperty(exports, 'FileUploader', {
1890
+ enumerable: true,
1891
+ get: function () { return react.FileUploader; }
1892
+ });
1893
+ Object.defineProperty(exports, 'FloatingActionButton', {
1894
+ enumerable: true,
1895
+ get: function () { return react.FloatingActionButton; }
1896
+ });
1897
+ Object.defineProperty(exports, 'Footer', {
1898
+ enumerable: true,
1899
+ get: function () { return react.Footer; }
1900
+ });
1901
+ Object.defineProperty(exports, 'Form', {
1902
+ enumerable: true,
1903
+ get: function () { return react.Form; }
1904
+ });
1905
+ Object.defineProperty(exports, 'Gantt', {
1906
+ enumerable: true,
1907
+ get: function () { return react.Gantt; }
1908
+ });
1909
+ Object.defineProperty(exports, 'Gradient', {
1910
+ enumerable: true,
1911
+ get: function () { return react.Gradient; }
1912
+ });
1913
+ Object.defineProperty(exports, 'Grid', {
1914
+ enumerable: true,
1915
+ get: function () { return react.Grid; }
1916
+ });
1917
+ Object.defineProperty(exports, 'GridBackground', {
1918
+ enumerable: true,
1919
+ get: function () { return react.GridBackground; }
1920
+ });
1921
+ Object.defineProperty(exports, 'GridItem', {
1922
+ enumerable: true,
1923
+ get: function () { return react.GridItem; }
1924
+ });
1925
+ Object.defineProperty(exports, 'Image', {
1926
+ enumerable: true,
1927
+ get: function () { return react.Image; }
1928
+ });
1929
+ Object.defineProperty(exports, 'ImageList', {
1930
+ enumerable: true,
1931
+ get: function () { return react.ImageList; }
1932
+ });
1933
+ Object.defineProperty(exports, 'ImagePlaceholder', {
1934
+ enumerable: true,
1935
+ get: function () { return react.ImagePlaceholder; }
1936
+ });
1937
+ Object.defineProperty(exports, 'Indicator', {
1938
+ enumerable: true,
1939
+ get: function () { return react.Indicator; }
1940
+ });
1941
+ Object.defineProperty(exports, 'Input', {
1942
+ enumerable: true,
1943
+ get: function () { return react.Input; }
1944
+ });
1945
+ Object.defineProperty(exports, 'Kanban', {
1946
+ enumerable: true,
1947
+ get: function () { return react.Kanban; }
1948
+ });
1949
+ Object.defineProperty(exports, 'Label', {
1950
+ enumerable: true,
1951
+ get: function () { return react.Label; }
1952
+ });
1953
+ Object.defineProperty(exports, 'Lightbox', {
1954
+ enumerable: true,
1955
+ get: function () { return react.Lightbox; }
1956
+ });
1957
+ Object.defineProperty(exports, 'List', {
1958
+ enumerable: true,
1959
+ get: function () { return react.List; }
1960
+ });
1961
+ Object.defineProperty(exports, 'Logo', {
1962
+ enumerable: true,
1963
+ get: function () { return react.Logo; }
1964
+ });
1965
+ Object.defineProperty(exports, 'MarkdownEditor', {
1966
+ enumerable: true,
1967
+ get: function () { return react.MarkdownEditor; }
1968
+ });
1969
+ Object.defineProperty(exports, 'Marquee', {
1970
+ enumerable: true,
1971
+ get: function () { return react.Marquee; }
1972
+ });
1973
+ Object.defineProperty(exports, 'Masonry', {
1974
+ enumerable: true,
1975
+ get: function () { return react.Masonry; }
1976
+ });
1977
+ Object.defineProperty(exports, 'MenuItem', {
1978
+ enumerable: true,
1979
+ get: function () { return react.MenuItem; }
1980
+ });
1981
+ Object.defineProperty(exports, 'Modal', {
1982
+ enumerable: true,
1983
+ get: function () { return react.Modal; }
1984
+ });
1985
+ Object.defineProperty(exports, 'ModalBody', {
1986
+ enumerable: true,
1987
+ get: function () { return react.ModalBody; }
1988
+ });
1989
+ Object.defineProperty(exports, 'ModalFooter', {
1990
+ enumerable: true,
1991
+ get: function () { return react.ModalFooter; }
1992
+ });
1993
+ Object.defineProperty(exports, 'ModalHeader', {
1994
+ enumerable: true,
1995
+ get: function () { return react.ModalHeader; }
1996
+ });
1997
+ Object.defineProperty(exports, 'Navbar', {
1998
+ enumerable: true,
1999
+ get: function () { return react.Navbar; }
2000
+ });
2001
+ Object.defineProperty(exports, 'OnboardingModal', {
2002
+ enumerable: true,
2003
+ get: function () { return react.OnboardingModal; }
2004
+ });
2005
+ Object.defineProperty(exports, 'OtpInput', {
2006
+ enumerable: true,
2007
+ get: function () { return react.OtpInput; }
2008
+ });
2009
+ Object.defineProperty(exports, 'PageHeader', {
2010
+ enumerable: true,
2011
+ get: function () { return react.PageHeader; }
2012
+ });
2013
+ Object.defineProperty(exports, 'Pagination', {
2014
+ enumerable: true,
2015
+ get: function () { return react.Pagination; }
2016
+ });
2017
+ Object.defineProperty(exports, 'PhoneVerify', {
2018
+ enumerable: true,
2019
+ get: function () { return react.PhoneVerify; }
2020
+ });
2021
+ Object.defineProperty(exports, 'Popover', {
2022
+ enumerable: true,
2023
+ get: function () { return react.Popover; }
2024
+ });
2025
+ Object.defineProperty(exports, 'Progress', {
2026
+ enumerable: true,
2027
+ get: function () { return react.Progress; }
2028
+ });
2029
+ Object.defineProperty(exports, 'ProgressStep', {
2030
+ enumerable: true,
2031
+ get: function () { return react.ProgressStep; }
2032
+ });
2033
+ Object.defineProperty(exports, 'Progressbar', {
2034
+ enumerable: true,
2035
+ get: function () { return react.Progressbar; }
2036
+ });
2037
+ Object.defineProperty(exports, 'Radio', {
2038
+ enumerable: true,
2039
+ get: function () { return react.Radio; }
2040
+ });
2041
+ Object.defineProperty(exports, 'RandomGradient', {
2042
+ enumerable: true,
2043
+ get: function () { return react.RandomGradient; }
2044
+ });
2045
+ Object.defineProperty(exports, 'RangeSlider', {
2046
+ enumerable: true,
2047
+ get: function () { return react.RangeSlider; }
2048
+ });
2049
+ Object.defineProperty(exports, 'Rating', {
2050
+ enumerable: true,
2051
+ get: function () { return react.Rating; }
2052
+ });
2053
+ Object.defineProperty(exports, 'Reorder', {
2054
+ enumerable: true,
2055
+ get: function () { return react.Reorder; }
2056
+ });
2057
+ Object.defineProperty(exports, 'ResizablePanels', {
2058
+ enumerable: true,
2059
+ get: function () { return react.ResizablePanels; }
2060
+ });
2061
+ Object.defineProperty(exports, 'ScrollArea', {
2062
+ enumerable: true,
2063
+ get: function () { return react.ScrollArea; }
2064
+ });
2065
+ Object.defineProperty(exports, 'SearchBar', {
2066
+ enumerable: true,
2067
+ get: function () { return react.SearchBar; }
2068
+ });
2069
+ Object.defineProperty(exports, 'Section', {
2070
+ enumerable: true,
2071
+ get: function () { return react.Section; }
2072
+ });
2073
+ Object.defineProperty(exports, 'SectionAppDownload', {
2074
+ enumerable: true,
2075
+ get: function () { return react.SectionAppDownload; }
2076
+ });
2077
+ Object.defineProperty(exports, 'SectionContact', {
2078
+ enumerable: true,
2079
+ get: function () { return react.SectionContact; }
2080
+ });
2081
+ Object.defineProperty(exports, 'SectionCta', {
2082
+ enumerable: true,
2083
+ get: function () { return react.SectionCta; }
2084
+ });
2085
+ Object.defineProperty(exports, 'SectionFaq', {
2086
+ enumerable: true,
2087
+ get: function () { return react.SectionFaq; }
2088
+ });
2089
+ Object.defineProperty(exports, 'SectionFeature', {
2090
+ enumerable: true,
2091
+ get: function () { return react.SectionFeature; }
2092
+ });
2093
+ Object.defineProperty(exports, 'SectionFeatureGrid', {
2094
+ enumerable: true,
2095
+ get: function () { return react.SectionFeatureGrid; }
2096
+ });
2097
+ Object.defineProperty(exports, 'SectionHero', {
2098
+ enumerable: true,
2099
+ get: function () { return react.SectionHero; }
2100
+ });
2101
+ Object.defineProperty(exports, 'SectionLogoCloud', {
2102
+ enumerable: true,
2103
+ get: function () { return react.SectionLogoCloud; }
2104
+ });
2105
+ Object.defineProperty(exports, 'SectionPricing', {
2106
+ enumerable: true,
2107
+ get: function () { return react.SectionPricing; }
2108
+ });
2109
+ Object.defineProperty(exports, 'SectionStats', {
2110
+ enumerable: true,
2111
+ get: function () { return react.SectionStats; }
2112
+ });
2113
+ Object.defineProperty(exports, 'SectionTestimonials', {
2114
+ enumerable: true,
2115
+ get: function () { return react.SectionTestimonials; }
2116
+ });
2117
+ Object.defineProperty(exports, 'SegmentControl', {
2118
+ enumerable: true,
2119
+ get: function () { return react.SegmentControl; }
2120
+ });
2121
+ Object.defineProperty(exports, 'Select', {
2122
+ enumerable: true,
2123
+ get: function () { return react.Select; }
2124
+ });
2125
+ Object.defineProperty(exports, 'Share', {
2126
+ enumerable: true,
2127
+ get: function () { return react.Share; }
2128
+ });
2129
+ Object.defineProperty(exports, 'Sidebar', {
2130
+ enumerable: true,
2131
+ get: function () { return react.Sidebar; }
2132
+ });
2133
+ Object.defineProperty(exports, 'Signature', {
2134
+ enumerable: true,
2135
+ get: function () { return react.Signature; }
2136
+ });
2137
+ Object.defineProperty(exports, 'Skeleton', {
2138
+ enumerable: true,
2139
+ get: function () { return react.Skeleton; }
2140
+ });
2141
+ Object.defineProperty(exports, 'Spinner', {
2142
+ enumerable: true,
2143
+ get: function () { return react.Spinner; }
2144
+ });
2145
+ Object.defineProperty(exports, 'SplitView', {
2146
+ enumerable: true,
2147
+ get: function () { return react.SplitView; }
2148
+ });
2149
+ Object.defineProperty(exports, 'Stack', {
2150
+ enumerable: true,
2151
+ get: function () { return react.Stack; }
2152
+ });
2153
+ Object.defineProperty(exports, 'Stat', {
2154
+ enumerable: true,
2155
+ get: function () { return react.Stat; }
2156
+ });
2157
+ Object.defineProperty(exports, 'Stepper', {
2158
+ enumerable: true,
2159
+ get: function () { return react.Stepper; }
2160
+ });
2161
+ Object.defineProperty(exports, 'Table', {
2162
+ enumerable: true,
2163
+ get: function () { return react.Table; }
2164
+ });
2165
+ Object.defineProperty(exports, 'Tabs', {
2166
+ enumerable: true,
2167
+ get: function () { return react.Tabs; }
2168
+ });
2169
+ Object.defineProperty(exports, 'Testimonial', {
2170
+ enumerable: true,
2171
+ get: function () { return react.Testimonial; }
2172
+ });
2173
+ Object.defineProperty(exports, 'Textarea', {
2174
+ enumerable: true,
2175
+ get: function () { return react.Textarea; }
2176
+ });
2177
+ Object.defineProperty(exports, 'TimePicker', {
2178
+ enumerable: true,
2179
+ get: function () { return react.TimePicker; }
2180
+ });
2181
+ Object.defineProperty(exports, 'Timeline', {
2182
+ enumerable: true,
2183
+ get: function () { return react.Timeline; }
2184
+ });
2185
+ Object.defineProperty(exports, 'Toast', {
2186
+ enumerable: true,
2187
+ get: function () { return react.Toast; }
2188
+ });
2189
+ Object.defineProperty(exports, 'Toggle', {
2190
+ enumerable: true,
2191
+ get: function () { return react.Toggle; }
2192
+ });
2193
+ Object.defineProperty(exports, 'Toolbar', {
2194
+ enumerable: true,
2195
+ get: function () { return react.Toolbar; }
2196
+ });
2197
+ Object.defineProperty(exports, 'Tooltip', {
2198
+ enumerable: true,
2199
+ get: function () { return react.Tooltip; }
2200
+ });
2201
+ Object.defineProperty(exports, 'TopBanner', {
2202
+ enumerable: true,
2203
+ get: function () { return react.TopBanner; }
2204
+ });
2205
+ Object.defineProperty(exports, 'Tutorial', {
2206
+ enumerable: true,
2207
+ get: function () { return react.Tutorial; }
2208
+ });
2209
+ Object.defineProperty(exports, 'TwoFactor', {
2210
+ enumerable: true,
2211
+ get: function () { return react.TwoFactor; }
2212
+ });
2213
+ Object.defineProperty(exports, 'VideoPlayer', {
2214
+ enumerable: true,
2215
+ get: function () { return react.VideoPlayer; }
2216
+ });
2217
+ Object.defineProperty(exports, 'YouTubePlayer', {
2218
+ enumerable: true,
2219
+ get: function () { return react.YouTubePlayer; }
2220
+ });
2221
+ Object.defineProperty(exports, 'useContextMenu', {
2222
+ enumerable: true,
2223
+ get: function () { return react.useContextMenu; }
2224
+ });
1306
2225
  exports.DEFAULT_LICENSE_MESSAGE_TYPES = DEFAULT_LICENSE_MESSAGE_TYPES;
1307
2226
  exports.DonationBadge = DonationBadge;
1308
2227
  exports.FigmaContainer = FigmaContainer;
@@ -1316,6 +2235,9 @@ exports.FigmaToastProvider = FigmaToastProvider;
1316
2235
  exports.FormWithSubmit = FormWithSubmit;
1317
2236
  exports.InteractionFeedback = InteractionFeedback;
1318
2237
  exports.LanguageSelector = LanguageSelector;
2238
+ exports.LanguageSettingsModal = LanguageSettingsModal;
2239
+ exports.LicenseOffer = LicenseOffer;
2240
+ exports.LicenseStatusCard = LicenseStatusCard;
1319
2241
  exports.LogoDropdown = LogoDropdown;
1320
2242
  exports.PageLicense = PageLicense;
1321
2243
  exports.PaymentBadge = PaymentBadge;
@@ -1327,7 +2249,10 @@ exports.START_DESIGNBASE_AUTH_MESSAGE = START_DESIGNBASE_AUTH_MESSAGE;
1327
2249
  exports.SettingsModal = SettingsModal;
1328
2250
  exports.TitleDescription = TitleDescription;
1329
2251
  exports.UpgradeBanner = UpgradeBanner;
2252
+ exports.UsageStatusPopover = UsageStatusPopover;
1330
2253
  exports.getActiveSection = getActiveSection;
2254
+ exports.interpolateText = interpolateText;
2255
+ exports.resolvePaymentFeedbackVariant = resolvePaymentFeedbackVariant;
1331
2256
  exports.resolveText = resolveText;
1332
2257
  exports.scrollToSection = scrollToSection;
1333
2258
  exports.useFigmaLicenseBridge = useFigmaLicenseBridge;