@designbasekorea/figma-ui 0.1.41 → 0.1.43

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,7 +6,16 @@ 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
 
9
- const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', text = 'Buy me a coffee', iconType = 'heart', size = 'm', className, onClick, }) => {
9
+ function resolveText(t, input, fallback) {
10
+ if (input == null)
11
+ return fallback;
12
+ if (typeof input === 'string') {
13
+ return input;
14
+ }
15
+ return t ? t(input.key, input.values) : input.key;
16
+ }
17
+
18
+ const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', text = { key: 'donation.buy_me_a_coffee' }, iconType = 'heart', size = 'm', className, onClick, t }) => {
10
19
  const handleClick = () => {
11
20
  if (onClick) {
12
21
  onClick();
@@ -16,10 +25,11 @@ const DonationBadge = ({ donationUrl = 'https://buymeacoffee.com/designbase', te
16
25
  }
17
26
  };
18
27
  const Icon = iconType === 'heart' ? icons.HeartFilledIcon : icons.CoffeeFilledIcon;
28
+ const displayText = resolveText(t, text, 'Buy me a coffee');
19
29
  const classes = clsx('designbase-figma-donation-badge', `designbase-figma-donation-badge--${size}`, `designbase-figma-donation-badge--${iconType}`, className);
20
- return (React.createElement("button", { type: "button", className: classes, onClick: handleClick, "aria-label": text },
30
+ return (React.createElement("button", { type: "button", className: classes, onClick: handleClick, "aria-label": displayText },
21
31
  React.createElement(Icon, { className: "designbase-figma-donation-badge__icon" }),
22
- React.createElement("span", { className: "designbase-figma-donation-badge__text" }, text)));
32
+ React.createElement("span", { className: "designbase-figma-donation-badge__text" }, displayText)));
23
33
  };
24
34
  DonationBadge.displayName = 'DonationBadge';
25
35
 
@@ -90,7 +100,7 @@ const FigmaHeader = ({ children, actions = [], searchBar, sticky = true, classNa
90
100
  };
91
101
  FigmaHeader.displayName = 'FigmaHeader';
92
102
 
93
- const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom, isEnabled = true, onToggle, className, enableScrollNavigation = false, headerHeight = 94, onActiveSectionChange, }) => {
103
+ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom, isEnabled = true, onToggle, className, enableScrollNavigation = false, headerHeight = 94, onActiveSectionChange, t }) => {
94
104
  const sectionRef = React.useRef(null);
95
105
  const sectionStyle = marginBottom ? { marginBottom: `${marginBottom}px` } : {};
96
106
  const classes = [
@@ -130,7 +140,7 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
130
140
  }, [enableScrollNavigation, dataCategory, headerHeight, onActiveSectionChange]);
131
141
  return (React.createElement("section", { ref: sectionRef, className: classes, ...(dataCategory ? { 'data-category': dataCategory } : {}), style: sectionStyle },
132
142
  title && (React.createElement("div", { className: "designbase-figma-section__header" },
133
- React.createElement("h2", { className: "designbase-figma-section__title" }, title),
143
+ React.createElement("h2", { className: "designbase-figma-section__title" }, resolveText(t, title)),
134
144
  React.createElement("div", { className: "designbase-figma-section__controls" },
135
145
  iconButton,
136
146
  onToggle && (React.createElement(ui.Toggle, { checked: isEnabled, onChange: () => onToggle(dataCategory), size: "s" }))))),
@@ -368,7 +378,7 @@ const DEFAULT_LANGUAGES = [
368
378
  { code: 'ko', label: 'KO' },
369
379
  { code: 'en', label: 'EN' },
370
380
  ];
371
- const LanguageSelector = ({ currentLanguage = 'ko', languages = DEFAULT_LANGUAGES, onLanguageChange, size = 's', className, }) => {
381
+ const LanguageSelector = ({ currentLanguage = 'ko', languages = DEFAULT_LANGUAGES, onLanguageChange, size = 's', className, t }) => {
372
382
  const handleLanguageChange = (languageCode) => {
373
383
  if (onLanguageChange) {
374
384
  onLanguageChange(languageCode);
@@ -377,7 +387,7 @@ const LanguageSelector = ({ currentLanguage = 'ko', languages = DEFAULT_LANGUAGE
377
387
  const classes = clsx('designbase-figma-language-selector', `designbase-figma-language-selector--${size}`, className);
378
388
  return (React.createElement("div", { className: classes }, languages.map((language) => (React.createElement("button", { key: language.code, type: "button", className: clsx('designbase-figma-language-selector__button', {
379
389
  'designbase-figma-language-selector__button--active': currentLanguage === language.code,
380
- }), onClick: () => handleLanguageChange(language.code), "aria-label": `${language.label} 언어 선택`, "aria-pressed": currentLanguage === language.code }, language.label)))));
390
+ }), onClick: () => handleLanguageChange(language.code), "aria-label": `${resolveText(t, language.label)} 언어 선택`, "aria-pressed": currentLanguage === language.code }, resolveText(t, language.label))))));
381
391
  };
382
392
  LanguageSelector.displayName = 'LanguageSelector';
383
393
 
@@ -410,13 +420,13 @@ const FigmaFooter = ({ logoSrc, logoAlt = 'DesignBase', logoType = 'designbase',
410
420
  React.createElement("span", { className: "designbase-figma-footer__reset-info" }, t('resetsDaily')))))),
411
421
  React.createElement(PaymentBadge, { isActive: isActive, onClick: onLicensePageClick, isLoading: isLoading, t: t }))),
412
422
  showDonation && (React.createElement("div", { className: "designbase-figma-footer__donation" },
413
- showDonationText && !isActive && (React.createElement("div", { className: "designbase-figma-footer__donation-text" }, donationPromptText || t('donationPrompt'))),
414
- React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s" })))),
423
+ showDonationText && !isActive && (React.createElement("div", { className: "designbase-figma-footer__donation-text" }, resolveText(t, donationPromptText, t('donationPrompt')))),
424
+ React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", t: t })))),
415
425
  children));
416
426
  };
417
427
  FigmaFooter.displayName = 'FigmaFooter';
418
428
 
419
- const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = false, value = '', onValueChange, label = 'License Key', placeholder = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', submitText = 'Submit', submittingText = 'Verifying...', className, }) => {
429
+ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = false, value = '', onValueChange, label = { key: 'form.license_key' }, placeholder = { key: 'form.license_placeholder' }, submitText = { key: 'form.submit' }, submittingText = { key: 'form.verifying' }, className, t }) => {
420
430
  const [inputValue, setInputValue] = React.useState(value);
421
431
  React.useEffect(() => {
422
432
  setInputValue(value);
@@ -430,15 +440,19 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
430
440
  setInputValue(newValue);
431
441
  onValueChange?.(newValue);
432
442
  };
443
+ const displayLabel = resolveText(t, label, 'License Key');
444
+ const displayPlaceholder = resolveText(t, placeholder, 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx');
445
+ const displaySubmitText = resolveText(t, submitText, 'Submit');
446
+ const displaySubmittingText = resolveText(t, submittingText, 'Verifying...');
433
447
  return (React.createElement("form", { className: `designbase-figma-form-with-submit ${className || ''}`, onSubmit: handleSubmit },
434
448
  React.createElement("div", { className: "designbase-figma-form-with-submit__field" },
435
- React.createElement("label", { className: "designbase-figma-form-with-submit__label" }, label),
436
- React.createElement(ui.Input, { value: inputValue, onChange: handleChange, placeholder: placeholder, disabled: disabled || isSubmitting, size: "m" })),
437
- React.createElement(ui.Button, { type: "submit", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true }, isSubmitting ? submittingText : submitText)));
449
+ React.createElement("label", { className: "designbase-figma-form-with-submit__label" }, displayLabel),
450
+ React.createElement(ui.Input, { value: inputValue, onChange: handleChange, placeholder: displayPlaceholder, disabled: disabled || isSubmitting, size: "m" })),
451
+ React.createElement(ui.Button, { type: "submit", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true }, isSubmitting ? displaySubmittingText : displaySubmitText)));
438
452
  };
439
453
  FormWithSubmit.displayName = 'FormWithSubmit';
440
454
 
441
- const InteractionFeedback = ({ status = 'default', message, statusMessage, leftContent, rightAction, visible = true, className, }) => {
455
+ const InteractionFeedback = ({ status = 'default', message, statusMessage, leftContent, rightAction, visible = true, className, t }) => {
442
456
  const feedbackClasses = clsx('designbase-figma-interaction', `designbase-figma-interaction--${status}`, {
443
457
  'designbase-figma-interaction--visible': visible,
444
458
  }, className);
@@ -447,30 +461,34 @@ const InteractionFeedback = ({ status = 'default', message, statusMessage, leftC
447
461
  return (React.createElement("div", { className: feedbackClasses },
448
462
  React.createElement("div", { className: "designbase-figma-interaction__content" },
449
463
  React.createElement("div", { className: "designbase-figma-interaction__left" }, leftContent || (React.createElement("div", { className: "designbase-figma-interaction__message" },
450
- message && (React.createElement("span", { className: "designbase-figma-interaction__text" }, message)),
451
- statusMessage && (React.createElement("span", { className: "designbase-figma-interaction__status-text" }, statusMessage))))),
464
+ message && (React.createElement("span", { className: "designbase-figma-interaction__text" }, resolveText(t, message))),
465
+ statusMessage && (React.createElement("span", { className: "designbase-figma-interaction__status-text" }, resolveText(t, statusMessage)))))),
452
466
  rightAction && (React.createElement("div", { className: "designbase-figma-interaction__right" }, rightAction)))));
453
467
  };
454
468
  InteractionFeedback.displayName = 'InteractionFeedback';
455
469
 
456
- const PaymentStatusSection = ({ status, usageCount, activationLimit, activationUsage, licenseKey, onDeactivate, isDeactivating = false, showDetails = false, className, }) => {
470
+ const PaymentStatusSection = ({ status, usageCount, activationLimit, activationUsage, licenseKey, onDeactivate, isDeactivating = false, showDetails = false, className, t }) => {
457
471
  const remainingActivations = activationLimit - activationUsage;
458
472
  return (React.createElement("div", { className: `designbase-figma-payment-status ${className || ''}` },
459
473
  React.createElement("div", { className: "designbase-figma-payment-status__license-key" },
460
- "\uB77C\uC774\uC120\uC2A4 \uD0A4: ",
474
+ resolveText(t, { key: 'payment.license_key_label' }, '라이선스 키'),
475
+ ": ",
461
476
  React.createElement("span", null, licenseKey)),
462
477
  showDetails && (React.createElement("div", { className: "designbase-figma-payment-status__details" },
463
478
  React.createElement("div", { className: "designbase-figma-payment-status__activation-info" },
464
479
  React.createElement("div", { className: "designbase-figma-payment-status__remaining" },
465
480
  remainingActivations,
466
481
  " ",
467
- remainingActivations === 1 ? '활성' : '활성',
468
- " \uC790\uB9AC \uB0A8\uC74C"),
482
+ resolveText(t, { key: 'payment.activations_remaining' }, '활성'),
483
+ " ",
484
+ resolveText(t, { key: 'payment.spots_remaining' }, '자리 남음')),
469
485
  React.createElement("div", { className: "designbase-figma-payment-status__usage" },
470
486
  activationUsage,
471
487
  "/",
472
488
  activationLimit)),
473
- React.createElement(ui.Button, { onClick: onDeactivate, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating ? '비활성화중...' : '라이선스 비활성화')))));
489
+ React.createElement(ui.Button, { onClick: onDeactivate, variant: "tertiary", size: "s", disabled: isDeactivating }, isDeactivating
490
+ ? resolveText(t, { key: 'payment.deactivating' }, '비활성화중...')
491
+ : resolveText(t, { key: 'payment.deactivate_license' }, '라이선스 비활성화'))))));
474
492
  };
475
493
  PaymentStatusSection.displayName = 'PaymentStatusSection';
476
494
 
@@ -832,37 +850,63 @@ const SettingsModal = ({ isOpen, onClose, categories: initialCategories, categor
832
850
  };
833
851
  SettingsModal.displayName = 'SettingsModal';
834
852
 
835
- const TitleDescription = ({ iconSrc, iconAlt = 'Icon', title, description, button, features, className, }) => {
853
+ const TitleDescription = ({ iconSrc, iconAlt = 'Icon', title, description, button, features, className, t }) => {
836
854
  const classes = [
837
855
  'designbase-figma-title-description',
838
856
  className,
839
857
  ]
840
858
  .filter(Boolean)
841
859
  .join(' ');
860
+ const displayTitle = resolveText(t, title);
861
+ const displayDescription = resolveText(t, description);
842
862
  return (React.createElement("div", { className: classes },
843
863
  iconSrc && (React.createElement("img", { className: "designbase-figma-title-description__icon", src: iconSrc, alt: iconAlt })),
844
- React.createElement("h5", { className: "designbase-figma-title-description__title" }, title),
845
- React.createElement("p", { className: "designbase-figma-title-description__description" }, description),
864
+ React.createElement("h5", { className: "designbase-figma-title-description__title" }, displayTitle),
865
+ React.createElement("p", { className: "designbase-figma-title-description__description" }, displayDescription),
846
866
  button && React.createElement("div", { className: "designbase-figma-title-description__button" }, button),
847
- features && features.length > 0 && (React.createElement("ul", { className: "designbase-figma-title-description__features" }, features.map((feature, index) => (React.createElement("li", { key: index, className: "designbase-figma-title-description__feature-item" },
848
- React.createElement("span", { className: "designbase-figma-title-description__check-icon" },
849
- React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
850
- React.createElement("circle", { cx: "12", cy: "12", r: "11", fill: "currentColor" }),
851
- React.createElement("path", { d: "M8 12L11 15L16 9", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }))),
852
- React.createElement("span", { className: "designbase-figma-title-description__feature-text" }, feature))))))));
867
+ features && features.length > 0 && (React.createElement("ul", { className: "designbase-figma-title-description__features" }, features.map((feature, index) => {
868
+ const displayFeature = resolveText(t, feature);
869
+ return (React.createElement("li", { key: index, className: "designbase-figma-title-description__feature-item" },
870
+ React.createElement("span", { className: "designbase-figma-title-description__check-icon" },
871
+ React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
872
+ React.createElement("circle", { cx: "12", cy: "12", r: "11", fill: "currentColor" }),
873
+ React.createElement("path", { d: "M8 12L11 15L16 9", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }))),
874
+ React.createElement("span", { className: "designbase-figma-title-description__feature-text" }, displayFeature)));
875
+ })))));
853
876
  };
854
877
  TitleDescription.displayName = 'TitleDescription';
855
878
 
856
- const UpgradeBanner = ({ onClick, isLoading = false, title, description, buttonText, t = (key) => key, className, }) => {
879
+ const UpgradeBanner = ({ onClick, isLoading = false, title = { key: 'banner.upgrade_title' }, description = { key: 'banner.upgrade_description' }, buttonText = { key: 'banner.upgrade_button' }, className, t }) => {
880
+ const displayTitle = resolveText(t, title, '프로로 업그레이드하세요');
881
+ const displayDescription = resolveText(t, description, '무제한 기능을 사용하고 더 많은 혜택을 누리세요.');
882
+ const displayButtonText = resolveText(t, buttonText, '지금 업그레이드');
857
883
  return (React.createElement("div", { className: `designbase-figma-upgrade-banner ${className || ''}` },
858
884
  React.createElement("div", { className: "designbase-figma-upgrade-banner__content" },
859
885
  React.createElement("div", { className: "designbase-figma-upgrade-banner__text-wrap" },
860
- React.createElement("h3", { className: "designbase-figma-upgrade-banner__title" }, title || t('bannerTitle') || '프로로 업그레이드하세요'),
861
- React.createElement("p", { className: "designbase-figma-upgrade-banner__text" }, description || t('bannerText') || '무제한 기능을 사용하고 더 많은 혜택을 누리세요.')),
862
- React.createElement(ui.Button, { onClick: onClick, variant: "primary", size: "m", disabled: isLoading }, buttonText || t('upgradeNow') || '지금 업그레이드'))));
886
+ React.createElement("h3", { className: "designbase-figma-upgrade-banner__title" }, displayTitle),
887
+ React.createElement("p", { className: "designbase-figma-upgrade-banner__text" }, displayDescription)),
888
+ React.createElement(ui.Button, { onClick: onClick, variant: "primary", size: "m", disabled: isLoading }, displayButtonText))));
863
889
  };
864
890
  UpgradeBanner.displayName = 'UpgradeBanner';
865
891
 
892
+ const LicenseManager = ({ licenseStatus, licenseKey = '', activationLimit = 3, activationUsage = 0, usageCount = 0, onLicenseActivate, onLicenseDeactivate, isActivating = false, isDeactivating = false, className, t }) => {
893
+ const [inputValue, setInputValue] = React.useState('');
894
+ const handleLicenseSubmit = async (submittedKey) => {
895
+ await onLicenseActivate(submittedKey);
896
+ setInputValue('');
897
+ };
898
+ const handleDeactivate = async () => {
899
+ await onLicenseDeactivate();
900
+ };
901
+ if (licenseStatus === 'ACTIVE' && licenseKey) {
902
+ return (React.createElement("div", { className: `designbase-figma-license-manager ${className || ''}` },
903
+ React.createElement(PaymentStatusSection, { status: "PAID", usageCount: usageCount, activationLimit: activationLimit, activationUsage: activationUsage, licenseKey: licenseKey, onDeactivate: handleDeactivate, isDeactivating: isDeactivating, showDetails: true, t: t })));
904
+ }
905
+ return (React.createElement("div", { className: `designbase-figma-license-manager ${className || ''}` },
906
+ React.createElement(FormWithSubmit, { onLicenseSubmit: handleLicenseSubmit, value: inputValue, onValueChange: setInputValue, isSubmitting: isActivating, disabled: false, t: t })));
907
+ };
908
+ LicenseManager.displayName = 'LicenseManager';
909
+
866
910
  exports.DonationBadge = DonationBadge;
867
911
  exports.FigmaContainer = FigmaContainer;
868
912
  exports.FigmaFooter = FigmaFooter;
@@ -872,6 +916,7 @@ exports.FigmaSidebar = FigmaSidebar;
872
916
  exports.FormWithSubmit = FormWithSubmit;
873
917
  exports.InteractionFeedback = InteractionFeedback;
874
918
  exports.LanguageSelector = LanguageSelector;
919
+ exports.LicenseManager = LicenseManager;
875
920
  exports.LogoDropdown = LogoDropdown;
876
921
  exports.PageLicense = PageLicense;
877
922
  exports.PaymentBadge = PaymentBadge;
@@ -883,6 +928,7 @@ exports.SettingsModal = SettingsModal;
883
928
  exports.TitleDescription = TitleDescription;
884
929
  exports.UpgradeBanner = UpgradeBanner;
885
930
  exports.getActiveSection = getActiveSection;
931
+ exports.resolveText = resolveText;
886
932
  exports.scrollToSection = scrollToSection;
887
933
  Object.keys(ui).forEach(function (k) {
888
934
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {