@designbasekorea/figma-ui 0.6.10 → 0.7.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.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +155 -34
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +155 -34
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
37
37
|
remainingShort: '남음',
|
|
38
38
|
usageCountCaption: '오늘 사용',
|
|
39
39
|
remainingCopy: '{{count}}회 남음 · 매일 리셋',
|
|
40
|
+
lowUsageWarning: '무료 사용량이 {{count}}회({{percent}}%) 남았습니다. 멤버십으로 무제한 이용해보세요.',
|
|
40
41
|
usageUnavailable: '사용량 제한이 없습니다',
|
|
41
42
|
unlimitedUsageTooltip: '모든 기능을 제한 없이 사용할 수 있습니다',
|
|
42
43
|
betaUsageDescription: '베타 기간에는 사용량 제한이 적용되지 않습니다',
|
|
@@ -169,6 +170,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
169
170
|
remainingShort: 'left',
|
|
170
171
|
usageCountCaption: 'Used today',
|
|
171
172
|
remainingCopy: '{{count}} remaining · resets daily',
|
|
173
|
+
lowUsageWarning: 'Only {{count}} free uses ({{percent}}%) remain. Upgrade for unlimited access.',
|
|
172
174
|
usageUnavailable: 'No usage limit',
|
|
173
175
|
unlimitedUsageTooltip: 'Use every feature without limits',
|
|
174
176
|
betaUsageDescription: 'Usage limits are not applied during the beta period',
|
|
@@ -301,6 +303,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
301
303
|
remainingShort: '残り',
|
|
302
304
|
usageCountCaption: '今日の使用',
|
|
303
305
|
remainingCopy: '{{count}}回残り · 毎日リセット',
|
|
306
|
+
lowUsageWarning: '無料使用回数は残り{{count}}回({{percent}}%)です。無制限利用にアップグレードできます。',
|
|
304
307
|
usageUnavailable: '使用制限はありません',
|
|
305
308
|
unlimitedUsageTooltip: 'すべての機能を無制限で使用できます',
|
|
306
309
|
betaUsageDescription: 'ベータ期間中は使用制限がありません',
|
|
@@ -978,7 +981,7 @@ const fallbackText = (t, key, fallback) => {
|
|
|
978
981
|
const translated = t?.(key);
|
|
979
982
|
return translated && translated !== key ? translated : fallback;
|
|
980
983
|
};
|
|
981
|
-
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, t, locale, className, }) => {
|
|
984
|
+
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, t, locale, className, }) => {
|
|
982
985
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
983
986
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
984
987
|
const rootRef = React.useRef(null);
|
|
@@ -988,9 +991,11 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, maxDailyUsage = 20,
|
|
|
988
991
|
const isBeta = paymentStatus === 'BETA';
|
|
989
992
|
const hasDailyLimit = !isPaid && maxDailyUsage > 0;
|
|
990
993
|
const limit = Math.max(1, Math.round(maxDailyUsage));
|
|
991
|
-
const
|
|
992
|
-
const remaining =
|
|
993
|
-
|
|
994
|
+
const hasRemainingUsage = typeof remainingUsage === 'number' && Number.isFinite(remainingUsage);
|
|
995
|
+
const remaining = hasRemainingUsage
|
|
996
|
+
? Math.min(limit, Math.max(0, Math.round(remainingUsage)))
|
|
997
|
+
: Math.max(0, limit - Math.min(limit, Math.max(0, Math.round(usageCount))));
|
|
998
|
+
const remainingPercent = hasDailyLimit ? Math.round((remaining / limit) * 100) : 0;
|
|
994
999
|
const hasControl = showUsage || showPlan;
|
|
995
1000
|
const planLabel = isPaid
|
|
996
1001
|
? fallbackText(translate, 'proUser', '프로')
|
|
@@ -1048,7 +1053,7 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, maxDailyUsage = 20,
|
|
|
1048
1053
|
React.createElement("div", { className: "designbase-figma-usage-status__control" },
|
|
1049
1054
|
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(translate, '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,
|
|
1050
1055
|
React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
|
|
1051
|
-
React.createElement("span", { style: { width: `${
|
|
1056
|
+
React.createElement("span", { style: { width: `${remainingPercent}%` } })),
|
|
1052
1057
|
React.createElement("span", { className: "designbase-figma-usage-status__usage-value" },
|
|
1053
1058
|
React.createElement("strong", null, remaining),
|
|
1054
1059
|
React.createElement("span", null,
|
|
@@ -1064,36 +1069,19 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, maxDailyUsage = 20,
|
|
|
1064
1069
|
React.createElement("span", null, fallbackText(translate, 'unlimitedUsageTooltip', '모든 기능을 제한 없이 사용할 수 있습니다')))) : isBeta ? (React.createElement("p", { className: "designbase-figma-usage-status__note" }, fallbackText(translate, 'betaUsageDescription', '베타 기간에는 사용량 제한이 적용되지 않습니다'))) : hasDailyLimit ? (React.createElement("div", { className: "designbase-figma-usage-status__usage-detail" },
|
|
1065
1070
|
React.createElement("div", { className: "designbase-figma-usage-status__usage-summary" },
|
|
1066
1071
|
React.createElement("strong", { className: "designbase-figma-usage-status__usage-count" },
|
|
1067
|
-
|
|
1072
|
+
remaining,
|
|
1068
1073
|
React.createElement("span", { className: "designbase-figma-usage-status__usage-divider" }, "/"),
|
|
1069
1074
|
limit),
|
|
1070
|
-
React.createElement("span", { className: "designbase-figma-usage-status__usage-caption" }, fallbackText(translate, '
|
|
1071
|
-
|
|
1072
|
-
|
|
1075
|
+
React.createElement("span", { className: "designbase-figma-usage-status__usage-caption" }, fallbackText(translate, 'remainingToday', '오늘 남은 사용량')),
|
|
1076
|
+
React.createElement("strong", { className: "designbase-figma-usage-status__usage-percent" },
|
|
1077
|
+
remainingPercent,
|
|
1078
|
+
"%")),
|
|
1079
|
+
React.createElement("div", { className: "designbase-figma-usage-status__progress", role: "progressbar", "aria-label": fallbackText(translate, 'remainingToday', '오늘 남은 사용량'), "aria-valuemin": 0, "aria-valuemax": limit, "aria-valuenow": remaining, "aria-valuetext": `${remaining} / ${limit}, ${remainingPercent}%` },
|
|
1080
|
+
React.createElement("span", { style: { width: `${remainingPercent}%` } })),
|
|
1073
1081
|
React.createElement("p", { className: "designbase-figma-usage-status__remaining-copy" }, resolveText(translate, { key: 'remainingCopy', values: { count: remaining } }, `${remaining}회 남음 · 매일 리셋`)))) : (React.createElement("p", { className: "designbase-figma-usage-status__note" }, fallbackText(translate, 'usageUnavailable', '사용량 제한이 없습니다')))))));
|
|
1074
1082
|
};
|
|
1075
1083
|
UsageStatusPopover.displayName = 'UsageStatusPopover';
|
|
1076
1084
|
|
|
1077
|
-
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 = { key: 'donation.buy_me_a_coffee' }, showDonationText = true, donationPromptText, showLanguageSelector = true, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t, children, }) => {
|
|
1078
|
-
const { t: translate } = useFigmaUiI18n(currentLanguage, t);
|
|
1079
|
-
const resolvedShowUsageInfo = showPaymentStatus && showUsageInfo;
|
|
1080
|
-
const resolvedShowPaymentBadge = showPaymentStatus && showPaymentBadge;
|
|
1081
|
-
const resolvedLicensePageClick = paymentStatus === 'BETA' ? undefined : onLicensePageClick;
|
|
1082
|
-
const hasChildren = React.Children.count(children) > 0;
|
|
1083
|
-
const classes = clsx('designbase-figma-footer', {
|
|
1084
|
-
'designbase-figma-footer--has-children': hasChildren,
|
|
1085
|
-
}, className);
|
|
1086
|
-
return (React.createElement("footer", { className: classes },
|
|
1087
|
-
React.createElement("div", { className: "designbase-figma-footer__wrap" },
|
|
1088
|
-
React.createElement("div", { className: "designbase-figma-footer__left" },
|
|
1089
|
-
React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, languages: languages, currentLanguage: currentLanguage, showLanguageSelector: showLanguageSelector, onLanguageChange: onLanguageChange, t: translate })),
|
|
1090
|
-
React.createElement("div", { className: "designbase-figma-footer__right" },
|
|
1091
|
-
(resolvedShowUsageInfo || resolvedShowPaymentBadge) && (React.createElement(UsageStatusPopover, { paymentStatus: paymentStatus, usageCount: usageCount, maxDailyUsage: maxDailyUsage, showUsage: resolvedShowUsageInfo, showPlan: resolvedShowPaymentBadge, isLoading: isLoading, onLicensePageClick: resolvedLicensePageClick, t: translate })),
|
|
1092
|
-
showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: translate })))),
|
|
1093
|
-
children));
|
|
1094
|
-
};
|
|
1095
|
-
FigmaFooter.displayName = 'FigmaFooter';
|
|
1096
|
-
|
|
1097
1085
|
const FigmaToastStack = ({ toasts, position, maxToasts, onRemoveToast, }) => {
|
|
1098
1086
|
const visibleToasts = [...toasts]
|
|
1099
1087
|
.sort((a, b) => b.createdAt - a.createdAt)
|
|
@@ -1154,17 +1142,150 @@ const FigmaToast = ({ message, isVisible, onClose, type = 'info', duration = 300
|
|
|
1154
1142
|
React.createElement(react.Toast, { toastId: "figma-toast-simple", title: message, status: type, duration: duration, showProgress: false, showClose: true, onClose: onClose })));
|
|
1155
1143
|
};
|
|
1156
1144
|
const useFigmaToast = () => {
|
|
1157
|
-
const [toast, setToast] = React.useState({
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1145
|
+
const [toast, setToast] = React.useState({
|
|
1146
|
+
message: '',
|
|
1147
|
+
isVisible: false,
|
|
1148
|
+
type: 'info',
|
|
1149
|
+
});
|
|
1150
|
+
const timeoutRef = React.useRef(null);
|
|
1151
|
+
const showToast = React.useCallback((message, type = 'info') => {
|
|
1152
|
+
if (timeoutRef.current)
|
|
1153
|
+
clearTimeout(timeoutRef.current);
|
|
1154
|
+
setToast({ message, isVisible: true, type });
|
|
1155
|
+
timeoutRef.current = setTimeout(() => {
|
|
1156
|
+
setToast({ message: '', isVisible: false, type: 'info' });
|
|
1157
|
+
timeoutRef.current = null;
|
|
1158
|
+
}, 5000);
|
|
1161
1159
|
}, []);
|
|
1162
|
-
|
|
1160
|
+
React.useEffect(() => () => {
|
|
1161
|
+
if (timeoutRef.current)
|
|
1162
|
+
clearTimeout(timeoutRef.current);
|
|
1163
|
+
}, []);
|
|
1164
|
+
const toastComponent = toast.isVisible ? (React.createElement(FigmaToast, { message: toast.message, isVisible: toast.isVisible, onClose: () => setToast({ message: '', isVisible: false, type: 'info' }), type: toast.type, duration: 5000 })) : null;
|
|
1163
1165
|
return { showToast, toastComponent };
|
|
1164
1166
|
};
|
|
1165
1167
|
FigmaToastProvider.displayName = 'FigmaToastProvider';
|
|
1166
1168
|
FigmaToast.displayName = 'FigmaToast';
|
|
1167
1169
|
|
|
1170
|
+
const DEFAULT_LOW_USAGE_WARNING = { key: 'lowUsageWarning' };
|
|
1171
|
+
const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount = 0, remainingUsage, listenForUsageMessages = true, isLoading = false, showPaymentStatus = true, showUsageInfo = true, maxDailyUsage = 20, showLowUsageWarning = true, lowUsageThresholdPercent = 10, lowUsageWarningText = DEFAULT_LOW_USAGE_WARNING, onLowUsageWarning, showPaymentBadge = true, showDonation = true, donationUrl = 'https://buymeacoffee.com/designbase', donationText = { key: 'donation.buy_me_a_coffee' }, showDonationText = true, donationPromptText, showLanguageSelector = true, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t, children, }) => {
|
|
1172
|
+
const { t: translate } = useFigmaUiI18n(currentLanguage, t);
|
|
1173
|
+
const { showToast, toastComponent } = useFigmaToast();
|
|
1174
|
+
const [liveUsage, setLiveUsage] = React.useState({});
|
|
1175
|
+
const previousRemainingRef = React.useRef(null);
|
|
1176
|
+
const hasWarnedLowUsageRef = React.useRef(false);
|
|
1177
|
+
const effectivePaymentStatus = liveUsage.paymentStatus ?? paymentStatus;
|
|
1178
|
+
const effectiveUsageCount = liveUsage.usageCount ?? usageCount;
|
|
1179
|
+
const effectiveRemainingUsage = liveUsage.remainingUsage ?? remainingUsage;
|
|
1180
|
+
const effectiveMaxDailyUsage = liveUsage.maxDailyUsage ?? maxDailyUsage;
|
|
1181
|
+
const limit = Math.max(1, Math.round(effectiveMaxDailyUsage));
|
|
1182
|
+
const resolvedRemaining = typeof effectiveRemainingUsage === 'number' && Number.isFinite(effectiveRemainingUsage)
|
|
1183
|
+
? Math.min(limit, Math.max(0, Math.round(effectiveRemainingUsage)))
|
|
1184
|
+
: Math.max(0, limit - Math.min(limit, Math.max(0, Math.round(effectiveUsageCount))));
|
|
1185
|
+
const remainingPercent = Math.round((resolvedRemaining / limit) * 100);
|
|
1186
|
+
const resolvedShowUsageInfo = showPaymentStatus && (showUsageInfo || effectivePaymentStatus === 'FREE');
|
|
1187
|
+
const resolvedShowPaymentBadge = showPaymentStatus && showPaymentBadge;
|
|
1188
|
+
const resolvedLicensePageClick = effectivePaymentStatus === 'BETA' ? undefined : onLicensePageClick;
|
|
1189
|
+
const hasChildren = React.Children.count(children) > 0;
|
|
1190
|
+
React.useEffect(() => {
|
|
1191
|
+
if (!listenForUsageMessages || typeof window === 'undefined')
|
|
1192
|
+
return undefined;
|
|
1193
|
+
const handleUsageMessage = (event) => {
|
|
1194
|
+
const message = event.data?.pluginMessage;
|
|
1195
|
+
if (!message || !['initialize', 'update-plugin-status', 'usage-consume-result'].includes(message.type)) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const nextLimit = [message.usageLimit, message.freeDailyLimit, message.maxDailyUsage]
|
|
1199
|
+
.find((value) => typeof value === 'number' && Number.isFinite(value) && value > 0);
|
|
1200
|
+
const nextUsed = [message.usageUsed, message.dailyUsage]
|
|
1201
|
+
.find((value) => typeof value === 'number' && Number.isFinite(value) && value >= 0);
|
|
1202
|
+
const nextRemaining = typeof message.remainingUsage === 'number' && Number.isFinite(message.remainingUsage)
|
|
1203
|
+
? message.remainingUsage
|
|
1204
|
+
: typeof nextLimit === 'number' && typeof nextUsed === 'number'
|
|
1205
|
+
? Math.max(0, nextLimit - nextUsed)
|
|
1206
|
+
: undefined;
|
|
1207
|
+
const nextPaymentStatus = message.paymentStatus === 'PAID'
|
|
1208
|
+
? 'PAID'
|
|
1209
|
+
: message.paymentStatus === 'FREE' || message.paymentStatus === 'UNPAID'
|
|
1210
|
+
? 'FREE'
|
|
1211
|
+
: undefined;
|
|
1212
|
+
if (nextPaymentStatus === undefined
|
|
1213
|
+
&& nextLimit === undefined
|
|
1214
|
+
&& nextUsed === undefined
|
|
1215
|
+
&& nextRemaining === undefined) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
setLiveUsage((previous) => ({
|
|
1219
|
+
...previous,
|
|
1220
|
+
...(nextPaymentStatus ? { paymentStatus: nextPaymentStatus } : {}),
|
|
1221
|
+
...(typeof nextLimit === 'number' ? { maxDailyUsage: nextLimit } : {}),
|
|
1222
|
+
...(typeof nextUsed === 'number' ? { usageCount: nextUsed } : {}),
|
|
1223
|
+
...(typeof nextRemaining === 'number' ? { remainingUsage: nextRemaining } : {}),
|
|
1224
|
+
}));
|
|
1225
|
+
};
|
|
1226
|
+
window.addEventListener('message', handleUsageMessage);
|
|
1227
|
+
return () => window.removeEventListener('message', handleUsageMessage);
|
|
1228
|
+
}, [listenForUsageMessages]);
|
|
1229
|
+
React.useEffect(() => {
|
|
1230
|
+
const previousRemaining = previousRemainingRef.current;
|
|
1231
|
+
const shouldTrack = showLowUsageWarning && effectivePaymentStatus === 'FREE' && effectiveMaxDailyUsage > 0;
|
|
1232
|
+
if (!shouldTrack) {
|
|
1233
|
+
previousRemainingRef.current = resolvedRemaining;
|
|
1234
|
+
hasWarnedLowUsageRef.current = false;
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
if (remainingPercent >= lowUsageThresholdPercent) {
|
|
1238
|
+
hasWarnedLowUsageRef.current = false;
|
|
1239
|
+
}
|
|
1240
|
+
else if (previousRemaining !== null
|
|
1241
|
+
&& resolvedRemaining < previousRemaining
|
|
1242
|
+
&& !hasWarnedLowUsageRef.current) {
|
|
1243
|
+
hasWarnedLowUsageRef.current = true;
|
|
1244
|
+
const warningText = typeof lowUsageWarningText === 'string'
|
|
1245
|
+
? lowUsageWarningText
|
|
1246
|
+
: {
|
|
1247
|
+
...lowUsageWarningText,
|
|
1248
|
+
values: {
|
|
1249
|
+
...(lowUsageWarningText.values || {}),
|
|
1250
|
+
count: resolvedRemaining,
|
|
1251
|
+
percent: remainingPercent,
|
|
1252
|
+
},
|
|
1253
|
+
};
|
|
1254
|
+
onLowUsageWarning?.({
|
|
1255
|
+
remaining: resolvedRemaining,
|
|
1256
|
+
percent: remainingPercent,
|
|
1257
|
+
limit,
|
|
1258
|
+
});
|
|
1259
|
+
showToast(resolveText(translate, warningText, `무료 사용량이 ${resolvedRemaining}회(${remainingPercent}%) 남았습니다.`) || `무료 사용량이 ${resolvedRemaining}회(${remainingPercent}%) 남았습니다.`, 'warning');
|
|
1260
|
+
}
|
|
1261
|
+
previousRemainingRef.current = resolvedRemaining;
|
|
1262
|
+
}, [
|
|
1263
|
+
lowUsageThresholdPercent,
|
|
1264
|
+
lowUsageWarningText,
|
|
1265
|
+
effectiveMaxDailyUsage,
|
|
1266
|
+
effectivePaymentStatus,
|
|
1267
|
+
onLowUsageWarning,
|
|
1268
|
+
remainingPercent,
|
|
1269
|
+
resolvedRemaining,
|
|
1270
|
+
showLowUsageWarning,
|
|
1271
|
+
showToast,
|
|
1272
|
+
translate,
|
|
1273
|
+
]);
|
|
1274
|
+
const classes = clsx('designbase-figma-footer', {
|
|
1275
|
+
'designbase-figma-footer--has-children': hasChildren,
|
|
1276
|
+
}, className);
|
|
1277
|
+
return (React.createElement("footer", { className: classes },
|
|
1278
|
+
React.createElement("div", { className: "designbase-figma-footer__wrap" },
|
|
1279
|
+
React.createElement("div", { className: "designbase-figma-footer__left" },
|
|
1280
|
+
React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, languages: languages, currentLanguage: currentLanguage, showLanguageSelector: showLanguageSelector, onLanguageChange: onLanguageChange, t: translate })),
|
|
1281
|
+
React.createElement("div", { className: "designbase-figma-footer__right" },
|
|
1282
|
+
(resolvedShowUsageInfo || resolvedShowPaymentBadge) && (React.createElement(UsageStatusPopover, { paymentStatus: effectivePaymentStatus, usageCount: effectiveUsageCount, remainingUsage: effectiveRemainingUsage, maxDailyUsage: effectiveMaxDailyUsage, showUsage: resolvedShowUsageInfo, showPlan: resolvedShowPaymentBadge, isLoading: isLoading, onLicensePageClick: resolvedLicensePageClick, t: translate })),
|
|
1283
|
+
showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: translate })))),
|
|
1284
|
+
children,
|
|
1285
|
+
toastComponent));
|
|
1286
|
+
};
|
|
1287
|
+
FigmaFooter.displayName = 'FigmaFooter';
|
|
1288
|
+
|
|
1168
1289
|
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' }, helperText, className, t, locale, }) => {
|
|
1169
1290
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
1170
1291
|
const [inputValue, setInputValue] = React.useState(value);
|