Refine SEO light theme and environment controls
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nodedc/ui-catalog",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -9,8 +9,8 @@
|
||||
"typecheck": "tsc -b --pretty false"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nodedc/ui-core": "0.5.0",
|
||||
"@nodedc/ui-react": "0.5.0",
|
||||
"@nodedc/ui-core": "0.5.1",
|
||||
"@nodedc/ui-react": "0.5.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
},
|
||||
|
||||
@@ -38,12 +38,7 @@ import {
|
||||
type ShareAccessMember,
|
||||
} from "@nodedc/ui-react";
|
||||
|
||||
type CatalogSection = "foundation" | "controls" | "media" | "windows" | "modals" | "inspector" | "icons";
|
||||
|
||||
const engineAccentStyle = {
|
||||
"--nodedc-accent-rgb": "255 47 146",
|
||||
"--nodedc-on-accent-rgb": "11 17 23",
|
||||
} as CSSProperties;
|
||||
type CatalogSection = "foundation" | "controls" | "media" | "windows" | "modals" | "icons";
|
||||
|
||||
const accents: Array<{ label: string; value: RgbTuple; hex: string }> = [
|
||||
{ label: "NODE.DC", value: [255, 47, 146], hex: "#ff2f92" },
|
||||
@@ -76,7 +71,7 @@ const sectionDefinitions: Record<CatalogSection, { eyebrow: string; title: strin
|
||||
controls: {
|
||||
eyebrow: "02 / CONTROLS",
|
||||
title: "Контролы",
|
||||
description: "Кнопки, поля, selection, Engine-настройки и понятные статусы операций.",
|
||||
description: "Кнопки, поля, выбор, Environment Settings и сворачиваемые секции нового Engine.",
|
||||
icon: "sliders",
|
||||
},
|
||||
media: {
|
||||
@@ -97,14 +92,8 @@ const sectionDefinitions: Record<CatalogSection, { eyebrow: string; title: strin
|
||||
description: "Полная карта modal-паттернов Launcher, нового Engine и BIM Viewer.",
|
||||
icon: "clipboard",
|
||||
},
|
||||
inspector: {
|
||||
eyebrow: "06 / INSPECTOR",
|
||||
title: "Инспектор",
|
||||
description: "Точный новый Engine Environment Settings без legacy-инспекторов.",
|
||||
icon: "settings",
|
||||
},
|
||||
icons: {
|
||||
eyebrow: "07 / ICONS",
|
||||
eyebrow: "06 / ICONS",
|
||||
title: "Иконки",
|
||||
description: "Канонический общий набор по Launcher, SEO, BIM Viewer и новым участкам Engine.",
|
||||
icon: "grid",
|
||||
@@ -232,7 +221,7 @@ export function CatalogApp() {
|
||||
const [fillColor, setFillColor] = useState("#ff6caf");
|
||||
const [strokeColor, setStrokeColor] = useState("#2b2b36");
|
||||
const [windowOpen, setWindowOpen] = useState(false);
|
||||
const [inspectorOpen, setInspectorOpen] = useState(false);
|
||||
const [sidePanelOpen, setSidePanelOpen] = useState(false);
|
||||
const [createModalOpen, setCreateModalOpen] = useState(false);
|
||||
const [confirmOpen, setConfirmOpen] = useState(false);
|
||||
const [shareAccessOpen, setShareAccessOpen] = useState(false);
|
||||
@@ -307,7 +296,7 @@ export function CatalogApp() {
|
||||
|
||||
const closeGuideline = workspace.closeNavigation;
|
||||
|
||||
const inspectorSections = [
|
||||
const environmentSections = [
|
||||
{
|
||||
id: "illumination",
|
||||
label: "Подсветка",
|
||||
@@ -384,7 +373,8 @@ export function CatalogApp() {
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<ColorField label="Свой accent" value={accentHex} onChange={setAccentHex} />
|
||||
<ColorField label="Акцент приложения" value={accentHex} onChange={setAccentHex} />
|
||||
<p className="catalog-preview__explanation">Акцент сразу перекрашивает environment-controls, активные действия, заливку range, file action и состояния окон. Геометрия и semantic-status при этом не меняются.</p>
|
||||
</Preview>
|
||||
<Preview title="Иерархия стекла" note="default / strong / soft">
|
||||
<div className="catalog-surface-stack">
|
||||
@@ -427,19 +417,17 @@ export function CatalogApp() {
|
||||
<Select label="Статус" value={selectedStatus} options={[...selectOptions]} searchable onChange={setSelectedStatus} />
|
||||
</FieldFrame>
|
||||
<FieldFrame label="Engine / split select">
|
||||
<div style={engineAccentStyle}>
|
||||
<Select
|
||||
variant="split"
|
||||
label="Тип связи"
|
||||
value={connectionType}
|
||||
options={[
|
||||
{ value: "spline", label: "Сплайн" },
|
||||
{ value: "straight", label: "Прямая" },
|
||||
{ value: "step", label: "Ступенчатая" },
|
||||
]}
|
||||
onChange={setConnectionType}
|
||||
/>
|
||||
</div>
|
||||
<Select
|
||||
variant="split"
|
||||
label="Тип связи"
|
||||
value={connectionType}
|
||||
options={[
|
||||
{ value: "spline", label: "Сплайн" },
|
||||
{ value: "straight", label: "Прямая" },
|
||||
{ value: "step", label: "Ступенчатая" },
|
||||
]}
|
||||
onChange={setConnectionType}
|
||||
/>
|
||||
</FieldFrame>
|
||||
<Dropdown
|
||||
trigger={({ open, toggle, setTriggerRef, surfaceId }) => (
|
||||
@@ -456,12 +444,13 @@ export function CatalogApp() {
|
||||
</Dropdown>
|
||||
</div>
|
||||
</Preview>
|
||||
<Preview title="Environment controls" note="точная геометрия Engine">
|
||||
<div className="catalog-engine-control-stack" style={engineAccentStyle}>
|
||||
<ControlRow label="Цвет"><ColorField value={lightColor} onChange={setLightColor} /></ControlRow>
|
||||
<RangeControl label="Яркость" value={brightness} min={0} max={100} formatValue={(value) => `${value}%`} onChange={setBrightness} />
|
||||
<Checker checked={checker} label="Использовать цвет портов" onChange={setChecker} />
|
||||
<ControlRow label="Применить ко всем"><Button variant="accent" shape="pill" width="full">Применить</Button></ControlRow>
|
||||
<Preview title="Environment controls" note="Engine / select + accordion" className="catalog-preview--wide">
|
||||
<div className="catalog-environment-demo">
|
||||
<GlassSurface tone="strong" radius="panel" className="catalog-environment-card">
|
||||
<div className="catalog-environment-title"><strong>Настройки окружения</strong><span>ENGINE / новый канон</span></div>
|
||||
<Inspector sections={environmentSections} defaultOpen={["illumination", "connections"]} />
|
||||
</GlassSurface>
|
||||
<p className="catalog-preview__explanation">Здесь собраны все контролы, которые нужны новым приложениям: color palette, range, checker, split-select, accent action и раскрывающиеся sections. Отдельной вкладки Inspector в каталоге больше нет.</p>
|
||||
</div>
|
||||
</Preview>
|
||||
<Preview title="Статусы операций" note="не цвет приложения" className="catalog-preview--wide">
|
||||
@@ -517,7 +506,7 @@ export function CatalogApp() {
|
||||
<p className="catalog-preview__explanation">Обычное окно блокирует фон и удерживает фокус. Правый инспектор не затемняет, не блокирует stage и не превращается в modal.</p>
|
||||
<div className="catalog-inline catalog-inline--wrap">
|
||||
<Button variant="accent" shape="pill" icon={<Icon name="apps" />} onClick={() => setWindowOpen(true)}>Открыть окно</Button>
|
||||
<Button shape="pill" icon={<Icon name="panel" />} onClick={() => setInspectorOpen(true)}>Открыть инспектор</Button>
|
||||
<Button shape="pill" icon={<Icon name="panel" />} onClick={() => setSidePanelOpen(true)}>Открыть боковую панель</Button>
|
||||
</div>
|
||||
</Preview>
|
||||
<Preview title="Оконные действия" note="круг `46 px`">
|
||||
@@ -563,15 +552,6 @@ export function CatalogApp() {
|
||||
</Preview>
|
||||
</div>
|
||||
);
|
||||
case "inspector":
|
||||
return (
|
||||
<div className="catalog-inspector-stage">
|
||||
<GlassSurface tone="strong" radius="panel" className="catalog-inspector-card" style={engineAccentStyle}>
|
||||
<div className="catalog-inspector-title"><strong>Настройки окружения</strong><span>ENGINE / новый канон</span></div>
|
||||
<Inspector sections={inspectorSections} defaultOpen={["illumination", "connections", "ports"]} />
|
||||
</GlassSurface>
|
||||
</div>
|
||||
);
|
||||
case "icons":
|
||||
return (
|
||||
<div className="catalog-icon-catalog">
|
||||
@@ -582,7 +562,7 @@ export function CatalogApp() {
|
||||
<IconButton label="Развернуть"><Icon name="expand" size={20} /></IconButton>
|
||||
<IconButton label="Закрыть"><Icon name="close" size={18} /></IconButton>
|
||||
</div>
|
||||
<p className="catalog-preview__explanation">Иконка наследует `currentColor`; фон, размер кнопки и active-state задаёт компонент поверхности, а не SVG.</p>
|
||||
<p className="catalog-preview__explanation">Иконка наследует `currentColor`; фон, размер кнопки и active-state задаёт компонент поверхности, а не SVG. Glyph оптически уменьшен на 18% без изменения hit target.</p>
|
||||
</Preview>
|
||||
{iconGroups.map((group) => (
|
||||
<section className="catalog-icon-group" key={group.title}>
|
||||
@@ -668,7 +648,7 @@ export function CatalogApp() {
|
||||
footer={
|
||||
<>
|
||||
<span className="nodedc-admin-panel__nav-icon" aria-hidden="true"><Icon name="shield" /></span>
|
||||
<span>Design System 0.5</span>
|
||||
<span>Design System 0.5.1</span>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
@@ -708,14 +688,16 @@ export function CatalogApp() {
|
||||
</Window>
|
||||
|
||||
<Window
|
||||
open={inspectorOpen}
|
||||
title="Настройки окружения"
|
||||
subtitle="ENGINE / новый канон"
|
||||
open={sidePanelOpen}
|
||||
title="Боковая панель"
|
||||
subtitle="modeless / shell contract"
|
||||
placement="end"
|
||||
style={engineAccentStyle}
|
||||
onClose={() => setInspectorOpen(false)}
|
||||
onClose={() => setSidePanelOpen(false)}
|
||||
>
|
||||
<Inspector sections={inspectorSections} defaultOpen={["illumination", "connections", "ports"]} />
|
||||
<div className="catalog-form">
|
||||
<TextField label="Название панели" value="Параметры рабочей области" readOnly />
|
||||
<p className="catalog-preview__explanation">Боковая панель демонстрирует только layer-механику: она modeless, не затемняет stage и не забирает фокус. Environment controls живут в разделе «Контролы».</p>
|
||||
</div>
|
||||
</Window>
|
||||
|
||||
<Window
|
||||
|
||||
+22
-17
@@ -14,7 +14,7 @@ body,
|
||||
}
|
||||
|
||||
body {
|
||||
background: #050506;
|
||||
background: var(--nodedc-canvas);
|
||||
color: var(--nodedc-text-primary);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ textarea {
|
||||
isolation: isolate;
|
||||
overflow: hidden;
|
||||
border-radius: var(--nodedc-radius-card);
|
||||
background: #0b0b0d url("/launcher-stage-poster.png") center / cover no-repeat;
|
||||
box-shadow: 0 44px 150px rgba(0, 0, 0, 0.62);
|
||||
background: var(--nodedc-canvas-soft) url("/launcher-stage-poster.png") center / cover no-repeat;
|
||||
box-shadow: 0 44px 150px color-mix(in srgb, var(--nodedc-canvas) 70%, transparent);
|
||||
}
|
||||
|
||||
.catalog-launcher-stage__media,
|
||||
@@ -229,7 +229,7 @@ textarea {
|
||||
grid-template-columns: minmax(12rem, 1.7fr) minmax(7rem, 0.7fr) minmax(6rem, 0.6fr) minmax(9rem, 0.9fr) 6rem;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-bottom: 1px solid var(--nodedc-glass-outline);
|
||||
color: var(--nodedc-text-secondary);
|
||||
padding: 0.62rem 0.8rem;
|
||||
font-size: var(--nodedc-font-size-sm);
|
||||
@@ -281,7 +281,7 @@ textarea {
|
||||
grid-template-rows: 3.2rem 1fr;
|
||||
gap: 0.6rem;
|
||||
border-radius: 1.1rem;
|
||||
background: rgba(0, 0, 0, 0.22);
|
||||
background: color-mix(in srgb, var(--nodedc-canvas-soft) 76%, transparent);
|
||||
padding: 0.6rem;
|
||||
}
|
||||
|
||||
@@ -307,30 +307,31 @@ textarea {
|
||||
background: color-mix(in srgb, var(--nodedc-glass-control-hover) 70%, transparent) !important;
|
||||
}
|
||||
|
||||
.catalog-inspector-stage {
|
||||
display: flex;
|
||||
min-height: 43rem;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
.catalog-environment-demo {
|
||||
display: grid;
|
||||
min-height: 30rem;
|
||||
grid-template-columns: minmax(0, 24.375rem) minmax(14rem, 1fr);
|
||||
align-items: start;
|
||||
gap: clamp(1rem, 4vw, 4rem);
|
||||
border-radius: var(--nodedc-radius-card);
|
||||
background:
|
||||
radial-gradient(circle at 18% 24%, rgba(var(--nodedc-accent-rgb), 0.13), transparent 22rem),
|
||||
color-mix(in srgb, var(--nodedc-canvas-soft) 86%, transparent);
|
||||
padding: 2rem;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
}
|
||||
|
||||
.catalog-inspector-card {
|
||||
.catalog-environment-card {
|
||||
width: min(24.375rem, 100%);
|
||||
padding: 1.125rem 0.75rem;
|
||||
}
|
||||
|
||||
.catalog-inspector-title {
|
||||
.catalog-environment-title {
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
padding: 0 0.875rem 0.875rem;
|
||||
}
|
||||
|
||||
.catalog-inspector-title span {
|
||||
.catalog-environment-title span {
|
||||
color: var(--nodedc-text-muted);
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
@@ -393,6 +394,10 @@ textarea {
|
||||
color: var(--nodedc-text-primary);
|
||||
}
|
||||
|
||||
.catalog-icon-tile__surface > svg {
|
||||
transform: scale(var(--nodedc-icon-glyph-scale));
|
||||
}
|
||||
|
||||
.catalog-icon-tile > span:last-child {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
@@ -499,9 +504,9 @@ textarea {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.catalog-inspector-stage {
|
||||
min-height: 40rem;
|
||||
justify-content: center;
|
||||
.catalog-environment-demo {
|
||||
min-height: auto;
|
||||
grid-template-columns: 1fr;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user