Stabilised basic functionalities after structured design recovery
Some checks failed
armco-org/Layout/pipeline/head There was a failure building this commit

This commit is contained in:
2025-11-14 00:41:52 +05:30
parent 0caeac2dc2
commit 5a86fea2ca
11 changed files with 86 additions and 36 deletions

8
package-lock.json generated
View File

@@ -10,7 +10,7 @@
"license": "ISC",
"dependencies": {
"@armco/icon": "^0.0.13",
"@armco/shared-components": "^0.0.60",
"@armco/shared-components": "^0.0.61",
"@armco/utils": "^0.0.31",
"bootstrap": "^5.3.8",
"react": ">16.8.0",
@@ -77,9 +77,9 @@
}
},
"node_modules/@armco/shared-components": {
"version": "0.0.60",
"resolved": "https://registry.npmjs.org/@armco/shared-components/-/shared-components-0.0.60.tgz",
"integrity": "sha512-Jr8sSrIq+YV3LVsPBrh8YZfTbINf7DHNl4kCSeKx/zueXPimINNz8n6Nd8yk++cp+bAjbhuZUX0hG2QLr8dSQA==",
"version": "0.0.61",
"resolved": "https://registry.npmjs.org/@armco/shared-components/-/shared-components-0.0.61.tgz",
"integrity": "sha512-Nuu5XL0kRwg2C82IiZOSPCnLUqborcyNKP4gulERGic28kduYeBZDSF6oYBKvNAkeGms77mxNGox+0SKJcyeTg==",
"license": "ISC",
"dependencies": {
"@armco/configs": "^0.0.15",

View File

@@ -15,7 +15,7 @@
},
"dependencies": {
"@armco/icon": "^0.0.13",
"@armco/shared-components": "^0.0.60",
"@armco/shared-components": "^0.0.61",
"@armco/utils": "^0.0.31",
"bootstrap": "^5.3.8",
"react": ">16.8.0",

View File

@@ -1,5 +1,5 @@
.ar-BuilderLayout.hide-controls {
> .ar-Layout__canvas > .ar-Layout__grid-tools {
.ar-BuilderLayout {
&.hide-controls > .ar-Layout__canvas > .ar-Layout__grid-tools {
grid-template: "grid" auto/auto;
}
.ar-Layout__help-panel {

View File

@@ -19,10 +19,9 @@ const BuilderLayout: FC<BuilderLayoutProps> = (props) => {
isChild,
mode,
slotDropHandler,
onSlotSelect,
slotRenderer,
} = props
const { layoutService, controlsEnabled } = useLayoutContext()
const { layoutService, eventsService, controlsEnabled } = useLayoutContext()
// From runtime: displayMode undefined or 'grid' => treat as grid layout
const isGridDisplay = !displayMode || displayMode === "grid"
@@ -50,7 +49,7 @@ const BuilderLayout: FC<BuilderLayoutProps> = (props) => {
layoutMode: mode,
mode: ArSlotViewMode.BUILD as const,
dropHandler: slotDropHandler,
onSlotSelect,
onClick: eventsService.selectSlot,
slotRenderer,
}
return slotRenderer ? (

View File

@@ -19,11 +19,11 @@ const BuilderLayoutContainer: FC<BuilderLayoutContainerProps> = ({ children, cla
if (controlPanelRef.current) {
controlPanelRef.current.style.bottom = containerRect.bottom + "px"
controlPanelRef.current.style.left = containerRect.left + "px"
controlPanelRef.current.style.width = containerRect.width + "px"
}
if (helpRef.current) {
helpRef.current.style.top = window.innerHeight - containerRect.top + "px"
helpRef.current.style.left = containerRect.left + "px"
helpRef.current.style.width = containerRect.width + "px"
}
setTimeout(() => {
const helpRect = helpRef.current?.getBoundingClientRect()

View File

@@ -16,8 +16,9 @@ const BuilderSlot = (props: BuilderSlotProps): JSX.Element => {
onClick,
...rest
} = props
const { controlsEnabled, selectionOnlyModeEnabled, eventsService } = useLayoutContext()
const { controlsEnabled, selectionOnlyModeEnabled } = useLayoutContext()
const [selected, setSelected] = useState<boolean>()
const [hovered, setHovered] = useState<boolean>(false)
const { mode = ArSlotViewMode.BUILD, slotDescriptor } = props
const slotRef = useRef<HTMLDivElement>(null)
const { slot, props: slotProps } = slotDescriptor
@@ -50,11 +51,13 @@ const BuilderSlot = (props: BuilderSlotProps): JSX.Element => {
setSelected(!selected)
onClick && onClick(slotDescriptor)
}}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
ref={slotRef}
{...slotRest}
>
{content}
{controlsEnabled && !selectionOnlyModeEnabled && (
{controlsEnabled && !selectionOnlyModeEnabled && hovered && (
<SlotTools {...rest} />
)}
</div>

View File

@@ -114,7 +114,7 @@ const LayoutControlPanel = forwardRef<HTMLDivElement, LayoutControlPanelProps>((
key={"layout-control-panel"}
>
{actionButton(theme, actions[0][0], actions[0][1], actions[0][2], actions[0][3])}
{layoutService.slots && (
{controlsEnabled && <>{layoutService.slots && (
<>
<span className="border-right mx-2" />
{actions.slice(1, 4).map((e, idx) =>
@@ -122,12 +122,13 @@ const LayoutControlPanel = forwardRef<HTMLDivElement, LayoutControlPanelProps>((
)}
</>
)}
<span className="border-right mx-2" />
{actions.slice(4, 10).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5]))}
<span className="border-right mx-2" />
{actions.slice(10, 12).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5]))}
<span className="border-right mx-2" />
{actions.slice(12).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5], e[6]))}
<span className="border-right mx-2" />
{actions.slice(4, 10).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5]))}
<span className="border-right mx-2" />
{actions.slice(10, 12).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5]))}
<span className="border-right mx-2" />
{actions.slice(12).map((e, idx) => actionButton(theme, e[0], e[1], e[2], e[3], e[4], e[5], e[6]))
}</>}
</div>
)
})

View File

@@ -7,6 +7,7 @@ import Icon from "@armco/icon"
type LayoutHelpProps = {
panelsDisplayed?: boolean
classes?: string
}
const keyBindings = [
@@ -35,7 +36,7 @@ const helpPoints = [
]
const LayoutHelp = forwardRef<HTMLDivElement, LayoutHelpProps>(
({ panelsDisplayed }, ref) => {
({ panelsDisplayed, classes }, ref) => {
const { theme } = useTheme()
const cmdIcon = useMemo(
() => (
@@ -46,13 +47,14 @@ const LayoutHelp = forwardRef<HTMLDivElement, LayoutHelpProps>(
),
[],
)
const fillColor = theme === ArThemes.DARK1 ? "black" : "white"
return (
<div
className={`ar-Layout__help-panel position-fixed overflow-hidden d-flex px-2 justify-content-between py-1${panelsDisplayed ? " show" : ""
}`}
}${classes ? " " + classes : ""}`}
ref={ref}
>
<span className="small fw-bold" style={{ color: theme === ArThemes.DARK1 ? "black" : "white" }}>
<span className="small fw-bold" style={{ color: fillColor }}>
Undo: Ctrl/Cmd + z, Redo: Ctrl/Cmd + y
</span>
<div>
@@ -60,7 +62,7 @@ const LayoutHelp = forwardRef<HTMLDivElement, LayoutHelpProps>(
<Icon
icon="fa.FaKeyboard"
slot={ArPopoverSlots.ANCHOR}
attributes={{ colors: { fillColor: "white" }, classes: "me-3" }}
attributes={{ colors: { fillColor }, classes: "me-3" }}
/>
<span slot={ArPopoverSlots.POPOVER} className="z-2">
{keyBindings.map((kb) => (
@@ -77,7 +79,7 @@ const LayoutHelp = forwardRef<HTMLDivElement, LayoutHelpProps>(
<Icon
icon="md.MdInfoOutline"
slot={ArPopoverSlots.ANCHOR}
attributes={{ colors: { fillColor: theme === ArThemes.DARK1 ? "black" : "white" } }}
attributes={{ colors: { fillColor } }}
/>
<span
className="ar-Layout__help-panel__help-content small z-2"

View File

@@ -7,15 +7,18 @@
}
}
.ar-Slot {
.build {
&.build {
&:hover {
border: 1px dashed #7d31f0 !important;
border: 1px solid #7d31f0 !important;
.ar-SlotTools {
display: flex;
}
}
&.selected {
border: 1px solid #86cff1 !important;
&:hover {
border: 1px solid #7d31f0 !important;
}
}
&.active {
outline: 4px solid #2e9cfd !important;
@@ -29,24 +32,29 @@
background-color: #55bdeda9;
}
}
.ar-SlotTools {
display: none;
}
}
.ar-SlotTools {
display: none;
}
.row-controller .ar-Slot__overlay-btn {
&.row-controller .ar-Slot__overlay-btn {
height: calc((100% - 16px) / 3);
&.delete {
height: 1rem;
}
}
.col-controller .ar-Slot__overlay-btn {
&.col-controller .ar-Slot__overlay-btn {
width: calc((100% - 16px) / 3);
&.delete {
width: 1rem;
}
}
.row-controller,
.col-controller {
&.row-controller,
&.col-controller {
&:hover {
.ar-SlotTools {
display: flex;
}
}
.ar-Slot__overlay-btn {
&.slot:hover {
background-color: #55bdeda9;

View File

@@ -1,8 +1,10 @@
import { useState } from "react"
import ReactDOM from "react-dom/client"
import { DndProvider } from "react-dnd"
import { HTML5Backend } from "react-dnd-html5-backend"
import { TouchBackend } from "react-dnd-touch-backend"
import { isMobile as checkMobile } from "@armco/utils/helper"
import { ArProvider } from "@armco/utils"
import Layout from "./Layout"
import "./test.scss"
@@ -11,4 +13,37 @@ const backend = isMobile ? TouchBackend : HTML5Backend
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement)
root.render(<div className="flex-center h-100 w-100 container"><DndProvider backend={backend}><Layout /></DndProvider></div>)
function formatGridTemplate(templateString: string) {
// 1. Normalize all whitespace in the string
let formatted = templateString.trim().replace(/\s+/g, ' ');
// 2. Replace the '/' separator with a newline and indentation
formatted = formatted.replace(' / ', '\n/ ');
// 3. Replace spaces that separate distinct *rows* or *column groups* with newlines
// This looks for a space that is immediately followed by a starting quote or the '/' character
formatted = formatted.replace(/\s+(?=["/])/g, '\n');
return formatted;
}
const LayoutWrapper = () => {
const [gridTemplate, setGridTemplate] = useState<string>("")
return <div className="d-flex h-100 w-100">
<div className="flex-center w-50 p-3">
<Layout onLayoutChange={(gridTemplate: string) => setGridTemplate(gridTemplate)} acceptTextOnClick />
</div>
<div className="bg-dark w-50 text-white p-4">
<strong className="mb-4 d-inline-block fs-4">GRID TEMPLATE</strong>
{gridTemplate && <pre className="custom-scrollbar p-1">{formatGridTemplate(gridTemplate)}</pre>}
</div>
</div>
}
root.render(<div className="flex-center h-100 w-100">
<ArProvider>
<DndProvider backend={backend}>
<LayoutWrapper />
</DndProvider>
</ArProvider>
</div>)

View File

@@ -19,7 +19,9 @@ export default defineConfig({
build: {
outDir: "build",
lib: {
entry: glob.sync(resolve(__dirname, "src/**/!(*.d).{ts,tsx}")),
entry: glob
.sync(resolve(__dirname, "src/**/!(*.d).{ts,tsx}"))
.filter((p) => !p.endsWith("Test.tsx")),
},
rollupOptions: {
treeshake: true,