@hai3/studio 0.1.0-alpha.1 → 0.2.0-alpha.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.cjs +117 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { I18nRegistry, Language, i18nRegistry, ScreensetCategory, eventBus, useTranslation,
|
|
1
|
+
import React4, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
|
|
2
|
+
import { I18nRegistry, Language, i18nRegistry, ScreensetCategory, eventBus, useTranslation, useNavigation, screensetRegistry, useTheme, getLanguageMetadata, LanguageDisplayMode, SUPPORTED_LANGUAGES, TextDirection, apiRegistry } from '@hai3/react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { Card, Button, ButtonSize, ButtonVariant, DropdownMenu, DropdownMenuTrigger, DropdownButton, DropdownMenuContent, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuItem, Switch } from '@hai3/uikit';
|
|
5
5
|
import { clamp, upperFirst } from 'lodash';
|
|
6
|
-
import { ButtonVariant as ButtonVariant$1 } from '@hai3/uikit-contracts';
|
|
7
6
|
|
|
8
7
|
var __create = Object.create;
|
|
9
8
|
var __defProp = Object.defineProperty;
|
|
@@ -1052,25 +1051,23 @@ var useResizable = () => {
|
|
|
1052
1051
|
var ThemeSelector = ({
|
|
1053
1052
|
className = ""
|
|
1054
1053
|
}) => {
|
|
1055
|
-
const
|
|
1056
|
-
const currentTheme = useAppSelector((state) => state.uicore.layout.theme);
|
|
1054
|
+
const { currentTheme, themes, setTheme } = useTheme();
|
|
1057
1055
|
const { portalContainer } = useStudioContext();
|
|
1058
1056
|
const { t } = useTranslation();
|
|
1059
1057
|
const formatThemeName = (themeName) => {
|
|
1060
1058
|
return themeName.split("-").map((word) => upperFirst(word)).join(" ");
|
|
1061
1059
|
};
|
|
1062
|
-
const availableThemes = themeRegistry.getThemeNames();
|
|
1063
1060
|
return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
|
|
1064
1061
|
/* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.theme") }),
|
|
1065
1062
|
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
1066
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant
|
|
1067
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children:
|
|
1063
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant.Outline, children: formatThemeName(currentTheme || "") }) }),
|
|
1064
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: themes.map((theme) => /* @__PURE__ */ jsx(
|
|
1068
1065
|
DropdownMenuItem,
|
|
1069
1066
|
{
|
|
1070
|
-
onClick: () =>
|
|
1071
|
-
children: formatThemeName(
|
|
1067
|
+
onClick: () => setTheme(theme.id),
|
|
1068
|
+
children: formatThemeName(theme.name || theme.id)
|
|
1072
1069
|
},
|
|
1073
|
-
|
|
1070
|
+
theme.id
|
|
1074
1071
|
)) })
|
|
1075
1072
|
] })
|
|
1076
1073
|
] });
|
|
@@ -1083,7 +1080,7 @@ var ScreensetSelector = ({
|
|
|
1083
1080
|
className = ""
|
|
1084
1081
|
}) => {
|
|
1085
1082
|
const { portalContainer } = useStudioContext();
|
|
1086
|
-
const { t,
|
|
1083
|
+
const { t, isRTL } = useTranslation();
|
|
1087
1084
|
const formatName = (name) => {
|
|
1088
1085
|
return name.split(/[-_]/).map((word) => upperFirst(word)).join(" ");
|
|
1089
1086
|
};
|
|
@@ -1099,8 +1096,8 @@ var ScreensetSelector = ({
|
|
|
1099
1096
|
};
|
|
1100
1097
|
return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
|
|
1101
1098
|
/* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.screenset") }),
|
|
1102
|
-
/* @__PURE__ */ jsxs(DropdownMenu, { dir:
|
|
1103
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant
|
|
1099
|
+
/* @__PURE__ */ jsxs(DropdownMenu, { dir: isRTL ? "rtl" : "ltr", children: [
|
|
1100
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant.Outline, children: formatName(getCurrentDisplay()) }) }),
|
|
1104
1101
|
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: options.map((categoryGroup) => /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
1105
1102
|
/* @__PURE__ */ jsx(DropdownMenuSubTrigger, { disabled: categoryGroup.screensets.length === 0, children: formatName(categoryGroup.category) }),
|
|
1106
1103
|
/* @__PURE__ */ jsx(DropdownMenuSubContent, { container: portalContainer, className: "z-[99999] pointer-events-auto", children: categoryGroup.screensets.map((item) => /* @__PURE__ */ jsx(
|
|
@@ -1121,18 +1118,17 @@ var RTL_INDICATOR_SUFFIX = " (RTL)";
|
|
|
1121
1118
|
function LanguageSelector({
|
|
1122
1119
|
displayMode = LanguageDisplayMode.Native
|
|
1123
1120
|
} = {}) {
|
|
1124
|
-
const { t, language,
|
|
1121
|
+
const { t, language, setLanguage } = useTranslation();
|
|
1125
1122
|
const { portalContainer } = useStudioContext();
|
|
1126
|
-
const
|
|
1127
|
-
const currentLanguage = languages.find((lang) => lang.code === language);
|
|
1123
|
+
const currentLanguage = language ? getLanguageMetadata(language) : null;
|
|
1128
1124
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1129
1125
|
/* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.language") }),
|
|
1130
1126
|
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
1131
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: ButtonVariant
|
|
1132
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children:
|
|
1127
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: ButtonVariant.Outline, children: currentLanguage ? displayMode === LanguageDisplayMode.Native ? currentLanguage.name : currentLanguage.englishName : FALLBACK_SELECT_LANGUAGE_TEXT }) }),
|
|
1128
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: SUPPORTED_LANGUAGES.map((lang) => /* @__PURE__ */ jsxs(
|
|
1133
1129
|
DropdownMenuItem,
|
|
1134
1130
|
{
|
|
1135
|
-
onClick: () =>
|
|
1131
|
+
onClick: () => setLanguage(lang.code),
|
|
1136
1132
|
children: [
|
|
1137
1133
|
displayMode === LanguageDisplayMode.Native ? lang.name : lang.englishName,
|
|
1138
1134
|
lang.direction === TextDirection.RightToLeft && RTL_INDICATOR_SUFFIX
|
|
@@ -1144,8 +1140,12 @@ function LanguageSelector({
|
|
|
1144
1140
|
] });
|
|
1145
1141
|
}
|
|
1146
1142
|
var ApiModeToggle = ({ className }) => {
|
|
1147
|
-
const useMockApi =
|
|
1143
|
+
const [useMockApi, setUseMockApi] = useState(true);
|
|
1148
1144
|
const { t } = useTranslation();
|
|
1145
|
+
const handleToggle = (checked) => {
|
|
1146
|
+
setUseMockApi(checked);
|
|
1147
|
+
apiRegistry.setMockMode(checked);
|
|
1148
|
+
};
|
|
1149
1149
|
return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between h-9 ${className}`, children: [
|
|
1150
1150
|
/* @__PURE__ */ jsx(
|
|
1151
1151
|
"label",
|
|
@@ -1160,7 +1160,7 @@ var ApiModeToggle = ({ className }) => {
|
|
|
1160
1160
|
{
|
|
1161
1161
|
id: "api-mode-toggle",
|
|
1162
1162
|
checked: useMockApi,
|
|
1163
|
-
onCheckedChange:
|
|
1163
|
+
onCheckedChange: handleToggle
|
|
1164
1164
|
}
|
|
1165
1165
|
)
|
|
1166
1166
|
] });
|
|
@@ -1168,20 +1168,35 @@ var ApiModeToggle = ({ className }) => {
|
|
|
1168
1168
|
ApiModeToggle.displayName = "ApiModeToggle";
|
|
1169
1169
|
var ALL_CATEGORIES = [ScreensetCategory.Drafts, ScreensetCategory.Mockups, ScreensetCategory.Production];
|
|
1170
1170
|
var buildScreensetOptions = () => {
|
|
1171
|
+
const allScreensets = screensetRegistry.getAll();
|
|
1171
1172
|
return ALL_CATEGORIES.map((category) => ({
|
|
1172
1173
|
category,
|
|
1173
|
-
screensets:
|
|
1174
|
+
screensets: allScreensets.filter((s) => s.category === category).map((s) => ({
|
|
1175
|
+
id: s.id,
|
|
1176
|
+
name: s.name
|
|
1177
|
+
}))
|
|
1174
1178
|
}));
|
|
1175
1179
|
};
|
|
1176
1180
|
var ControlPanel = () => {
|
|
1177
|
-
const
|
|
1178
|
-
const currentScreenset = useAppSelector((state) => state.uicore.layout.currentScreenset);
|
|
1181
|
+
const { currentScreenset, navigateToScreenset } = useNavigation();
|
|
1179
1182
|
const [screensetOptions, setScreensetOptions] = useState([]);
|
|
1180
1183
|
const { t } = useTranslation();
|
|
1181
1184
|
useEffect(() => {
|
|
1182
1185
|
const options = buildScreensetOptions();
|
|
1183
1186
|
setScreensetOptions(options);
|
|
1184
1187
|
}, []);
|
|
1188
|
+
const getCurrentValue = () => {
|
|
1189
|
+
if (!currentScreenset) return "";
|
|
1190
|
+
const screenset = screensetRegistry.get(currentScreenset);
|
|
1191
|
+
if (!screenset) return "";
|
|
1192
|
+
return `${screenset.category}:${screenset.id}`;
|
|
1193
|
+
};
|
|
1194
|
+
const handleScreensetChange = (value) => {
|
|
1195
|
+
const [, screensetId] = value.split(":");
|
|
1196
|
+
if (screensetId) {
|
|
1197
|
+
navigateToScreenset(screensetId);
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1185
1200
|
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1186
1201
|
/* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("studio:controls.heading") }),
|
|
1187
1202
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
@@ -1189,8 +1204,8 @@ var ControlPanel = () => {
|
|
|
1189
1204
|
ScreensetSelector,
|
|
1190
1205
|
{
|
|
1191
1206
|
options: screensetOptions,
|
|
1192
|
-
currentValue:
|
|
1193
|
-
onChange:
|
|
1207
|
+
currentValue: getCurrentValue(),
|
|
1208
|
+
onChange: handleScreensetChange
|
|
1194
1209
|
}
|
|
1195
1210
|
),
|
|
1196
1211
|
/* @__PURE__ */ jsx(ApiModeToggle, {}),
|
|
@@ -1203,13 +1218,13 @@ ControlPanel.displayName = "ControlPanel";
|
|
|
1203
1218
|
var StudioPanel = () => {
|
|
1204
1219
|
const { toggleCollapsed, setPortalContainer } = useStudioContext();
|
|
1205
1220
|
const { t } = useTranslation();
|
|
1206
|
-
const portalRef =
|
|
1221
|
+
const portalRef = React4.useRef(null);
|
|
1207
1222
|
const { size, handleMouseDown: handleResizeMouseDown } = useResizable();
|
|
1208
1223
|
const { position, isDragging, handleMouseDown: handleDragMouseDown } = useDraggable({
|
|
1209
1224
|
panelSize: size,
|
|
1210
1225
|
storageKey: STORAGE_KEYS.POSITION
|
|
1211
1226
|
});
|
|
1212
|
-
|
|
1227
|
+
React4.useEffect(() => {
|
|
1213
1228
|
setPortalContainer(portalRef.current);
|
|
1214
1229
|
return () => setPortalContainer(null);
|
|
1215
1230
|
}, [setPortalContainer]);
|