@designbasekorea/figma-ui 0.7.2 → 0.8.0

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.esm.js CHANGED
@@ -55,6 +55,8 @@ const FIGMA_UI_TRANSLATIONS = {
55
55
  'license.youtube_membership': 'YouTube 멤버십',
56
56
  'license.unlock_unlimited': '무제한 사용 활성화',
57
57
  'license.unlock_unlimited_description': '라이선스 키를 등록하면 모든 Designbase 플러그인의 프로 기능과 무제한 사용을 이용할 수 있습니다.',
58
+ 'license.unlimited_benefit_title': '모든 플러그인 무제한 사용',
59
+ 'license.unlimited_benefit_description': '사용 횟수 제한 없이 프로 기능과 프리미엄 콘텐츠를 이용할 수 있습니다.',
58
60
  'license.get_key_title': '라이선스 키 받기',
59
61
  'license.get_key_description': '멤버십 회원에게 매월 새 라이선스 키가 제공됩니다.',
60
62
  'license.get_key_step_1_title': '멤버십 가입',
@@ -69,6 +71,10 @@ const FIGMA_UI_TRANSLATIONS = {
69
71
  'license.unlock_pro_features': '프로 기능 활성화',
70
72
  'license.current_plan': '현재 플랜',
71
73
  'license.pro_plan': '프로 플랜',
74
+ 'license.source_tabs_label': '라이선스 제공 방식',
75
+ 'license.source_lemon_squeezy': 'Lemon Squeezy 라이선스',
76
+ 'license.source_lemon_hint': '기존 Lemon Squeezy 구매 라이선스 키를 입력하세요.',
77
+ 'license.source_youtube_hint': 'YouTube 멤버십 회원에게 제공되는 전용 키를 입력하세요.',
72
78
  'license.membership': '멤버십',
73
79
  'license.pro_account': '프로 계정',
74
80
  'license.upgrade_to_pro': '프로로 업그레이드',
@@ -107,7 +113,7 @@ const FIGMA_UI_TRANSLATIONS = {
107
113
  'license.youtube_membership_join': '멤버십 가입',
108
114
  'license.youtube_membership_guide': '안내보기',
109
115
  'license.all_plugins': '모든 플러그인',
110
- 'license.source_youtube_membership': 'YouTube 멤버십',
116
+ 'license.source_youtube_membership': 'YouTube 멤버십 전용',
111
117
  'license.source_purchase': '구매 라이선스',
112
118
  'license.status_active': '활성',
113
119
  'license.status_inactive': '라이선스 확인 실패',
@@ -207,6 +213,8 @@ const FIGMA_UI_TRANSLATIONS = {
207
213
  'license.youtube_membership': 'YouTube Membership',
208
214
  'license.unlock_unlimited': 'Unlock Unlimited Access',
209
215
  'license.unlock_unlimited_description': 'Add a license key to unlock Pro features and unlimited use across Designbase plugins.',
216
+ 'license.unlimited_benefit_title': 'Unlimited access to every plugin',
217
+ 'license.unlimited_benefit_description': 'Use Pro features and premium content without usage limits.',
210
218
  'license.get_key_title': 'Get a license key',
211
219
  'license.get_key_description': 'Members receive a new license key every month.',
212
220
  'license.get_key_step_1_title': 'Join the membership',
@@ -221,6 +229,10 @@ const FIGMA_UI_TRANSLATIONS = {
221
229
  'license.unlock_pro_features': 'Unlock Pro features',
222
230
  'license.current_plan': 'Current plan',
223
231
  'license.pro_plan': 'Pro plan',
232
+ 'license.source_tabs_label': 'License type',
233
+ 'license.source_lemon_squeezy': 'Lemon Squeezy license',
234
+ 'license.source_lemon_hint': 'Enter the license key from your Lemon Squeezy purchase.',
235
+ 'license.source_youtube_hint': 'Enter the key provided to YouTube channel members.',
224
236
  'license.membership': 'Membership',
225
237
  'license.pro_account': 'Pro account',
226
238
  'license.upgrade_to_pro': 'Upgrade to Pro',
@@ -259,7 +271,7 @@ const FIGMA_UI_TRANSLATIONS = {
259
271
  'license.youtube_membership_join': 'Join membership',
260
272
  'license.youtube_membership_guide': 'View guide',
261
273
  'license.all_plugins': 'All plugins',
262
- 'license.source_youtube_membership': 'YouTube Membership',
274
+ 'license.source_youtube_membership': 'YouTube membership only',
263
275
  'license.source_purchase': 'Purchased license',
264
276
  'license.status_active': 'Active',
265
277
  'license.status_inactive': 'License check failed',
@@ -359,6 +371,8 @@ const FIGMA_UI_TRANSLATIONS = {
359
371
  'license.youtube_membership': 'YouTubeメンバーシップ',
360
372
  'license.unlock_unlimited': '無制限アクセスを有効化',
361
373
  'license.unlock_unlimited_description': 'ライセンスキーを登録すると、DesignbaseプラグインのPro機能を無制限で利用できます。',
374
+ 'license.unlimited_benefit_title': 'すべてのプラグインを無制限で利用',
375
+ 'license.unlimited_benefit_description': '回数制限なくPro機能とプレミアムコンテンツを利用できます。',
362
376
  'license.get_key_title': 'ライセンスキーを取得',
363
377
  'license.get_key_description': 'メンバーには毎月新しいライセンスキーが提供されます。',
364
378
  'license.get_key_step_1_title': 'メンバーシップに参加',
@@ -373,6 +387,10 @@ const FIGMA_UI_TRANSLATIONS = {
373
387
  'license.unlock_pro_features': 'Pro機能を有効化',
374
388
  'license.current_plan': '現在のプラン',
375
389
  'license.pro_plan': 'Proプラン',
390
+ 'license.source_tabs_label': 'ライセンスの種類',
391
+ 'license.source_lemon_squeezy': 'Lemon Squeezy ライセンス',
392
+ 'license.source_lemon_hint': 'Lemon Squeezyで購入したライセンスキーを入力してください。',
393
+ 'license.source_youtube_hint': 'YouTubeメンバー向けの専用キーを入力してください。',
376
394
  'license.membership': 'メンバーシップ',
377
395
  'license.pro_account': 'Proアカウント',
378
396
  'license.upgrade_to_pro': 'Proにアップグレード',
@@ -411,7 +429,7 @@ const FIGMA_UI_TRANSLATIONS = {
411
429
  'license.youtube_membership_join': 'メンバーシップに参加',
412
430
  'license.youtube_membership_guide': 'ガイドを見る',
413
431
  'license.all_plugins': 'すべてのプラグイン',
414
- 'license.source_youtube_membership': 'YouTubeメンバーシップ',
432
+ 'license.source_youtube_membership': 'YouTubeメンバーシップ専用',
415
433
  'license.source_purchase': '購入ライセンス',
416
434
  'license.status_active': '有効',
417
435
  'license.status_inactive': 'ライセンス確認に失敗しました',
@@ -1539,14 +1557,9 @@ const LicenseOffer = ({ joinUrl, guideUrl, membershipUrl, t, locale, className,
1539
1557
  title: resolveText(translate, { key: 'license.get_key_step_2_title' }, '이번 달 키 복사'),
1540
1558
  description: resolveText(translate, { key: 'license.get_key_step_2_description' }, '멤버 전용 커뮤니티 게시글에서 키를 확인합니다.'),
1541
1559
  },
1542
- {
1543
- title: resolveText(translate, { key: 'license.get_key_step_3_title' }, '키 등록'),
1544
- description: resolveText(translate, { key: 'license.get_key_step_3_description' }, '아래 입력창에 붙여 넣으면 프로 기능이 열립니다.'),
1545
- },
1546
1560
  ];
1547
1561
  return (React.createElement("section", { className: `designbase-figma-license-offer ${className || ''}`, "aria-labelledby": titleId },
1548
1562
  React.createElement("header", { className: "designbase-figma-license-offer__header" },
1549
- React.createElement("span", { className: "designbase-figma-license-offer__section-index", "aria-hidden": "true" }, "1"),
1550
1563
  React.createElement("div", null,
1551
1564
  React.createElement("h3", { id: titleId, className: "designbase-figma-license-offer__title" }, resolveText(translate, { key: 'license.get_key_title' }, '라이선스 키 받기')),
1552
1565
  React.createElement("p", { className: "designbase-figma-license-offer__description" }, resolveText(translate, { key: 'license.get_key_description' }, '멤버십 회원에게 매월 새 라이선스 키가 제공됩니다.')))),
@@ -1992,7 +2005,9 @@ function formatUsageLabel(state, t) {
1992
2005
  if (usageLimit === 'unlimited') {
1993
2006
  return (resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음') ?? '사용 횟수 제한 없음');
1994
2007
  }
1995
- const limit = typeof usageLimit === 'number' ? usageLimit : remainingUsage + usageUsed;
2008
+ const limit = typeof usageLimit === 'number'
2009
+ ? usageLimit
2010
+ : remainingUsage + usageUsed;
1996
2011
  const remaining = remainingUsage ?? Math.max(0, limit - usageUsed);
1997
2012
  if (usageReset === 'daily') {
1998
2013
  const fallback = `오늘 남은 횟수 ${remaining}/${limit}`;
@@ -2011,7 +2026,7 @@ function formatUsageLabel(state, t) {
2011
2026
  }
2012
2027
  return (resolveText(t, { key: 'license.usage_generic', values: { remaining, limit } }, `남은 횟수 ${remaining}/${limit}`) ?? `남은 횟수 ${remaining}/${limit}`);
2013
2028
  }
2014
- const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', licenseStatus: initialLicenseStatus, licenseSource: initialLicenseSource, accessScope: initialAccessScope, expiresAt: initialExpiresAt, lastVerifiedAt: initialLastVerifiedAt, wordpressLinks, paymentPageUrl, mode = 'pricing', membershipUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, locale, className, }) => {
2029
+ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', licenseStatus: initialLicenseStatus, licenseSource: initialLicenseSource, accessScope: initialAccessScope, expiresAt: initialExpiresAt, lastVerifiedAt: initialLastVerifiedAt, wordpressLinks, paymentPageUrl, mode = 'pricing', showYoutubeMembershipTab = false, membershipUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, locale, className, }) => {
2015
2030
  const { t: translate } = useFigmaUiI18n(locale, t);
2016
2031
  const links = useMemo(() => ({
2017
2032
  purchaseUrl: wordpressLinks?.purchaseUrl ?? paymentPageUrl,
@@ -2040,8 +2055,9 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
2040
2055
  onUsageCountChange: setUsageCount,
2041
2056
  });
2042
2057
  const [licenseKeyDraft, setLicenseKeyDraft] = useState(initialLicenseKey);
2058
+ const [activeLicenseMode, setActiveLicenseMode] = useState(mode);
2043
2059
  const isPaid = state.isLicenseRegistered && state.paymentStatus === 'PAID';
2044
- const isMembershipMode = mode === 'youtube-membership';
2060
+ const isMembershipMode = activeLicenseMode === 'youtube-membership';
2045
2061
  const usageLabel = formatUsageLabel(state, translate);
2046
2062
  const handleLicenseSubmit = async (submittedLicenseKey) => {
2047
2063
  if (onLicenseSubmit) {
@@ -2054,8 +2070,14 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
2054
2070
  setLicenseKeyDraft(value);
2055
2071
  setLicenseKeyInput(value);
2056
2072
  };
2057
- return (React.createElement("div", { className: `designbase-figma-page-license designbase-figma-page-license--${mode} ${className || ''}`, "data-license-mode": mode },
2073
+ return (React.createElement("div", { className: `designbase-figma-page-license designbase-figma-page-license--${activeLicenseMode} ${className || ''}`, "data-license-mode": activeLicenseMode },
2058
2074
  React.createElement("div", { className: "designbase-figma-page-license__content" },
2075
+ showYoutubeMembershipTab && (React.createElement("div", { className: "designbase-figma-page-license__source-tabs", role: "tablist", "aria-label": resolveText(translate, { key: 'license.source_tabs_label' }, 'License type') },
2076
+ React.createElement("button", { type: "button", role: "tab", "aria-selected": !isMembershipMode, onClick: () => setActiveLicenseMode('pricing') }, resolveText(translate, { key: 'license.source_lemon_squeezy' }, 'Lemon Squeezy license')),
2077
+ React.createElement("button", { type: "button", role: "tab", "aria-selected": isMembershipMode, onClick: () => setActiveLicenseMode('youtube-membership') }, resolveText(translate, { key: 'license.source_youtube_membership' }, 'YouTube membership')))),
2078
+ showYoutubeMembershipTab && (React.createElement("p", { className: "designbase-figma-page-license__source-hint" }, isMembershipMode
2079
+ ? resolveText(translate, { key: 'license.source_youtube_hint' }, 'Enter the key provided to YouTube channel members.')
2080
+ : resolveText(translate, { key: 'license.source_lemon_hint' }, 'Enter the license key from your Lemon Squeezy purchase.'))),
2059
2081
  React.createElement("div", { className: "designbase-figma-page-license__header" },
2060
2082
  React.createElement("div", { className: "designbase-figma-page-license__title" },
2061
2083
  React.createElement("h2", null, isPaid
@@ -2067,9 +2089,16 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
2067
2089
  React.createElement("p", { className: "designbase-figma-page-license__description" }, isPaid
2068
2090
  ? resolveText(translate, { key: 'license.all_features_available' }, '모든 기능을 사용할 수 있습니다.')
2069
2091
  : isMembershipMode
2070
- ? resolveText(translate, { key: 'license.unlock_unlimited_description' }, '라이선스 키를 등록하면 모든 Designbase 플러그인의 프로 기능과 무제한 사용을 이용할 수 있습니다.')
2092
+ ? resolveText(translate, {
2093
+ key: 'license.unlock_unlimited_description',
2094
+ }, '라이선스 키를 등록하면 모든 Designbase 플러그인의 프로 기능과 무제한 사용을 이용할 수 있습니다.')
2071
2095
  : resolveText(translate, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
2072
2096
  !isPaid && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
2097
+ !isPaid && isMembershipMode && (React.createElement("div", { className: "designbase-figma-page-license__benefit" },
2098
+ React.createElement("span", { className: "designbase-figma-page-license__benefit-icon", "aria-hidden": "true" }, "\u221E"),
2099
+ React.createElement("div", null,
2100
+ React.createElement("strong", null, resolveText(translate, { key: 'license.unlimited_benefit_title' }, '모든 플러그인 무제한 사용')),
2101
+ React.createElement("p", null, resolveText(translate, { key: 'license.unlimited_benefit_description' }, '사용 횟수 제한 없이 프로 기능과 프리미엄 콘텐츠를 이용할 수 있습니다.'))))),
2073
2102
  !isMembershipMode && (React.createElement(PricingComparison, { features: pricingFeatures, pricing: pricing, paymentType: paymentType, t: translate })),
2074
2103
  state.lastMessage &&
2075
2104
  state.lastErrorCode &&
@@ -2084,9 +2113,12 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
2084
2113
  React.createElement("div", { className: "designbase-figma-page-license__paid-actions" },
2085
2114
  state.activationLimit > 0 && (React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
2086
2115
  React.createElement("div", { className: "designbase-figma-page-license__remaining" },
2087
- Math.max(0, state.activationLimit - state.activationUsage),
2116
+ Math.max(0, state.activationLimit -
2117
+ state.activationUsage),
2088
2118
  ' ',
2089
- resolveText(translate, { key: 'license.activations_remaining' }, '활성'),
2119
+ resolveText(translate, {
2120
+ key: 'license.activations_remaining',
2121
+ }, '활성'),
2090
2122
  ' ',
2091
2123
  resolveText(translate, { key: 'license.spots_remaining' }, '자리 남음')),
2092
2124
  React.createElement("div", { className: "designbase-figma-page-license__usage-count" },
@@ -2096,39 +2128,60 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
2096
2128
  React.createElement(Button, { onPress: deactivateLicense, variant: "secondary", size: "m", fullWidth: true, disabled: isDeactivating }, isDeactivating
2097
2129
  ? resolveText(translate, { key: 'license.deactivating' }, '비활성화 중...')
2098
2130
  : resolveText(translate, { key: 'license.deactivate' }, '라이선스 비활성화')),
2099
- state.deactivateMessage && state.deactivateErrorCode && (React.createElement("p", { className: `designbase-figma-page-license__action-feedback designbase-figma-page-license__action-feedback--${resolvePaymentFeedbackVariant(state.deactivateErrorCode)}`, role: "alert", "aria-live": "polite" }, state.deactivateMessage)),
2131
+ state.deactivateMessage &&
2132
+ state.deactivateErrorCode && (React.createElement("p", { className: `designbase-figma-page-license__action-feedback designbase-figma-page-license__action-feedback--${resolvePaymentFeedbackVariant(state.deactivateErrorCode)}`, role: "alert", "aria-live": "polite" }, state.deactivateMessage)),
2100
2133
  React.createElement("p", { className: "designbase-figma-page-license__deactivate-hint" }, resolveText(translate, { key: 'license.deactivate_hint' }, '이 기기에서 라이선스 연결을 해제합니다.'))))),
2101
2134
  !isPaid && (React.createElement(React.Fragment, null,
2102
2135
  isMembershipMode && (React.createElement(LicenseOffer, { joinUrl: links.membershipUrl || links.purchaseUrl, guideUrl: links.helpUrl || links.purchaseUrl, t: translate })),
2103
2136
  !isMembershipMode &&
2104
- (enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
2137
+ (enableAccountAuth ||
2138
+ links.purchaseUrl ||
2139
+ links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
2105
2140
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
2106
- React.createElement("h3", null, resolveText(translate, { key: 'license.designbase_account' }, '디자인베이스 계정'))),
2107
- React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, { key: 'license.designbase_account_hint' }, 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.')),
2141
+ React.createElement("h3", null, resolveText(translate, {
2142
+ key: 'license.designbase_account',
2143
+ }, '디자인베이스 계정'))),
2144
+ React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, {
2145
+ key: 'license.designbase_account_hint',
2146
+ }, 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.')),
2108
2147
  React.createElement("div", { className: "designbase-figma-page-license__actions" },
2109
- enableAccountAuth && (React.createElement(Button, { onPress: startDesignbaseAuth, variant: "primary", size: "m", disabled: isStartingAuth || isVerifying, fullWidth: true }, isStartingAuth
2110
- ? resolveText(translate, { key: 'license.authenticating' }, '인증 중...')
2111
- : resolveText(translate, { key: 'license.login_with_designbase' }, '디자인베이스로 로그인'))),
2148
+ enableAccountAuth && (React.createElement(Button, { onPress: startDesignbaseAuth, variant: "primary", size: "m", disabled: isStartingAuth ||
2149
+ isVerifying, fullWidth: true }, isStartingAuth
2150
+ ? resolveText(translate, {
2151
+ key: 'license.authenticating',
2152
+ }, '인증 중...')
2153
+ : resolveText(translate, {
2154
+ key: 'license.login_with_designbase',
2155
+ }, '디자인베이스로 로그인'))),
2112
2156
  links.purchaseUrl && (React.createElement(Button, { onPress: () => openExternalUrl(links.purchaseUrl), variant: "secondary", size: "m", fullWidth: true },
2113
- React.createElement("span", null, resolveText(translate, { key: 'license.purchase_membership' }, '멤버십 안내')),
2157
+ React.createElement("span", null, resolveText(translate, {
2158
+ key: 'license.purchase_membership',
2159
+ }, '멤버십 안내')),
2114
2160
  React.createElement(ExternalLinkIcon, { size: 16 }))),
2115
2161
  links.accountUrl && (React.createElement(Button, { onPress: () => openExternalUrl(links.accountUrl), variant: "tertiary", size: "s", fullWidth: true },
2116
- React.createElement("span", null, resolveText(translate, { key: 'license.manage_account' }, '계정·멤버십 관리')),
2162
+ React.createElement("span", null, resolveText(translate, {
2163
+ key: 'license.manage_account',
2164
+ }, '계정·멤버십 관리')),
2117
2165
  React.createElement(ExternalLinkIcon, { size: 16 })))))),
2118
2166
  showLicenseKeyInput && (React.createElement("div", { className: isMembershipMode
2119
2167
  ? 'designbase-figma-page-license__key-form'
2120
2168
  : 'designbase-figma-page-license__section' },
2121
2169
  React.createElement("div", { className: "designbase-figma-page-license__section-header" },
2122
- isMembershipMode && (React.createElement("span", { className: "designbase-figma-page-license__section-index", "aria-hidden": "true" }, "2")),
2123
2170
  React.createElement("h3", null, isMembershipMode
2124
- ? resolveText(translate, { key: 'license.activate_key_title' }, '라이선스 키 등록')
2171
+ ? resolveText(translate, {
2172
+ key: 'license.activate_key_title',
2173
+ }, '라이선스 키 등록')
2125
2174
  : resolveText(translate, { key: 'license.enter_key' }, '라이선스 키 입력'))),
2126
- isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, { key: 'license.activate_key_description' }, '이미 키가 있다면 아래에 붙여 넣어 프로 기능을 활성화하세요.'))),
2175
+ isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, {
2176
+ key: 'license.activate_key_description',
2177
+ }, '이미 키가 있다면 아래에 붙여 넣어 프로 기능을 활성화하세요.'))),
2127
2178
  React.createElement(FormWithSubmit, { onLicenseSubmit: handleLicenseSubmit, disabled: false, isSubmitting: isVerifying, value: licenseKeyDraft, onValueChange: handleLicenseKeyChange, label: { key: 'license.key' }, submitText: {
2128
2179
  key: isMembershipMode
2129
2180
  ? 'license.unlock_pro_features'
2130
2181
  : 'license.submit',
2131
- }, submittingText: { key: 'license.verifying' }, helperText: {
2182
+ }, submittingText: {
2183
+ key: 'license.verifying',
2184
+ }, helperText: {
2132
2185
  key: isMembershipMode
2133
2186
  ? 'license.enter_from_youtube'
2134
2187
  : 'license.enter_from_email',