@aglyn/besigner-ui 1.0.0-beta.181 → 1.0.0-beta.183

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/besigner-ui",
3
- "version": "1.0.0-beta.181",
3
+ "version": "1.0.0-beta.183",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,22 +25,22 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/aglyn": "1.0.0-beta.181",
29
- "@aglyn/aglyn-markdown-editor": "1.0.0-beta.181",
30
- "@aglyn/aglyn-node-renderer": "1.0.0-beta.181",
31
- "@aglyn/besigner": "1.0.0-beta.181",
32
- "@aglyn/shared-data-enums": "1.0.0-beta.181",
33
- "@aglyn/shared-data-mdi": "1.0.0-beta.181",
34
- "@aglyn/shared-data-types": "1.0.0-beta.181",
35
- "@aglyn/shared-svg-icons": "1.0.0-beta.181",
36
- "@aglyn/shared-ui-json-editor": "1.0.0-beta.181",
37
- "@aglyn/shared-ui-jsx": "1.0.0-beta.181",
38
- "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.181",
39
- "@aglyn/shared-ui-snackstack": "1.0.0-beta.181",
40
- "@aglyn/shared-ui-theme": "1.0.0-beta.181",
41
- "@aglyn/shared-util-dom": "1.0.0-beta.181",
42
- "@aglyn/shared-util-tools": "1.0.0-beta.181",
43
- "@aglyn/shared-util-vendor": "1.0.0-beta.181",
28
+ "@aglyn/aglyn": "1.0.0-beta.183",
29
+ "@aglyn/aglyn-markdown-editor": "1.0.0-beta.183",
30
+ "@aglyn/aglyn-node-renderer": "1.0.0-beta.183",
31
+ "@aglyn/besigner": "1.0.0-beta.183",
32
+ "@aglyn/shared-data-enums": "1.0.0-beta.183",
33
+ "@aglyn/shared-data-mdi": "1.0.0-beta.183",
34
+ "@aglyn/shared-data-types": "1.0.0-beta.183",
35
+ "@aglyn/shared-svg-icons": "1.0.0-beta.183",
36
+ "@aglyn/shared-ui-json-editor": "1.0.0-beta.183",
37
+ "@aglyn/shared-ui-jsx": "1.0.0-beta.183",
38
+ "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.183",
39
+ "@aglyn/shared-ui-snackstack": "1.0.0-beta.183",
40
+ "@aglyn/shared-ui-theme": "1.0.0-beta.183",
41
+ "@aglyn/shared-util-dom": "1.0.0-beta.183",
42
+ "@aglyn/shared-util-tools": "1.0.0-beta.183",
43
+ "@aglyn/shared-util-vendor": "1.0.0-beta.183",
44
44
  "@dnd-kit/core": "^6.3.1",
45
45
  "@dnd-kit/utilities": "^3.2.2",
46
46
  "@react-aria/utils": "^3.34.1",
@@ -15,7 +15,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
15
15
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
- */ import { REUSABLE_COMPONENT_CATEGORY } from "@aglyn/aglyn";
18
+ */ import { REUSABLE_COMPONENT_CATEGORY, REUSABLE_EMAIL_BLOCK_CATEGORY } from "@aglyn/aglyn";
19
19
  import { DragType } from "@aglyn/besigner";
20
20
  import { mergeRefs } from "@aglyn/shared-ui-jsx";
21
21
  import { DragOverlay, useDndMonitor } from "@dnd-kit/core";
@@ -127,6 +127,11 @@ export const ComponentAccordionList = observer((props)=>{
127
127
  title: 'Your components',
128
128
  excerpt: 'Sections you promoted into reusable components. Drop one to place an instance — edit the component once and every instance follows.',
129
129
  href: besignerDocsUrl('reusableComponents', '#insert-instances')
130
+ } : // is just as empty until the site saves a block for it.
131
+ (item == null ? void 0 : item.$id) === REUSABLE_EMAIL_BLOCK_CATEGORY ? {
132
+ title: REUSABLE_EMAIL_BLOCK_CATEGORY,
133
+ excerpt: 'Headers, footers and other blocks you saved for emails. Drop one into this email — change the block once and every email using it follows.',
134
+ href: besignerDocsUrl('reusableComponents', '#reusable-email-blocks')
130
135
  } : undefined,
131
136
  onRenderSummary: ({ item })=>/*#__PURE__*/ _jsx(Observer, {
132
137
  children: ()=>/*#__PURE__*/ _jsx(_Fragment, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/component-accordion-list.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { REUSABLE_COMPONENT_CATEGORY } from '@aglyn/aglyn'\nimport { DragType } from '@aglyn/besigner'\nimport { mergeRefs } from '@aglyn/shared-ui-jsx'\nimport { DragOverlay, useDndMonitor } from '@dnd-kit/core'\nimport { Box, Grid, Stack } from '@mui/material'\nimport { Observer, observer } from 'mobx-react-lite'\nimport { useEffect } from 'react'\nimport { useElementDrawerContext } from '../contexts/element-drawer-context'\nimport useDetailHoverIntent from '../hooks/use-detail-hover-intent'\nimport usePickerFilter from '../hooks/use-picker-filter'\nimport useVisibleComponentCategories from '../hooks/use-visible-component-categories'\nimport { besignerDocsUrl } from '../utils/docs-help'\nimport { AccordionListComponent } from './accordion-list.component'\nimport Draggable from './dnd/draggable'\nimport ElementDetailOverlay from './element-detail-overlay.component'\nimport EmptyResults from './empty-results'\nimport NodeCard, { type NodeCardItemData } from './node-card'\nimport PickerSearchField from './picker-search-field'\n\nexport type ComponentGridGroupItemData = {\n $id: string\n label: string\n items: NodeCardItemData[]\n}\n\nNodeCard.displayName = 'NodeCard'\n\ninterface ComponentAccordionListProp {}\n\nexport const ComponentAccordionList = observer(\n (props: ComponentAccordionListProp) => {\n const { ...rest } = props\n const allItems = useVisibleComponentCategories()\n\n // The SAME search the Choose-element dialog runs (AGL-2486). The panel\n // had no search at all; giving it a second implementation would mean two\n // pickers disagreeing about what `icon` matches, which is worse than one\n // of them having none.\n const { filter, items, handleFilterChange } = usePickerFilter(allItems)\n\n // Hover previews, click PINS, and the pin outranks the pointer — which\n // is what makes the floating panel clickable at all. See\n // `useDetailHoverIntent` for why each half is load-bearing.\n const detail = useDetailHoverIntent<NodeCardItemData>()\n\n // The panel floats over the CANVAS, which is exactly where a dragged\n // element is going. It leaves the drop path on drag START — waiting for\n // the drop would leave it sitting under the pointer for the whole\n // gesture — and stays suspended until the drag ends so the cards the\n // pointer crosses on the way out cannot re-open it.\n useDndMonitor({\n onDragStart: detail.suspend,\n onDragEnd: detail.resume,\n onDragCancel: detail.resume,\n })\n\n // A modal opening over the panel is a context change, and a pinned\n // detail has no business outliving it.\n const drawerOpen = useElementDrawerContext()?.open\n useEffect(() => {\n if (drawerOpen) detail.dismiss()\n }, [drawerOpen, detail])\n\n return (\n <Stack sx={{ height: 1, minHeight: 0 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1,\n py: 0.5,\n borderBottom: 1,\n borderColor: 'divider',\n // The panel is a scrolling column; the search must stay reachable\n // without scrolling back to the top of ~45 elements.\n position: 'sticky',\n top: 0,\n zIndex: 6,\n backgroundColor: 'surface.main',\n }}\n >\n <PickerSearchField value={filter} onChange={handleFilterChange} />\n </Box>\n {!items?.length ? (\n <EmptyResults sx={{ minHeight: 200 }} />\n ) : (\n // The grid scrolls; the detail region below it does not, so the\n // description stays put while you browse.\n // Scrolling moves the card the panel is anchored to, so a pinned\n // panel would end up pointing at whatever slid into its place.\n <Box\n sx={{ flex: 1, minHeight: 0, overflowY: 'auto' }}\n onScroll={detail.dismiss}\n >\n <AccordionListComponent\n // No `key` remount to force the results group open (AGL-2486).\n // Keying on the filter flipped one render too EARLY — the query\n // changes synchronously, the results group only exists after\n // fuse.js loads — so the remount reseeded from the categories\n // and the group that arrived next was collapsed. The list now\n // opens a group when it first appears, which is the same render\n // the group actually exists in.\n items={items}\n defaultExpanded={items.map((i) => i.$id)}\n getItemId={(item) => item?.$id}\n // Only the host's own components group carries help (AGL-2167).\n // The built-in groups are self-evident from their contents; this one\n // is the only group whose items the user has to CREATE before it\n // holds anything, and an empty-looking group explains nothing.\n getItemHelp={(item) =>\n item?.$id === REUSABLE_COMPONENT_CATEGORY\n ? {\n title: 'Your components',\n excerpt:\n 'Sections you promoted into reusable components. Drop one to place an instance — edit the component once and every instance follows.',\n href: besignerDocsUrl(\n 'reusableComponents',\n '#insert-instances',\n ),\n }\n : undefined\n }\n onRenderSummary={({ item }) => (\n <Observer>{() => <>{item?.label}</>}</Observer>\n )}\n AccordionDetailsProps={{\n sx: { overflowX: 'hidden' },\n }}\n onRenderDetail={({ item }) => (\n <Observer>\n {() => (\n <Box>\n <Grid spacing={2} container sx={{ overflowX: 'hidden' }}>\n {item?.items?.map((node, index) => (\n <Grid\n key={node?.$id ?? index}\n size={6}\n onMouseEnter={(e) =>\n detail.open(node, e.currentTarget as HTMLElement)\n }\n onMouseLeave={detail.scheduleClose}\n onClick={(e) =>\n detail.togglePin(\n node,\n e.currentTarget as HTMLElement,\n )\n }\n >\n <Draggable\n node={node}\n type={DragType.PRESET}\n idSuffix={item?.$id}\n >\n {({ draggable, node, forwardRef }) => (\n <>\n <NodeCard\n ref={mergeRefs(\n forwardRef,\n draggable.setNodeRef,\n )}\n node={node as any}\n style={\n draggable.isDragging\n ? { opacity: 0.5 }\n : {}\n }\n {...draggable.listeners}\n />\n <DragOverlay dropAnimation={null}>\n {draggable.isDragging && (\n <NodeCard\n node={node as any}\n sx={{ zIndex: 9999 }}\n />\n )}\n </DragOverlay>\n </>\n )}\n </Draggable>\n </Grid>\n ))}\n </Grid>\n </Box>\n )}\n </Observer>\n )}\n {...rest}\n />\n </Box>\n )}\n <ElementDetailOverlay\n item={detail.active?.item}\n anchor={detail.active?.anchor ?? null}\n pinned={detail.isPinned}\n onPointerEnter={detail.keepOpen}\n onPointerLeave={detail.scheduleClose}\n onDismiss={detail.dismiss}\n />\n </Stack>\n )\n },\n)\nComponentAccordionList.displayName = 'ComponentAccordionList'\n\nexport default ComponentAccordionList\n"],"names":["REUSABLE_COMPONENT_CATEGORY","DragType","mergeRefs","DragOverlay","useDndMonitor","Box","Grid","Stack","Observer","observer","useEffect","useElementDrawerContext","useDetailHoverIntent","usePickerFilter","useVisibleComponentCategories","besignerDocsUrl","AccordionListComponent","Draggable","ElementDetailOverlay","EmptyResults","NodeCard","PickerSearchField","displayName","ComponentAccordionList","props","detail","rest","allItems","filter","items","handleFilterChange","onDragStart","suspend","onDragEnd","resume","onDragCancel","drawerOpen","open","dismiss","sx","height","minHeight","display","alignItems","px","py","borderBottom","borderColor","position","top","zIndex","backgroundColor","value","onChange","length","flex","overflowY","onScroll","defaultExpanded","map","i","$id","getItemId","item","getItemHelp","title","excerpt","href","undefined","onRenderSummary","label","AccordionDetailsProps","overflowX","onRenderDetail","spacing","container","node","index","size","onMouseEnter","e","currentTarget","onMouseLeave","scheduleClose","onClick","togglePin","type","PRESET","idSuffix","draggable","forwardRef","ref","setNodeRef","style","isDragging","opacity","listeners","dropAnimation","active","anchor","pinned","isPinned","onPointerEnter","keepOpen","onPointerLeave","onDismiss"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/component-accordion-list.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n REUSABLE_COMPONENT_CATEGORY,\n REUSABLE_EMAIL_BLOCK_CATEGORY,\n} from '@aglyn/aglyn'\nimport { DragType } from '@aglyn/besigner'\nimport { mergeRefs } from '@aglyn/shared-ui-jsx'\nimport { DragOverlay, useDndMonitor } from '@dnd-kit/core'\nimport { Box, Grid, Stack } from '@mui/material'\nimport { Observer, observer } from 'mobx-react-lite'\nimport { useEffect } from 'react'\nimport { useElementDrawerContext } from '../contexts/element-drawer-context'\nimport useDetailHoverIntent from '../hooks/use-detail-hover-intent'\nimport usePickerFilter from '../hooks/use-picker-filter'\nimport useVisibleComponentCategories from '../hooks/use-visible-component-categories'\nimport { besignerDocsUrl } from '../utils/docs-help'\nimport { AccordionListComponent } from './accordion-list.component'\nimport Draggable from './dnd/draggable'\nimport ElementDetailOverlay from './element-detail-overlay.component'\nimport EmptyResults from './empty-results'\nimport NodeCard, { type NodeCardItemData } from './node-card'\nimport PickerSearchField from './picker-search-field'\n\nexport type ComponentGridGroupItemData = {\n $id: string\n label: string\n items: NodeCardItemData[]\n}\n\nNodeCard.displayName = 'NodeCard'\n\ninterface ComponentAccordionListProp {}\n\nexport const ComponentAccordionList = observer(\n (props: ComponentAccordionListProp) => {\n const { ...rest } = props\n const allItems = useVisibleComponentCategories()\n\n // The SAME search the Choose-element dialog runs (AGL-2486). The panel\n // had no search at all; giving it a second implementation would mean two\n // pickers disagreeing about what `icon` matches, which is worse than one\n // of them having none.\n const { filter, items, handleFilterChange } = usePickerFilter(allItems)\n\n // Hover previews, click PINS, and the pin outranks the pointer — which\n // is what makes the floating panel clickable at all. See\n // `useDetailHoverIntent` for why each half is load-bearing.\n const detail = useDetailHoverIntent<NodeCardItemData>()\n\n // The panel floats over the CANVAS, which is exactly where a dragged\n // element is going. It leaves the drop path on drag START — waiting for\n // the drop would leave it sitting under the pointer for the whole\n // gesture — and stays suspended until the drag ends so the cards the\n // pointer crosses on the way out cannot re-open it.\n useDndMonitor({\n onDragStart: detail.suspend,\n onDragEnd: detail.resume,\n onDragCancel: detail.resume,\n })\n\n // A modal opening over the panel is a context change, and a pinned\n // detail has no business outliving it.\n const drawerOpen = useElementDrawerContext()?.open\n useEffect(() => {\n if (drawerOpen) detail.dismiss()\n }, [drawerOpen, detail])\n\n return (\n <Stack sx={{ height: 1, minHeight: 0 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1,\n py: 0.5,\n borderBottom: 1,\n borderColor: 'divider',\n // The panel is a scrolling column; the search must stay reachable\n // without scrolling back to the top of ~45 elements.\n position: 'sticky',\n top: 0,\n zIndex: 6,\n backgroundColor: 'surface.main',\n }}\n >\n <PickerSearchField value={filter} onChange={handleFilterChange} />\n </Box>\n {!items?.length ? (\n <EmptyResults sx={{ minHeight: 200 }} />\n ) : (\n // The grid scrolls; the detail region below it does not, so the\n // description stays put while you browse.\n // Scrolling moves the card the panel is anchored to, so a pinned\n // panel would end up pointing at whatever slid into its place.\n <Box\n sx={{ flex: 1, minHeight: 0, overflowY: 'auto' }}\n onScroll={detail.dismiss}\n >\n <AccordionListComponent\n // No `key` remount to force the results group open (AGL-2486).\n // Keying on the filter flipped one render too EARLY — the query\n // changes synchronously, the results group only exists after\n // fuse.js loads — so the remount reseeded from the categories\n // and the group that arrived next was collapsed. The list now\n // opens a group when it first appears, which is the same render\n // the group actually exists in.\n items={items}\n defaultExpanded={items.map((i) => i.$id)}\n getItemId={(item) => item?.$id}\n // Only the host's own components group carries help (AGL-2167).\n // The built-in groups are self-evident from their contents; this one\n // is the only group whose items the user has to CREATE before it\n // holds anything, and an empty-looking group explains nothing.\n getItemHelp={(item) =>\n item?.$id === REUSABLE_COMPONENT_CATEGORY\n ? {\n title: 'Your components',\n excerpt:\n 'Sections you promoted into reusable components. Drop one to place an instance — edit the component once and every instance follows.',\n href: besignerDocsUrl(\n 'reusableComponents',\n '#insert-instances',\n ),\n }\n : // The same group in an email's drawer (AGL-3287), which\n // is just as empty until the site saves a block for it.\n item?.$id === REUSABLE_EMAIL_BLOCK_CATEGORY\n ? {\n title: REUSABLE_EMAIL_BLOCK_CATEGORY,\n excerpt:\n 'Headers, footers and other blocks you saved for emails. Drop one into this email — change the block once and every email using it follows.',\n href: besignerDocsUrl(\n 'reusableComponents',\n '#reusable-email-blocks',\n ),\n }\n : undefined\n }\n onRenderSummary={({ item }) => (\n <Observer>{() => <>{item?.label}</>}</Observer>\n )}\n AccordionDetailsProps={{\n sx: { overflowX: 'hidden' },\n }}\n onRenderDetail={({ item }) => (\n <Observer>\n {() => (\n <Box>\n <Grid spacing={2} container sx={{ overflowX: 'hidden' }}>\n {item?.items?.map((node, index) => (\n <Grid\n key={node?.$id ?? index}\n size={6}\n onMouseEnter={(e) =>\n detail.open(node, e.currentTarget as HTMLElement)\n }\n onMouseLeave={detail.scheduleClose}\n onClick={(e) =>\n detail.togglePin(\n node,\n e.currentTarget as HTMLElement,\n )\n }\n >\n <Draggable\n node={node}\n type={DragType.PRESET}\n idSuffix={item?.$id}\n >\n {({ draggable, node, forwardRef }) => (\n <>\n <NodeCard\n ref={mergeRefs(\n forwardRef,\n draggable.setNodeRef,\n )}\n node={node as any}\n style={\n draggable.isDragging\n ? { opacity: 0.5 }\n : {}\n }\n {...draggable.listeners}\n />\n <DragOverlay dropAnimation={null}>\n {draggable.isDragging && (\n <NodeCard\n node={node as any}\n sx={{ zIndex: 9999 }}\n />\n )}\n </DragOverlay>\n </>\n )}\n </Draggable>\n </Grid>\n ))}\n </Grid>\n </Box>\n )}\n </Observer>\n )}\n {...rest}\n />\n </Box>\n )}\n <ElementDetailOverlay\n item={detail.active?.item}\n anchor={detail.active?.anchor ?? null}\n pinned={detail.isPinned}\n onPointerEnter={detail.keepOpen}\n onPointerLeave={detail.scheduleClose}\n onDismiss={detail.dismiss}\n />\n </Stack>\n )\n },\n)\nComponentAccordionList.displayName = 'ComponentAccordionList'\n\nexport default ComponentAccordionList\n"],"names":["REUSABLE_COMPONENT_CATEGORY","REUSABLE_EMAIL_BLOCK_CATEGORY","DragType","mergeRefs","DragOverlay","useDndMonitor","Box","Grid","Stack","Observer","observer","useEffect","useElementDrawerContext","useDetailHoverIntent","usePickerFilter","useVisibleComponentCategories","besignerDocsUrl","AccordionListComponent","Draggable","ElementDetailOverlay","EmptyResults","NodeCard","PickerSearchField","displayName","ComponentAccordionList","props","detail","rest","allItems","filter","items","handleFilterChange","onDragStart","suspend","onDragEnd","resume","onDragCancel","drawerOpen","open","dismiss","sx","height","minHeight","display","alignItems","px","py","borderBottom","borderColor","position","top","zIndex","backgroundColor","value","onChange","length","flex","overflowY","onScroll","defaultExpanded","map","i","$id","getItemId","item","getItemHelp","title","excerpt","href","undefined","onRenderSummary","label","AccordionDetailsProps","overflowX","onRenderDetail","spacing","container","node","index","size","onMouseEnter","e","currentTarget","onMouseLeave","scheduleClose","onClick","togglePin","type","PRESET","idSuffix","draggable","forwardRef","ref","setNodeRef","style","isDragging","opacity","listeners","dropAnimation","active","anchor","pinned","isPinned","onPointerEnter","keepOpen","onPointerLeave","onDismiss"],"mappings":";;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,2BAA2B,EAC3BC,6BAA6B,QACxB,eAAc;AACrB,SAASC,QAAQ,QAAQ,kBAAiB;AAC1C,SAASC,SAAS,QAAQ,uBAAsB;AAChD,SAASC,WAAW,EAAEC,aAAa,QAAQ,gBAAe;AAC1D,SAASC,GAAG,EAAEC,IAAI,EAAEC,KAAK,QAAQ,gBAAe;AAChD,SAASC,QAAQ,EAAEC,QAAQ,QAAQ,kBAAiB;AACpD,SAASC,SAAS,QAAQ,QAAO;AACjC,SAASC,uBAAuB,QAAQ,wCAAoC;AAC5E,OAAOC,0BAA0B,sCAAkC;AACnE,OAAOC,qBAAqB,gCAA4B;AACxD,OAAOC,mCAAmC,+CAA2C;AACrF,SAASC,eAAe,QAAQ,wBAAoB;AACpD,SAASC,sBAAsB,QAAQ,gCAA4B;AACnE,OAAOC,eAAe,qBAAiB;AACvC,OAAOC,0BAA0B,wCAAoC;AACrE,OAAOC,kBAAkB,qBAAiB;AAC1C,OAAOC,cAAyC,iBAAa;AAC7D,OAAOC,uBAAuB,2BAAuB;AAQrDD,SAASE,WAAW,GAAG;AAIvB,OAAO,MAAMC,yBAAyBd,SACpC,CAACe;;QA4BoBb,0BAiJPc,gBACEA;IA7Kd,MAAM,EAAW,GAAGD,OAATE,oBAASF;IACpB,MAAMG,WAAWb;IAEjB,uEAAuE;IACvE,yEAAyE;IACzE,yEAAyE;IACzE,uBAAuB;IACvB,MAAM,EAAEc,MAAM,EAAEC,KAAK,EAAEC,kBAAkB,EAAE,GAAGjB,gBAAgBc;IAE9D,uEAAuE;IACvE,yDAAyD;IACzD,4DAA4D;IAC5D,MAAMF,SAASb;IAEf,qEAAqE;IACrE,wEAAwE;IACxE,kEAAkE;IAClE,qEAAqE;IACrE,oDAAoD;IACpDR,cAAc;QACZ2B,aAAaN,OAAOO,OAAO;QAC3BC,WAAWR,OAAOS,MAAM;QACxBC,cAAcV,OAAOS,MAAM;IAC7B;IAEA,mEAAmE;IACnE,uCAAuC;IACvC,MAAME,cAAazB,2BAAAA,8CAAAA,yBAA2B0B,IAAI;IAClD3B,UAAU;QACR,IAAI0B,YAAYX,OAAOa,OAAO;IAChC,GAAG;QAACF;QAAYX;KAAO;IAEvB,qBACE,MAAClB;QAAMgC,IAAI;YAAEC,QAAQ;YAAGC,WAAW;QAAE;;0BACnC,KAACpC;gBACCkC,IAAI;oBACFG,SAAS;oBACTC,YAAY;oBACZC,IAAI;oBACJC,IAAI;oBACJC,cAAc;oBACdC,aAAa;oBACb,kEAAkE;oBAClE,qDAAqD;oBACrDC,UAAU;oBACVC,KAAK;oBACLC,QAAQ;oBACRC,iBAAiB;gBACnB;0BAEA,cAAA,KAAC9B;oBAAkB+B,OAAOxB;oBAAQyB,UAAUvB;;;YAE7C,EAACD,yBAAAA,MAAOyB,MAAM,kBACb,KAACnC;gBAAaoB,IAAI;oBAAEE,WAAW;gBAAI;iBAEnC,gEAAgE;YAChE,0CAA0C;YAC1C,iEAAiE;YACjE,+DAA+D;0BAC/D,KAACpC;gBACCkC,IAAI;oBAAEgB,MAAM;oBAAGd,WAAW;oBAAGe,WAAW;gBAAO;gBAC/CC,UAAUhC,OAAOa,OAAO;0BAExB,cAAA,KAACtB;oBACC,+DAA+D;oBAC/D,gEAAgE;oBAChE,6DAA6D;oBAC7D,8DAA8D;oBAC9D,8DAA8D;oBAC9D,gEAAgE;oBAChE,gCAAgC;oBAChCa,OAAOA;oBACP6B,iBAAiB7B,MAAM8B,GAAG,CAAC,CAACC,IAAMA,EAAEC,GAAG;oBACvCC,WAAW,CAACC,OAASA,wBAAAA,KAAMF,GAAG;oBAC9B,gEAAgE;oBAChE,qEAAqE;oBACrE,iEAAiE;oBACjE,+DAA+D;oBAC/DG,aAAa,CAACD,OACZA,CAAAA,wBAAAA,KAAMF,GAAG,MAAK9D,8BACV;4BACEkE,OAAO;4BACPC,SACE;4BACFC,MAAMpD,gBACJ,sBACA;wBAEJ,IAEA,wDAAwD;wBACxDgD,CAAAA,wBAAAA,KAAMF,GAAG,MAAK7D,gCACZ;4BACEiE,OAAOjE;4BACPkE,SACE;4BACFC,MAAMpD,gBACJ,sBACA;wBAEJ,IACAqD;oBAERC,iBAAiB,CAAC,EAAEN,IAAI,EAAE,iBACxB,KAACvD;sCAAU,kBAAM;8CAAGuD,wBAAAA,KAAMO,KAAK;;;oBAEjCC,uBAAuB;wBACrBhC,IAAI;4BAAEiC,WAAW;wBAAS;oBAC5B;oBACAC,gBAAgB,CAAC,EAAEV,IAAI,EAAE,iBACvB,KAACvD;sCACE;oCAGMuD;qDAFL,KAAC1D;8CACC,cAAA,KAACC;wCAAKoE,SAAS;wCAAGC,SAAS;wCAACpC,IAAI;4CAAEiC,WAAW;wCAAS;kDACnDT,yBAAAA,cAAAA,KAAMlC,KAAK,qBAAXkC,YAAaJ,GAAG,CAAC,CAACiB,MAAMC;;iEACvB,KAACvE;gDAECwE,MAAM;gDACNC,cAAc,CAACC,IACbvD,OAAOY,IAAI,CAACuC,MAAMI,EAAEC,aAAa;gDAEnCC,cAAczD,OAAO0D,aAAa;gDAClCC,SAAS,CAACJ,IACRvD,OAAO4D,SAAS,CACdT,MACAI,EAAEC,aAAa;0DAInB,cAAA,KAAChE;oDACC2D,MAAMA;oDACNU,MAAMrF,SAASsF,MAAM;oDACrBC,QAAQ,EAAEzB,wBAAAA,KAAMF,GAAG;8DAElB,CAAC,EAAE4B,SAAS,EAAEb,IAAI,EAAEc,UAAU,EAAE,iBAC/B;;8EACE,KAACtE;oEACCuE,KAAKzF,UACHwF,YACAD,UAAUG,UAAU;oEAEtBhB,MAAMA;oEACNiB,OACEJ,UAAUK,UAAU,GAChB;wEAAEC,SAAS;oEAAI,IACf,CAAC;mEAEHN,UAAUO,SAAS;8EAEzB,KAAC7F;oEAAY8F,eAAe;8EACzBR,UAAUK,UAAU,kBACnB,KAAC1E;wEACCwD,MAAMA;wEACNrC,IAAI;4EAAEW,QAAQ;wEAAK;;;;;;uDArC1B0B,wBAAAA,KAAMf,GAAG,mBAAIgB;;;;;;mBAmD5BnD;;0BAIV,KAACR;gBACC6C,IAAI,GAAEtC,iBAAAA,OAAOyE,MAAM,qBAAbzE,eAAesC,IAAI;gBACzBoC,MAAM,WAAE1E,kBAAAA,OAAOyE,MAAM,qBAAbzE,gBAAe0E,MAAM,mBAAI;gBACjCC,QAAQ3E,OAAO4E,QAAQ;gBACvBC,gBAAgB7E,OAAO8E,QAAQ;gBAC/BC,gBAAgB/E,OAAO0D,aAAa;gBACpCsB,WAAWhF,OAAOa,OAAO;;;;AAIjC,GACD;AACDf,uBAAuBD,WAAW,GAAG;AAErC,eAAeC,uBAAsB"}
@@ -40,7 +40,7 @@ import { besignerDocsUrl } from "../utils/docs-help.js";
40
40
  import { canvasSchemeToSxScheme, deviceFlagToBreakpoint } from "../utils/responsive-sx.js";
41
41
  import { applyStylePartialToSx, buildFlexGridGroup, buildStyleFieldGroups, computeEffectiveStyleValues, computeStylePartial, pickStyleValues, styleGroupFieldNames } from "../utils/style-field-groups.js";
42
42
  import { filterStyleGroup, matchesStyleQuery, STYLE_SECTION_ENTRIES, styleFieldEntry } from "../utils/style-field-search.js";
43
- import { placementCopy, propDefaultsOf, styleChangeLabel } from "../utils/placement-override-copy.js";
43
+ import { EMAIL_PLACEMENT_STYLE_NOTE, placementCopy, placementKindFor, propDefaultsOf, styleChangeLabel } from "../utils/placement-override-copy.js";
44
44
  import { getPlacementPartPick, resolvePickedPart } from "../utils/placement-part-pick.js";
45
45
  import { countLayoutStyleChanges, countStyleChanges, getLayoutStyleTarget, getNodeStyleTarget } from "../utils/style-target.js";
46
46
  import { buildStyleThemeScales } from "../utils/theme-scale-options.js";
@@ -1006,7 +1006,10 @@ const ElementStylesForm = observer(/*#__PURE__*/ forwardRef((props, ref)=>{
1006
1006
  }, [
1007
1007
  target
1008
1008
  ]);
1009
- const placementKind = isPlacedForm ? 'form' : 'component';
1009
+ // A reusable block placed in an email is the same kind of placement,
1010
+ // worded for the email it is in (AGL-3287).
1011
+ const [viewType] = useAglynBesignerFlag('viewType');
1012
+ const placementKind = placementKindFor(isPlacedForm, viewType);
1010
1013
  const placementText = placementCopy(placementKind);
1011
1014
  const styleChangeCount = target.isInstanceOverride ? countStyleChanges(node) : 0;
1012
1015
  // The definition's declared defaults, for part names whose words come
@@ -1086,6 +1089,26 @@ const ElementStylesForm = observer(/*#__PURE__*/ forwardRef((props, ref)=>{
1086
1089
  // Re-seeds a group form's initial values when the selection, the
1087
1090
  // override target or the artboard scope changes (AGL-540/588/1332).
1088
1091
  const formSeedKey = `${styleNodeId != null ? styleNodeId : ''}:${overrideKey}:${activeBreakpoint != null ? activeBreakpoint : 'base'}` + `:${activeScheme != null ? activeScheme : 'light'}:${activeState != null ? activeState : 'base'}`;
1092
+ // A reusable block placed in an email takes no style changes (AGL-3287).
1093
+ // The email is built from each block's own settings and never reads a
1094
+ // style, so a restyle made here would show on the canvas and reach no
1095
+ // inbox — which is worse than not offering one. One note says where the
1096
+ // block's look IS changed; its settings stay open in the Attributes tab.
1097
+ if (placementKind === 'email' && target.isInstanceOverride && !target.isLayoutOverride) {
1098
+ return /*#__PURE__*/ _jsx(Container, {
1099
+ gutterY: [
1100
+ 1
1101
+ ],
1102
+ dense: true,
1103
+ children: /*#__PURE__*/ _jsx(Alert, {
1104
+ severity: "info",
1105
+ sx: {
1106
+ fontSize: '0.8125rem'
1107
+ },
1108
+ children: EMAIL_PLACEMENT_STYLE_NOTE
1109
+ })
1110
+ });
1111
+ }
1089
1112
  return /*#__PURE__*/ _jsxs(_Fragment, {
1090
1113
  children: [
1091
1114
  /*#__PURE__*/ _jsx(Container, {