@aglyn/plugins-mui 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +22 -0
- package/package.json +47 -0
- package/src/index.d.ts +21 -0
- package/src/index.js +22 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/accordion.d.ts +96 -0
- package/src/lib/components/accordion.js +392 -0
- package/src/lib/components/accordion.js.map +1 -0
- package/src/lib/components/app-bar.d.ts +32 -0
- package/src/lib/components/app-bar.js +86 -0
- package/src/lib/components/app-bar.js.map +1 -0
- package/src/lib/components/blocks.d.ts +46 -0
- package/src/lib/components/blocks.js +1007 -0
- package/src/lib/components/blocks.js.map +1 -0
- package/src/lib/components/box.d.ts +47 -0
- package/src/lib/components/box.js +125 -0
- package/src/lib/components/box.js.map +1 -0
- package/src/lib/components/breadcrumbs.d.ts +44 -0
- package/src/lib/components/breadcrumbs.js +172 -0
- package/src/lib/components/breadcrumbs.js.map +1 -0
- package/src/lib/components/button.d.ts +89 -0
- package/src/lib/components/button.js +272 -0
- package/src/lib/components/button.js.map +1 -0
- package/src/lib/components/card.d.ts +61 -0
- package/src/lib/components/card.js +336 -0
- package/src/lib/components/card.js.map +1 -0
- package/src/lib/components/collection.d.ts +514 -0
- package/src/lib/components/collection.js +2999 -0
- package/src/lib/components/collection.js.map +1 -0
- package/src/lib/components/container.d.ts +42 -0
- package/src/lib/components/container.js +169 -0
- package/src/lib/components/container.js.map +1 -0
- package/src/lib/components/custom-html.d.ts +78 -0
- package/src/lib/components/custom-html.js +219 -0
- package/src/lib/components/custom-html.js.map +1 -0
- package/src/lib/components/data-table.d.ts +57 -0
- package/src/lib/components/data-table.js +216 -0
- package/src/lib/components/data-table.js.map +1 -0
- package/src/lib/components/document-root.d.ts +77 -0
- package/src/lib/components/document-root.js +118 -0
- package/src/lib/components/document-root.js.map +1 -0
- package/src/lib/components/drawer.d.ts +93 -0
- package/src/lib/components/drawer.js +566 -0
- package/src/lib/components/drawer.js.map +1 -0
- package/src/lib/components/function-controls.d.ts +66 -0
- package/src/lib/components/function-controls.js +207 -0
- package/src/lib/components/function-controls.js.map +1 -0
- package/src/lib/components/function-scope.d.ts +110 -0
- package/src/lib/components/function-scope.js +478 -0
- package/src/lib/components/function-scope.js.map +1 -0
- package/src/lib/components/function-widget.d.ts +75 -0
- package/src/lib/components/function-widget.js +307 -0
- package/src/lib/components/function-widget.js.map +1 -0
- package/src/lib/components/grid.d.ts +91 -0
- package/src/lib/components/grid.js +322 -0
- package/src/lib/components/grid.js.map +1 -0
- package/src/lib/components/icon.d.ts +54 -0
- package/src/lib/components/icon.js +163 -0
- package/src/lib/components/icon.js.map +1 -0
- package/src/lib/components/image-list.d.ts +58 -0
- package/src/lib/components/image-list.js +336 -0
- package/src/lib/components/image-list.js.map +1 -0
- package/src/lib/components/image.d.ts +154 -0
- package/src/lib/components/image.js +451 -0
- package/src/lib/components/image.js.map +1 -0
- package/src/lib/components/inline-text.d.ts +74 -0
- package/src/lib/components/inline-text.js +407 -0
- package/src/lib/components/inline-text.js.map +1 -0
- package/src/lib/components/language-switcher.d.ts +35 -0
- package/src/lib/components/language-switcher.js +179 -0
- package/src/lib/components/language-switcher.js.map +1 -0
- package/src/lib/components/layout-slot.d.ts +68 -0
- package/src/lib/components/layout-slot.js +192 -0
- package/src/lib/components/layout-slot.js.map +1 -0
- package/src/lib/components/link-box-accessible-name.d.ts +79 -0
- package/src/lib/components/link-box-accessible-name.js +158 -0
- package/src/lib/components/link-box-accessible-name.js.map +1 -0
- package/src/lib/components/link-box.d.ts +66 -0
- package/src/lib/components/link-box.js +212 -0
- package/src/lib/components/link-box.js.map +1 -0
- package/src/lib/components/list-item-text.d.ts +22 -0
- package/src/lib/components/list-item-text.js +86 -0
- package/src/lib/components/list-item-text.js.map +1 -0
- package/src/lib/components/list-item.d.ts +32 -0
- package/src/lib/components/list-item.js +127 -0
- package/src/lib/components/list-item.js.map +1 -0
- package/src/lib/components/list.d.ts +34 -0
- package/src/lib/components/list.js +108 -0
- package/src/lib/components/list.js.map +1 -0
- package/src/lib/components/markdown.d.ts +129 -0
- package/src/lib/components/markdown.js +853 -0
- package/src/lib/components/markdown.js.map +1 -0
- package/src/lib/components/nav-menu.d.ts +68 -0
- package/src/lib/components/nav-menu.js +683 -0
- package/src/lib/components/nav-menu.js.map +1 -0
- package/src/lib/components/pagination.d.ts +59 -0
- package/src/lib/components/pagination.js +243 -0
- package/src/lib/components/pagination.js.map +1 -0
- package/src/lib/components/paper.d.ts +47 -0
- package/src/lib/components/paper.js +202 -0
- package/src/lib/components/paper.js.map +1 -0
- package/src/lib/components/plugin-frame.d.ts +64 -0
- package/src/lib/components/plugin-frame.js +335 -0
- package/src/lib/components/plugin-frame.js.map +1 -0
- package/src/lib/components/plugin.d.ts +95 -0
- package/src/lib/components/plugin.js +304 -0
- package/src/lib/components/plugin.js.map +1 -0
- package/src/lib/components/product.d.ts +40 -0
- package/src/lib/components/product.js +287 -0
- package/src/lib/components/product.js.map +1 -0
- package/src/lib/components/reusable-instance.d.ts +57 -0
- package/src/lib/components/reusable-instance.js +126 -0
- package/src/lib/components/reusable-instance.js.map +1 -0
- package/src/lib/components/screen-link.d.ts +85 -0
- package/src/lib/components/screen-link.js +324 -0
- package/src/lib/components/screen-link.js.map +1 -0
- package/src/lib/components/search-box.d.ts +41 -0
- package/src/lib/components/search-box.js +125 -0
- package/src/lib/components/search-box.js.map +1 -0
- package/src/lib/components/section.d.ts +56 -0
- package/src/lib/components/section.js +132 -0
- package/src/lib/components/section.js.map +1 -0
- package/src/lib/components/stack.d.ts +55 -0
- package/src/lib/components/stack.js +309 -0
- package/src/lib/components/stack.js.map +1 -0
- package/src/lib/components/tabs.d.ts +288 -0
- package/src/lib/components/tabs.js +788 -0
- package/src/lib/components/tabs.js.map +1 -0
- package/src/lib/components/theme-mode-switcher.d.ts +38 -0
- package/src/lib/components/theme-mode-switcher.js +168 -0
- package/src/lib/components/theme-mode-switcher.js.map +1 -0
- package/src/lib/components/toolbar.d.ts +37 -0
- package/src/lib/components/toolbar.js +117 -0
- package/src/lib/components/toolbar.js.map +1 -0
- package/src/lib/components/typography.d.ts +33 -0
- package/src/lib/components/typography.js +433 -0
- package/src/lib/components/typography.js.map +1 -0
- package/src/lib/components/video-lightbox-controls.d.ts +131 -0
- package/src/lib/components/video-lightbox-controls.js +536 -0
- package/src/lib/components/video-lightbox-controls.js.map +1 -0
- package/src/lib/components/video-lightbox.d.ts +60 -0
- package/src/lib/components/video-lightbox.js +247 -0
- package/src/lib/components/video-lightbox.js.map +1 -0
- package/src/lib/components/video-playback-beacon.d.ts +80 -0
- package/src/lib/components/video-playback-beacon.js +128 -0
- package/src/lib/components/video-playback-beacon.js.map +1 -0
- package/src/lib/components/video-player-frame.d.ts +58 -0
- package/src/lib/components/video-player-frame.js +51 -0
- package/src/lib/components/video-player-frame.js.map +1 -0
- package/src/lib/components/video.d.ts +220 -0
- package/src/lib/components/video.js +874 -0
- package/src/lib/components/video.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +17 -0
- package/src/lib/constants/bundle-common.js +18 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/field-presets.d.ts +93 -0
- package/src/lib/constants/field-presets.js +248 -0
- package/src/lib/constants/field-presets.js.map +1 -0
- package/src/lib/plugin.d.ts +80 -0
- package/src/lib/plugin.js +599 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/utils/author-html-label.d.ts +73 -0
- package/src/lib/utils/author-html-label.js +89 -0
- package/src/lib/utils/author-html-label.js.map +1 -0
- package/src/lib/utils/drop-cleared-props.d.ts +18 -0
- package/src/lib/utils/drop-cleared-props.js +74 -0
- package/src/lib/utils/drop-cleared-props.js.map +1 -0
- package/src/lib/utils/element-picker.d.ts +99 -0
- package/src/lib/utils/element-picker.js +140 -0
- package/src/lib/utils/element-picker.js.map +1 -0
- package/src/lib/utils/generate-preset-id.d.ts +19 -0
- package/src/lib/utils/generate-preset-id.js +25 -0
- package/src/lib/utils/generate-preset-id.js.map +1 -0
- package/src/lib/utils/link-target-props.d.ts +53 -0
- package/src/lib/utils/link-target-props.js +53 -0
- package/src/lib/utils/link-target-props.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/video.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 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 * as Aglyn from '@aglyn/aglyn'\nimport {\n readStoredVisitorConsent,\n VISITOR_CONSENT_CHANGED_EVENT,\n} from '@aglyn/aglyn/app-utils/visitor-consent'\nimport {\n wistiaMediaId,\n wistiaPlayerSrc,\n} from '@aglyn/aglyn/app-utils/wistia-embed'\nimport { mdiPlay, mdiVideo } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport Box from '@mui/material/Box'\nimport type { SxProps } from '@mui/material/styles'\nimport useEventCallback from '@mui/utils/useEventCallback'\nimport useForkRef from '@mui/utils/useForkRef'\nimport {\n Suspense,\n forwardRef,\n lazy,\n useCallback,\n useEffect,\n useState,\n type ReactNode,\n} from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\nimport { useVideoPlaybackBeacon } from './video-playback-beacon'\nimport { VideoPlayerFrame } from './video-player-frame'\n\n/**\n * The lightbox, behind a lazy boundary rather than a plain import (AGL-2744).\n *\n * `video-lightbox.tsx` is the only module in the tenant's component graph that\n * names `@mui/material/Dialog`, and `plugin.ts` imports every element in this\n * bundle eagerly — so naming it here would put the whole MUI Dialog stack on\n * every published page of every customer site, which is precisely what\n * AGL-1290 took OFF those pages by withholding `dialog-confirm` and\n * `navigation-drawer` from the shared JSX barrel.\n *\n * Behind `lazy()` it is a chunk nothing on a first paint requests: not on a\n * page without a video, not on a page with one, only for a visitor who has\n * asked to watch. Same shape as `product-detail.tsx`'s Payment Element, for\n * the same reason.\n */\nconst VideoLightbox = lazy(() =>\n import('./video-lightbox').then((module) => ({\n default: module.VideoLightbox,\n })),\n)\n\n// Component ids are persisted in screen documents; never rename.\nexport const ID: Aglyn.ComponentId = 'video'\n\n/**\n * The width the poster is requested at.\n *\n * `<video poster>` takes ONE url and no `srcset`, so unlike `image.tsx` there\n * is no candidate list to hand the browser and no `sizes` to resolve against —\n * a single width has to serve every viewport. Asking for it is what turns a\n * 335 KB PNG poster into the 4 KB WebP the DAM already generated.\n *\n * Read from `@aglyn/aglyn` rather than restated: the page's `thumbnailUrl`\n * asks for the same width, and a crawler that fetches a different image from\n * the one a visitor sees is describing a different picture.\n */\nconst POSTER_REQUEST_WIDTH = Aglyn.MEDIA_CDN_POSTER_WIDTH\n\n/** How much of a video the browser may fetch before anyone asks for it. */\nexport type VideoPreload = 'none' | 'metadata' | 'auto'\n\n/**\n * What `preload` an unset field resolves to, given the rest of the node.\n *\n * Exported for the spec, because the whole point of this element is what it\n * does NOT download and a rule that is only asserted through rendered markup\n * is a rule three refactors from being an accident.\n *\n * * **Autoplay wins first.** A video that starts on its own needs its bytes\n * by definition; `none` there is a hint every browser overrides anyway, and\n * stating it would only mislead the next reader.\n * * **A poster buys `none`.** This is the saving the element exists for — the\n * poster carries the first paint at image cost, and not one byte of video\n * is fetched until a visitor presses play.\n * * **No poster keeps `metadata`.** With neither a poster nor metadata a\n * `<video>` paints a black rectangle, so deferring an unpostered video\n * trades a real transfer for a real regression. `metadata` is also what\n * every document authored before this rendered, which is what makes the\n * change safe for sites already published.\n */\nexport function resolveVideoPreload(options: {\n preload?: unknown\n poster?: unknown\n autoPlay?: unknown\n}): VideoPreload {\n const { preload, poster, autoPlay } = options ?? {}\n if (preload === 'none' || preload === 'metadata' || preload === 'auto')\n return preload\n if (autoPlay) return 'auto'\n return poster ? 'none' : 'metadata'\n}\n\nexport interface VideoProps {\n /**\n * Where the video comes from. Either a **media reference** —\n * `media:{scope}/{mediaId}`, what \"Browse media\" stores (AGL-1215) — or any\n * URL. `resolveMediaSrc` decides, exactly as it does for an image.\n *\n * A Wistia link is read differently (AGL-2826): the element keeps only the\n * media id and plays Wistia's own player, which loads when a visitor\n * presses play and never before, unless {@link loadPlayer} loads it with the\n * page. See `wistia-embed.ts`.\n */\n src?: string\n /**\n * The still shown before playback, and the element's entire first paint\n * once `preload` is `none`. A media reference or a URL, like `src`.\n *\n * Optional even for a poster-first placement: when the DAM captured a frame\n * at upload, {@link posterFromSource} says so and the element derives the\n * poster from the video's own reference.\n */\n poster?: string\n /**\n * The chosen asset has a poster the DAM generated (AGL-2749), served at\n * `?poster=1` on the video's own reference.\n *\n * Written by the pick, never by an author, and it is a flag rather than a\n * url on purpose: the url can be derived from `src` by anybody, but only\n * the media document knows whether it resolves to anything. A video\n * uploaded before AGL-2742 answers 404, and this is what keeps that 404 out\n * of an `<img>` and out of the page's `thumbnailUrl`.\n */\n posterFromSource?: boolean\n /**\n * The video's title (AGL-2741). Serves three jobs at once and is deliberate\n * about it: the `<video>`'s tooltip, the accessible name a screen reader\n * announces for the player, and `VideoObject.name` in the page's structured\n * data. One sentence an author writes once.\n */\n title?: string\n /**\n * What the video is about — `VideoObject.description`, which Google\n * recommends for a video rich result but does not require, so a blank one\n * drops only this field from the structured data. Never rendered as\n * visible text; the element is a player, not a caption.\n */\n description?: string\n /**\n * When the video was first published, as `YYYY-MM-DD`. Google requires it\n * beside the title and the poster, and it is the one nothing else on the\n * page can supply: a screen's own publish date is when the PAGE went up,\n * which for a film embedded months later is simply a different fact.\n *\n * The day is what an author types; the page's `VideoObject` publishes it as\n * that day at noon UTC, because Google reads `uploadDate` as a date-time\n * with a zone (`uploadDateTime` in the VideoObject builder).\n */\n uploadDate?: string\n /**\n * Running time in seconds. Copied off the media document when the DAM's\n * video pipeline publishes one (`Aglyn.videoMediaProps`) and read from the\n * asset again when the page is composed, so a replace reaches it\n * (AGL-2807); typed by the author otherwise, and omitted from the schema\n * when neither happened.\n */\n durationSeconds?: number\n /**\n * Show the poster as a play button and open the film in a dialog\n * (AGL-2744).\n *\n * Default OFF, so every document published before this keeps rendering the\n * inline player it was authored against. Requires a poster — there is\n * nothing to click without one — and falls back to inline playback when\n * there is none, rather than rendering a button with no face.\n *\n * A Wistia poster waits for a press whether this is on or off; the switch\n * decides only where its player opens, in the dialog or in place of the\n * poster. A Wistia player that {@link loadPlayer} put in the page stays in\n * the page either way.\n */\n lightbox?: boolean\n /**\n * Load a Wistia video's player with the page (AGL-2962), in place of the\n * poster and without autoplay, for a visitor whose stored consent grants\n * analytics.\n *\n * For a page built to show this one film. A search engine lists a video\n * only from a page whose main content it is, and it can only find a player\n * that is in the page once the page has loaded; a poster that must be\n * pressed first is the case Search Console reports as \"Cannot determine\n * video position and size\".\n *\n * Default OFF, so every document published before this renders the poster\n * it was authored against. No effect on any other source: a library film or\n * a video URL already renders its `<video>` into the page's HTML. The\n * page-load state below says who gets the player and when.\n */\n loadPlayer?: boolean\n /** Captions file — a WebVTT (`.vtt`) URL or media reference. */\n captionsSrc?: string\n /** What the captions track is called in the player's menu. */\n captionsLabel?: string\n /** BCP-47 language tag for the captions, e.g. `en`. */\n captionsLang?: string\n autoPlay?: boolean\n loop?: boolean\n muted?: boolean\n controls?: boolean\n /**\n * Play inline on a phone rather than taking over the screen. Defaults ON,\n * which is what this element has always rendered — it is a control now\n * because a full-screen takeover is a legitimate choice for a film and\n * there was no way to ask for it.\n */\n playsInline?: boolean\n /** See {@link resolveVideoPreload}; unset is decided from the node. */\n preload?: VideoPreload\n /** CSS width (e.g. \"100%\", \"640px\"); defaults to 100%. */\n width?: string\n /** CSS height (e.g. \"360px\"); defaults to auto. */\n height?: string\n /**\n * The asset's own pixel dimensions, copied off the media document when the\n * video was picked (AGL-2741) — the same pair, by the same route and for\n * the same reason, as `image.tsx` — and read from the asset again when the\n * page is composed, so a replace with a different shape resizes the player\n * (AGL-2807).\n *\n * NOT author controls, which is why neither appears in the schema below.\n * They describe the file; the CSS `width`/`height` above describe the\n * placement. Here they become a CSS `aspect-ratio` rather than the HTML\n * attribute pair an `<img>` gets, because a `<video>`'s `width`/`height`\n * content attributes are used dimensions, not a ratio — writing them would\n * pin the element to the file's pixel size instead of reserving its shape.\n *\n * The stake is higher than it is for an image. An `<img>` with no ratio is\n * zero-height until its bytes decode; a `<video preload=\"none\">` with no\n * ratio is zero-height until somebody presses play, which on most pages is\n * never.\n */\n intrinsicWidth?: number\n /** See `intrinsicWidth` — the two are only ever used as a pair. */\n intrinsicHeight?: number\n /** Border radius in px. */\n radius?: number\n /**\n * Authored node styles, handed over by the renderer rather than typed\n * into an attribute — recomposed below so the Styles panel's values are\n * merged rather than replaced (AGL-1284).\n */\n sx?: SxProps\n /**\n * Accepted and dropped. The element is `selfClosing`, so the besigner never\n * gives it children; the `<track>` below is the renderer's own child and\n * anything arriving through the tree would land beside it.\n */\n children?: ReactNode\n}\n\n/**\n * Video element (AGL-162, AGL-2741): plays a media-library upload, any URL or\n * a Wistia video (AGL-2826), poster first.\n *\n * The default is now to download NOTHING until a visitor asks. A poster is an\n * image — a few tens of kilobytes through the DAM's WebP variants, edge-cached\n * — while the video behind it is not edge-cacheable at all and is measured in\n * megabytes. `preload` decides which of those a page pays for on first paint,\n * and {@link resolveVideoPreload} explains what an unset field resolves to.\n *\n * An empty src shows a labeled placeholder so the element stays selectable in\n * the editor.\n */\nconst Video = forwardRef<HTMLElement, VideoProps>((props, ref) => {\n const {\n src: storedSrc,\n poster: storedPoster,\n posterFromSource,\n title,\n // Structured-data-only fields. Every one of them MUST be destructured:\n // what is left in `rest` is spread onto the `<video>`, where a\n // `description` or an `uploadDate` becomes an invalid DOM attribute in\n // the published HTML.\n description: _description,\n uploadDate: _uploadDate,\n durationSeconds: _durationSeconds,\n lightbox,\n loadPlayer,\n captionsSrc,\n captionsLabel,\n captionsLang,\n autoPlay,\n loop,\n muted,\n controls,\n playsInline,\n preload,\n width,\n height,\n intrinsicWidth,\n intrinsicHeight,\n radius,\n children: _children,\n // Pulled out of the spread: the literals below are composed AFTER\n // `{...rest}`, so leaving it there REPLACES every style the author set\n // from the Styles panel (AGL-1240, the same trap image.tsx documents).\n sx: nodeSxProp,\n ...rest\n } = props\n const nodeSx = Array.isArray(nodeSxProp)\n ? nodeSxProp\n : nodeSxProp\n ? [nodeSxProp]\n : []\n // Both fields are media-picker targets, so both can hold a media\n // reference (AGL-1215) as well as any of the URL forms that predate it.\n // Resolving here is not optional: the picker hands back one string for\n // whichever attribute asked for it, so every field it can write to has to\n // understand the same value.\n const { hostId } = Aglyn.useSite()\n /**\n * The delivery copy, not the master (AGL-2753).\n *\n * `videoDeliverySrc` is `resolveMediaSrc` plus `?r=auto`, which asks the CDN\n * for the best encoding it holds instead of naming one. The element cannot\n * name one: renditions are produced out of band by\n * `tools/scripts/generate-video-renditions.mjs`, minutes or days after the\n * upload, so at pick time an asset usually has none and a copied list would\n * be empty for exactly the videos it exists to serve. Asking rather than\n * naming is what lets an encoding made tomorrow reach a video placed today,\n * with no re-pick and nothing rewritten in a published document.\n *\n * Nothing here is conditional on the asset having renditions, because the\n * URL degrades to the master by construction — which is the file this\n * served before, so a page cannot get worse by adopting it.\n */\n const src = Aglyn.videoDeliverySrc(storedSrc, { hostId })\n // Two candidates, one rule, shared with the page's `thumbnailUrl`: the\n // author's own poster wins, and the DAM's generated frame is used only when\n // the node records that one exists (AGL-2749).\n const posterFor = (width?: number) =>\n Aglyn.videoPosterSrc({\n hostId,\n poster: storedPoster,\n src: storedSrc,\n generated: posterFromSource,\n width,\n })\n /** Full size — what an `<img>` wants beside a `srcSet` of widths. */\n const posterBase = posterFor()\n /** One width — what `<video poster>` and a `thumbnailUrl` have to take. */\n const poster = posterFor(POSTER_REQUEST_WIDTH)\n const captions = Aglyn.resolveMediaSrc(captionsSrc, { hostId })\n /**\n * The lightbox's two pieces of state, and they are deliberately two.\n *\n * `open` is what the dialog reads. `armed` is whether the chunk has been\n * ASKED for, which happens on the first hover or focus rather than on the\n * click — so by the time a visitor's pointer has travelled from the poster\n * to the play badge, the module is usually already there and the dialog\n * opens on the same frame as the click. A visitor who never goes near the\n * poster never arms it and never fetches it, which is the whole bargain.\n *\n * `armed` never goes back to false. Re-mounting `lazy()` after a close\n * would not re-download anything (the module is resolved), and leaving it\n * mounted is what lets a second open be instant.\n */\n const [open, setOpen] = useState(false)\n const [armed, setArmed] = useState(false)\n const arm = useCallback(() => setArmed(true), [])\n const closeLightbox = useCallback(() => setOpen(false), [])\n const openLightbox = useCallback(() => {\n setArmed(true)\n setOpen(true)\n }, [])\n /**\n * The besigner canvas is inert (AGL-830): opening a focus-trapping dialog\n * inside the editor would steal the author's keyboard mid-edit, and the\n * click on a poster there means \"select this node\", not \"watch this\".\n * The trigger still RENDERS as a button, because what an author sees on the\n * canvas has to be what a visitor gets.\n */\n const { editorInert, suppressNavigation } = Aglyn.useScreenLink(undefined)\n /**\n * What a play is counted against (AGL-2781): the site, the asset the STORED\n * value names, and whether this surface is an editor. Handed to the\n * lightbox as data rather than as handlers, because a play there belongs to\n * one open of the dialog and only the dialog knows when that begins.\n */\n const playback = { hostId, src: storedSrc, suppressed: suppressNavigation }\n const playbackHandlers = useVideoPlaybackBeacon(playback)\n /**\n * A Wistia video (AGL-2826), and the player address a press produced.\n *\n * Unless the page loads the player (see `pageLoadSrc` below), nothing of\n * Wistia's renders before that press. The poster is a button, as it is for\n * the lightbox, so a visitor who only looks at the page makes no request to\n * Wistia and is handed no storage by it. `playerSrc` stays empty until the\n * press, and setting it is what brings the frame in.\n */\n const wistiaId = wistiaMediaId(storedSrc)\n const [playerSrc, setPlayerSrc] = useState<string>()\n /**\n * The press. Consent is read here and not during render: the record lives\n * in this browser's storage, which a cached page cannot vary on, and a\n * visitor may answer the banner between the first paint and the click.\n *\n * Wistia records the viewing only when this visitor's analytics consent is\n * on record. A visitor without that record — still deciding, refused,\n * opted out by GPC, or visiting a site that runs no consent banner — gets\n * the player with `doNotTrack`.\n */\n const playWistia = useCallback(() => {\n setPlayerSrc(\n wistiaPlayerSrc(storedSrc, {\n doNotTrack: !readStoredVisitorConsent(hostId)?.analytics,\n muted: Boolean(muted),\n loop: Boolean(loop),\n }),\n )\n }, [storedSrc, hostId, muted, loop])\n /**\n * The player address \"Load the player with the page\" produced (AGL-2962):\n * Wistia's player without autoplay, in place of the poster before anyone has\n * pressed anything, so a search engine rendering the page finds the player\n * in it.\n *\n * Only for a visitor whose stored consent grants analytics, which is why the\n * address never carries `doNotTrack`. The unpressed frame is not free of\n * storage: measured on 2026-09-14 in headless Chrome, it set no cookie but\n * wrote two keys to its own `localStorage`, a random resume key and a record\n * of its load times, with `doNotTrack` on as well as off. A visitor in a\n * prior-consent region has to say yes before that. Everyone else keeps the\n * poster, and a press on it loads the player as it does with the switch\n * off, `doNotTrack` included.\n *\n * Set from an effect and never during render, for the reason a press reads\n * consent at the click: the record is in this browser's storage, which the\n * server HTML and the first paint cannot vary on, so both are the poster for\n * every visitor. The effect reads the record on mount and again on every\n * consent change, because the decision can land after the element mounts:\n * the implied default is recorded when the region lookup answers, and a\n * banner is answered whenever the visitor gets to it. A withdrawal before\n * any press on the element puts the poster back, even over a film started\n * from the play button inside Wistia's frame, which the element cannot see.\n *\n * Never on the besigner canvas, where the poster button is inert too, and\n * never for a Wistia video without a poster, which has no first paint to\n * give. A press ends it: from then on the pressed address is the one in the\n * frame, and a later change of consent moves nothing, as it moves nothing\n * for a player a press loaded with the switch off.\n */\n const [pageLoadSrc, setPageLoadSrc] = useState<string>()\n useEffect(() => {\n if (!loadPlayer || !wistiaId || !poster || editorInert || playerSrc) {\n return undefined\n }\n const sync = () =>\n setPageLoadSrc(\n readStoredVisitorConsent(hostId)?.analytics\n ? wistiaPlayerSrc(storedSrc, {\n autoPlay: false,\n muted: Boolean(muted),\n loop: Boolean(loop),\n })\n : undefined,\n )\n sync()\n window.addEventListener(VISITOR_CONSENT_CHANGED_EVENT, sync)\n return () => window.removeEventListener(VISITOR_CONSENT_CHANGED_EVENT, sync)\n }, [\n loadPlayer,\n wistiaId,\n poster,\n editorInert,\n playerSrc,\n hostId,\n storedSrc,\n muted,\n loop,\n ])\n /** Read through the switch, so switching it off removes a loaded player. */\n const loadedSrc = loadPlayer ? pageLoadSrc : undefined\n /**\n * The address of the Wistia player standing in place of the poster, if one\n * is: a pressed player while the lightbox is off, and a player the page\n * loaded whatever the lightbox is set to. The pressed address outranks the\n * loaded one, because it is the one that plays.\n */\n const inPlaceSrc =\n wistiaId && (!lightbox || loadedSrc) ? (playerSrc ?? loadedSrc) : undefined\n /**\n * What pressing the poster does. The poster's own button and a press sent\n * from outside the element both call this one function, so the two cannot\n * come to disagree about what a press is.\n *\n * A player the page loaded is already in place, so a press plays it there\n * and never opens the lightbox.\n */\n const press = () => {\n if (wistiaId) playWistia()\n if (lightbox && !loadedSrc) openLightbox()\n }\n /**\n * A press sent from outside the element (AGL-2867) — a \"Play a video\"\n * interaction on a button elsewhere on the page — answered as the markup\n * rendered below would answer a press on it, branch for branch:\n *\n * - nothing that can play (no source, or a Wistia video with no poster):\n * nothing happens;\n * - a Wistia player a press put in place of its poster: it is playing\n * already;\n * - a Wistia player the page loaded and nothing has pressed: `press()`,\n * whose autoplaying address replaces the loaded one. That is what the play\n * button inside the frame does, and the element cannot reach that button\n * across Wistia's origin, so a film already started from it starts over;\n * - a poster that is a button: that button's own press, which reads consent\n * at that moment and is the only thing that ever loads the lightbox chunk\n * or a player the page did not load;\n * - the inline player: `play()`, which is what a press on it does.\n *\n * Inert on the besigner canvas, as the poster button is, for the same\n * reason: nothing may load a player or open a dialog inside the editor.\n *\n * `useEventCallback`, not React's `useEffectEvent`: in the React this repo\n * runs, an effect event declared in a `forwardRef` component is never\n * handed the implementation from later renders, so a listener added once\n * would go on answering with the props of the first one.\n */\n const answerVideoCommand = useEventCallback((element: HTMLElement) => {\n if (editorInert || !src) return\n if (wistiaId && !poster) return\n if (inPlaceSrc && playerSrc) return\n if ((lightbox || wistiaId) && poster) return press()\n if (element instanceof HTMLVideoElement) {\n // A play the browser refuses (a trigger that was not a press, on an\n // unmuted film) is the browser's decision to make, not an error.\n void Promise.resolve(element.play()).catch(() => undefined)\n }\n })\n /**\n * The element's own DOM root, which receives the command. State rather than\n * a ref object, because the root is a different element in different\n * branches — the inline `<video>`, or the box around a poster — and the\n * listener has to follow it.\n */\n const [root, setRoot] = useState<HTMLElement | null>(null)\n const rootRef = useForkRef(ref, setRoot)\n useEffect(() => {\n if (!root) return undefined\n return Aglyn.subscribeVideoCommands(root, () => answerVideoCommand(root))\n }, [root, answerVideoCommand])\n /**\n * The labeled box the element shows when it has nothing it can play. The\n * label is for the author, so only editing surfaces draw it; a published\n * page renders the bare element.\n */\n const placeholder = (label: string) =>\n suppressNavigation ? (\n <Box\n ref={rootRef}\n {...rest}\n sx={[\n {\n width: width || '100%',\n height: height || 180,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px dashed',\n borderColor: 'divider',\n borderRadius: radius != null ? `${radius}px` : undefined,\n color: 'text.secondary',\n fontSize: 12,\n fontFamily: 'system-ui, sans-serif',\n },\n ...nodeSx,\n ]}\n >\n {label}\n </Box>\n ) : (\n <Box ref={rootRef} {...rest} sx={nodeSx} />\n )\n if (!src) return placeholder('Video — set a source URL')\n /**\n * The reserved box, as a ratio rather than a size.\n *\n * Both-or-neither and finite-and-positive for the reasons `image.tsx` gives\n * at its own pair: a lone dimension describes no shape, and a capture may\n * legitimately be `0` or missing. Suppressed when the author pinned a\n * `height`, because then the box is already definite and a ratio would only\n * fight the value they typed.\n */\n const usable = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value) && value > 0\n const aspectRatio =\n !height && usable(intrinsicWidth) && usable(intrinsicHeight)\n ? `${intrinsicWidth} / ${intrinsicHeight}`\n : undefined\n const track = captions ? (\n // `default` so the track is selected without the visitor hunting for it\n // in the player's menu. A captions file an author took the trouble to\n // attach is one they meant people to see, and the browser still offers\n // the switch that turns it off.\n <track\n kind=\"captions\"\n src={captions}\n srcLang={captionsLang || undefined}\n label={captionsLabel || undefined}\n default\n />\n ) : null\n /**\n * A Wistia video with no poster has nothing to press, and the alternative —\n * loading the player up front for every visitor — is the request this\n * element exists to withhold. So it says what it needs instead, with \"Load\n * the player with the page\" on as well: the poster is that switch's server\n * HTML and first paint, and what every visitor without analytics consent\n * goes on seeing.\n */\n if (wistiaId && !poster) {\n return placeholder('Video — add a poster image to play this Wistia video')\n }\n /**\n * The Wistia player in place of the poster: after a press when the lightbox\n * is off, or loaded with the page (AGL-2962). The wrapper is the same element\n * the poster sat in, so the node's styles and ref stay where they were and\n * only its contents change.\n */\n if (inPlaceSrc) {\n return (\n <Box\n ref={rootRef}\n {...rest}\n sx={[\n {\n display: 'block',\n position: 'relative',\n width: width || '100%',\n height: height || 'auto',\n },\n ...nodeSx,\n ]}\n >\n <VideoPlayerFrame\n // A press on a player the page loaded mounts a new frame rather than\n // handing the loaded one a new address. Navigating a frame that has\n // already loaded a document adds an entry to the tab's history, so\n // Back would first take the frame back to the unpressed player\n // instead of leaving the page. Measured on 2026-09-14 in Chrome 154:\n // a new `src` on a loaded frame took `history.length` from 1 to 2,\n // and a new frame element in its place added nothing.\n key={playerSrc ? 'pressed' : 'loaded'}\n src={inPlaceSrc}\n title={title}\n aspectRatio={aspectRatio}\n height={height}\n radius={radius}\n // Focus follows a press into the player. A player the page loaded\n // takes none: nobody asked for it, and focusing a frame as the page\n // loads would scroll the page to it and take the keyboard with it.\n focusOnMount={Boolean(playerSrc)}\n />\n </Box>\n )\n }\n /**\n * Poster-first, dialog on click (AGL-2744).\n *\n * Requires a poster, and falls back to the inline player without one rather\n * than rendering a button with no face. That is not a limitation to work\n * around — a lightbox trigger with nothing to show is a blank rectangle\n * that claims to be a film.\n *\n * A Wistia video takes this branch until a player stands in place of its\n * poster (AGL-2826), which includes the server HTML and first paint of one\n * that loads its player with the page. With the lightbox off its press swaps\n * the player in above, and the lazy dialog is never armed, because nothing is\n * going to open it.\n */\n if ((lightbox || wistiaId) && poster) {\n const playsInPlace = Boolean(wistiaId) && !lightbox\n return (\n <Box\n ref={rootRef}\n {...rest}\n sx={[\n {\n display: 'block',\n position: 'relative',\n width: width || '100%',\n height: height || 'auto',\n },\n ...nodeSx,\n ]}\n >\n <Box\n component=\"button\"\n type=\"button\"\n // Inert on the canvas: a focus-trapping dialog opened inside the\n // editor would take the author's keyboard away mid-edit, and the\n // click there means \"select this node\". Same shape as the Drawer's\n // `editorInert ? undefined : handler`. It is also why a hosted\n // player never loads into the canvas.\n onClick={editorInert ? undefined : press}\n // Arming on hover and on focus, not on click, is what makes the\n // dialog open on the same frame as the press — and it costs a\n // visitor who never approaches the poster nothing at all.\n onPointerEnter={editorInert || playsInPlace ? undefined : arm}\n onFocus={editorInert || playsInPlace ? undefined : arm}\n // The button IS the play control, so it says so. Without a title it\n // still announces its purpose rather than reading as an image.\n aria-label={title ? `Play video: ${title}` : 'Play video'}\n sx={{\n // A button reset: the poster is the control, so none of the\n // browser's own chrome should show through it.\n appearance: 'none',\n border: 0,\n p: 0,\n m: 0,\n display: 'block',\n width: '100%',\n font: 'inherit',\n color: 'inherit',\n background: 'none',\n cursor: editorInert ? 'default' : 'pointer',\n position: 'relative',\n overflow: 'hidden',\n borderRadius: radius != null ? `${radius}px` : undefined,\n // The focus ring is the theme's, not a literal: a keyboard\n // visitor has to be able to see where they are on a poster of\n // unknown brightness.\n '&:focus-visible': {\n outline: '2px solid',\n outlineColor: 'primary.dark',\n outlineOffset: 2,\n },\n }}\n >\n <Box\n component=\"img\"\n src={posterBase}\n // The poster is an `<img>` here rather than a `<video poster>`,\n // which is the one advantage this mode has over the inline one:\n // an `<img>` takes the DAM's whole candidate list, so a phone\n // downloads `?w=320` where the inline player has to be handed a\n // single width for every viewport.\n srcSet={\n Aglyn.isMediaCdnUrl(posterBase)\n ? Aglyn.MEDIA_CDN_VARIANT_WIDTHS.map((variant) => {\n // Built through the same rule as the src, not by pasting\n // `?w=` onto it: a generated poster's url already carries\n // `?poster=1`, so a hand-appended query would produce\n // `?poster=1?w=320` and 404 every candidate.\n const candidate = posterFor(variant)\n return candidate ? `${candidate} ${variant}w` : ''\n })\n .filter(Boolean)\n .join(', ')\n : undefined\n }\n sizes={Aglyn.isMediaCdnUrl(posterBase) ? '100vw' : undefined}\n // Empty by design. The button's `aria-label` already names the\n // film and its purpose; alt text here would make a screen reader\n // read the same thing twice, once as a control and once as a\n // picture.\n alt=\"\"\n // No `loading` hint, deliberately — see `deferred-images.spec`,\n // where this element is exempt. A poster is the entire visual of\n // a media element an author placed on purpose, and a browser\n // fetches `<video poster>` eagerly too, so deferring it would be\n // a regression against what this element rendered yesterday\n // rather than a saving.\n decoding=\"async\"\n sx={{\n display: 'block',\n width: '100%',\n height: height || 'auto',\n objectFit: 'cover',\n aspectRatio,\n }}\n />\n <Box\n aria-hidden\n sx={{\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n // A poster is a frame of unknown brightness, and this control\n // has to separate from all of them. A solid disc does; the\n // translucent scrim it replaced sank into any dark frame.\n width: { xs: 64, sm: 80, md: 96 },\n height: { xs: 64, sm: 80, md: 96 },\n borderRadius: '50%',\n // The site's accent, not a literal. A play control is the one\n // mark on a poster that should read as the brand's, so it takes\n // the theme's primary the way every other accented glyph does.\n color: 'primary.main',\n bgcolor: 'common.white',\n boxShadow: 6,\n // Gated in CSS rather than behind a JS branch, so toggling the\n // OS setting after load resolves in BOTH directions — the same\n // reason `element-animation-assets` puts every rule it has\n // inside this query.\n '@media (prefers-reduced-motion: no-preference)': {\n transition: 'transform 150ms, color 150ms',\n 'button:hover &, button:focus-visible &': {\n transform: 'translate(-50%, -50%) scale(1.08)',\n color: 'primary.dark',\n },\n },\n }}\n >\n <MdiIcon\n path={mdiPlay.path}\n sx={{ fontSize: { xs: 32, sm: 40, md: 48 }, ml: '4px' }}\n />\n </Box>\n </Box>\n {armed ? (\n // `fallback={null}`: the poster is still on screen underneath, so\n // there is nothing to cover and a spinner would only flash. The\n // chunk is usually resolved before the click anyway.\n <Suspense fallback={null}>\n <VideoLightbox\n open={open}\n onClose={closeLightbox}\n title={title}\n src={src}\n poster={poster}\n aspectRatio={aspectRatio}\n loop={loop}\n muted={muted}\n captions={track}\n playback={playback}\n embedSrc={wistiaId ? playerSrc : undefined}\n />\n </Suspense>\n ) : null}\n </Box>\n )\n }\n return (\n <Box\n ref={rootRef}\n component=\"video\"\n src={src}\n poster={poster || undefined}\n title={title || undefined}\n autoPlay={Boolean(autoPlay)}\n loop={Boolean(loop)}\n // Browsers block unmuted autoplay.\n muted={Boolean(muted) || Boolean(autoPlay)}\n controls={controls !== false}\n playsInline={playsInline !== false}\n preload={resolveVideoPreload({ preload, poster, autoPlay })}\n {...rest}\n // After the spread, so a stray prop from the tree cannot unwire the\n // counters.\n onPlay={playbackHandlers.onPlay}\n onTimeUpdate={playbackHandlers.onTimeUpdate}\n onEnded={playbackHandlers.onEnded}\n sx={[\n {\n display: 'block',\n width: width || '100%',\n height: height || 'auto',\n aspectRatio,\n borderRadius: radius != null ? `${radius}px` : undefined,\n },\n ...nodeSx,\n ]}\n >\n {track}\n </Box>\n )\n})\nVideo.displayName = 'Video'\n\n/**\n * The caption fields say nothing until there is a captions file to label.\n *\n * `isNotEmpty` rather than an inverted `is: ''` — the two are not the same\n * question for a field nobody has touched. An unset attribute is `undefined`,\n * which is not equal to `''`, so `{ is: '', notMatch: true }` would read as\n * \"not empty\" and show both controls on every fresh Video element.\n */\nconst HAS_CAPTIONS = { when: 'captionsSrc', isNotEmpty: true }\n\nexport const schema: Aglyn.ComponentSchema<VideoProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Video',\n description: 'Plays a video file from your media library or any URL.',\n category: Aglyn.ComponentCategory.MEDIA,\n icon: {\n path: mdiVideo.path,\n sx: { color: '#7b1fa2' },\n },\n flags: {\n selfClosing: Aglyn.FEATURE_FLAG.ENABLED,\n },\n attributes: [\n {\n name: 'src',\n description:\n 'Pick the film from your media library with \"Browse media\", or ' +\n 'paste the URL of a video hosted somewhere else. A Wistia media ' +\n \"link plays in Wistia's player, which loads when a visitor presses \" +\n 'play. Load the player with the page can load it sooner.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Video source',\n },\n {\n name: 'poster',\n description:\n 'The still shown before anyone presses play. Videos from your media ' +\n 'library already have one; pick a different image here to override ' +\n 'it. A poster is what keeps the video off the wire until it is asked for. ' +\n 'A Wistia video needs one: it is the button a visitor presses.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Poster image',\n },\n {\n name: 'title',\n description:\n 'Names the video for screen readers, for the tooltip, and for ' +\n 'search engines. Write it as a headline, not a file name.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Video title',\n },\n {\n name: 'description',\n description:\n 'A sentence or two about what the video shows, different for each ' +\n 'video. Never displayed on the page. Search engines read it, and ' +\n 'can still list the video in results when it is blank.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n label: 'Video description',\n },\n {\n name: 'uploadDate',\n description:\n 'The day the video was first published, as YYYY-MM-DD. Search ' +\n 'engines need this and cannot use the page date instead.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Publication date',\n },\n {\n name: 'durationSeconds',\n description:\n 'How long the video runs, in seconds. Filled in from the media ' +\n 'library when it knows; otherwise type it, or leave it blank.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Duration (seconds)',\n type: 'number',\n },\n {\n name: 'lightbox',\n description:\n 'Show the poster as a play button and open the film full size in a ' +\n 'dialog. Needs a poster image; without one the player stays in the ' +\n \"page. A Wistia video's poster waits for a press either way, and the \" +\n 'video plays in place of the poster when this is off. A Wistia player ' +\n 'that loads with the page stays in the page.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Open in a lightbox',\n },\n {\n name: 'loadPlayer',\n description:\n \"For a Wistia video: show Wistia's player as soon as the page loads, \" +\n 'instead of a poster to press, to visitors whose privacy choices ' +\n 'allow analytics. Everyone else still gets the poster. Use it on a ' +\n 'page built to show this one video, so search engines can find the ' +\n 'player. The player stays in the page even with the lightbox on.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Load the player with the page',\n },\n {\n name: 'preload',\n description:\n 'How much to fetch before anyone presses play. Leave unset and a ' +\n 'video with a poster fetches nothing at all.',\n component: Aglyn.FieldComponentType.SELECT,\n label: 'Preload',\n // Real sentinels, never `''` (AGL-1451): each of these is a member of\n // the declared `VideoPreload` union, so a video switched to Metadata\n // can be switched back.\n options: [\n { value: 'none', label: 'Nothing until play (default with a poster)' },\n { value: 'metadata', label: 'Length and dimensions only' },\n { value: 'auto', label: 'As much as the browser likes' },\n ],\n },\n {\n name: 'controls',\n description: 'Show the browser playback controls (on by default).',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'Controls',\n },\n {\n name: 'autoPlay',\n description: 'Start playback automatically (mutes the video).',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'Autoplay',\n },\n {\n name: 'loop',\n description: 'Restart the video when it ends.',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'Loop',\n },\n {\n name: 'muted',\n description: 'Play without sound.',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'Muted',\n },\n {\n name: 'playsInline',\n description:\n 'Keep the video in the page on a phone instead of taking over the ' +\n 'whole screen (on by default).',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'Play inline on phones',\n },\n {\n name: 'captionsSrc',\n description:\n 'A WebVTT captions file (.vtt) for this video — pick it with ' +\n '\"Browse media\" or paste its URL.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Captions file',\n },\n {\n name: 'captionsLabel',\n description:\n 'What to call the captions track in the player menu, e.g. English.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Captions label',\n condition: HAS_CAPTIONS,\n },\n {\n name: 'captionsLang',\n description:\n 'The language code of the captions, e.g. en or es — it tells the ' +\n 'browser which track to offer.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Captions language',\n condition: HAS_CAPTIONS,\n },\n {\n name: 'width',\n description:\n 'Width of the player — a number plus a unit, e.g. 100% or 640px.',\n component: Aglyn.FieldComponentType.CSS_DIMENSION,\n label: 'Width',\n },\n {\n name: 'height',\n description: 'Height of the player. Leave empty for auto.',\n component: Aglyn.FieldComponentType.CSS_DIMENSION,\n label: 'Height',\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Video',\n pluginId: BUNDLE_ID,\n description: 'Video from your media library or any URL',\n category: Aglyn.ComponentCategory.MEDIA,\n icon: {\n path: mdiVideo.path,\n sx: { color: '#7b1fa2' },\n },\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n]\n\nexport default Video\n"],"names":["Aglyn","readStoredVisitorConsent","VISITOR_CONSENT_CHANGED_EVENT","wistiaMediaId","wistiaPlayerSrc","mdiPlay","mdiVideo","MdiIcon","Box","useEventCallback","useForkRef","Suspense","forwardRef","lazy","useCallback","useEffect","useState","BUNDLE_ID","generatePresetId","useVideoPlaybackBeacon","VideoPlayerFrame","VideoLightbox","then","module","default","ID","POSTER_REQUEST_WIDTH","MEDIA_CDN_POSTER_WIDTH","resolveVideoPreload","options","preload","poster","autoPlay","Video","props","ref","src","storedSrc","storedPoster","posterFromSource","title","description","_description","uploadDate","_uploadDate","durationSeconds","_durationSeconds","lightbox","loadPlayer","captionsSrc","captionsLabel","captionsLang","loop","muted","controls","playsInline","width","height","intrinsicWidth","intrinsicHeight","radius","children","_children","sx","nodeSxProp","rest","nodeSx","Array","isArray","hostId","useSite","videoDeliverySrc","posterFor","videoPosterSrc","generated","posterBase","captions","resolveMediaSrc","open","setOpen","armed","setArmed","arm","closeLightbox","openLightbox","editorInert","suppressNavigation","useScreenLink","undefined","playback","suppressed","playbackHandlers","wistiaId","playerSrc","setPlayerSrc","playWistia","doNotTrack","analytics","Boolean","pageLoadSrc","setPageLoadSrc","sync","window","addEventListener","removeEventListener","loadedSrc","inPlaceSrc","press","answerVideoCommand","element","HTMLVideoElement","Promise","resolve","play","catch","root","setRoot","rootRef","subscribeVideoCommands","placeholder","label","display","alignItems","justifyContent","border","borderColor","borderRadius","color","fontSize","fontFamily","usable","value","Number","isFinite","aspectRatio","track","kind","srcLang","position","focusOnMount","playsInPlace","component","type","onClick","onPointerEnter","onFocus","aria-label","appearance","p","m","font","background","cursor","overflow","outline","outlineColor","outlineOffset","srcSet","isMediaCdnUrl","MEDIA_CDN_VARIANT_WIDTHS","map","variant","candidate","filter","join","sizes","alt","decoding","objectFit","aria-hidden","top","left","transform","xs","sm","md","bgcolor","boxShadow","transition","path","ml","fallback","onClose","embedSrc","onPlay","onTimeUpdate","onEnded","displayName","HAS_CAPTIONS","when","isNotEmpty","schema","$id","pluginId","category","ComponentCategory","MEDIA","icon","flags","selfClosing","FEATURE_FLAG","ENABLED","attributes","name","FieldComponentType","TEXT_FIELD","TEXTAREA","SWITCH","SELECT","CHECKBOX","condition","CSS_DIMENSION","presets","NodeType","PRESET","data","componentId"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
export declare const BUNDLE_ID = "mui";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ export const BUNDLE_ID = 'mui';
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=bundle-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/constants/bundle-common.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2021 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\nexport const BUNDLE_ID = 'mui'\n"],"names":["BUNDLE_ID"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,OAAO,MAAMA,YAAY,MAAK"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { AglynAttributeSchema } from '@aglyn/aglyn';
|
|
18
|
+
/**
|
|
19
|
+
* Theme colour for Button and Screen Link.
|
|
20
|
+
*
|
|
21
|
+
* The `{ value: '', label: 'Default' }` option was DELETED (AGL-1453). It could
|
|
22
|
+
* not persist — the attributes form strips `''` on change (AGL-1191) — so the
|
|
23
|
+
* pick silently reverted, and it was a second name for a choice already on the
|
|
24
|
+
* list: MUI's own default for both components is `primary`, offered below.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately NOT replaced with a `'primary'` sentinel, which is where this
|
|
27
|
+
* differs from the props that got one. "Default" means *unset*, and unset is
|
|
28
|
+
* load-bearing: MUI reads a component's props through `useDefaultProps`, which
|
|
29
|
+
* applies a host theme's `components.MuiButton.defaultProps.color` to
|
|
30
|
+
* `undefined` ONLY. A sentinel would pin `primary` and bypass the host's own
|
|
31
|
+
* default — the opposite of what an author asking for "Default" wants. Unset
|
|
32
|
+
* stays expressible through the field's ✕, which persists `null`, and
|
|
33
|
+
* `dropClearedProps` turns that back into `undefined` at the boundary.
|
|
34
|
+
*/
|
|
35
|
+
export declare const FIELD_COLOR: AglynAttributeSchema;
|
|
36
|
+
/**
|
|
37
|
+
* App Bar theme colors. Unlike the base FIELD_COLOR (where "Default" means
|
|
38
|
+
* "unset — let the component decide"), MUI AppBar's `color="default"` is a
|
|
39
|
+
* real value DISTINCT from its implicit default (`primary`), so the option
|
|
40
|
+
* must persist. An empty-string option value never can: the attributes form
|
|
41
|
+
* strips `''` on change (ddf's enhancedOnChange maps an emptied field to its
|
|
42
|
+
* clearedValue, and final-form's default parse turns `''` into `undefined`),
|
|
43
|
+
* so the prop key vanished before save and the pick silently reverted on
|
|
44
|
+
* reload (AGL-1191). Persist the explicit `'default'` sentinel instead; an
|
|
45
|
+
* author who wants "unset" clears the field with the ✕ affordance.
|
|
46
|
+
*/
|
|
47
|
+
export declare const FIELD_COLOR_ALT1: AglynAttributeSchema;
|
|
48
|
+
export declare const FIELD_DISABLED: AglynAttributeSchema;
|
|
49
|
+
export declare const FIELD_FULL_WIDTH: AglynAttributeSchema;
|
|
50
|
+
export declare const FIELD_DISABLE_GUTTERS: AglynAttributeSchema;
|
|
51
|
+
/**
|
|
52
|
+
* Size for Button and Screen Link. Pagination replaces the option list.
|
|
53
|
+
*
|
|
54
|
+
* `{ value: '', label: 'Default' }` deleted for the same reason as
|
|
55
|
+
* FIELD_COLOR's (AGL-1453): unpersistable, and a second name for `medium`,
|
|
56
|
+
* which is MUI's own default and is already on the list.
|
|
57
|
+
*/
|
|
58
|
+
export declare const FIELD_SIZE: AglynAttributeSchema;
|
|
59
|
+
/**
|
|
60
|
+
* App Bar positioning.
|
|
61
|
+
*
|
|
62
|
+
* `{ value: '', label: 'Default' }` deleted (AGL-1453): unpersistable, and a
|
|
63
|
+
* second name for `fixed`, MUI AppBar's own default, already on the list.
|
|
64
|
+
*/
|
|
65
|
+
export declare const FIELD_POSITION: AglynAttributeSchema;
|
|
66
|
+
/**
|
|
67
|
+
* Text content of a text-capable component (`children` prop). Pair with the
|
|
68
|
+
* `textEditable` schema flag so editor surfaces know the component renders
|
|
69
|
+
* its children as editable text.
|
|
70
|
+
*/
|
|
71
|
+
export declare const FIELD_TEXT_CONTENT: AglynAttributeSchema;
|
|
72
|
+
/**
|
|
73
|
+
* Where a link opens, for the elements that render through `AppLink`.
|
|
74
|
+
*
|
|
75
|
+
* `'_self'` is a REAL SENTINEL, not a deletion, for the reason `renderAs`
|
|
76
|
+
* carries one: the attributes form strips `''` before save (AGL-1191), so an
|
|
77
|
+
* `{ value: '', label: 'Same tab' }` option could not persist and a link
|
|
78
|
+
* switched to a new tab would have no route in this dropdown back. It is
|
|
79
|
+
* safe to store because `linkTargetProps` resolves it to no attribute at
|
|
80
|
+
* all, which is exactly what an unset target already renders.
|
|
81
|
+
*
|
|
82
|
+
* Deliberately no separate "New window" option. `target="_blank"` asks for a
|
|
83
|
+
* new browsing context and the browser — not the page — decides whether that
|
|
84
|
+
* is a tab or a window, so a second label would be a second name for one
|
|
85
|
+
* behavior. Authors who need a specific named window pick Custom and name it.
|
|
86
|
+
*/
|
|
87
|
+
export declare const FIELD_LINK_TARGET: AglynAttributeSchema;
|
|
88
|
+
/**
|
|
89
|
+
* The name behind FIELD_LINK_TARGET's Custom choice. Shown only for that
|
|
90
|
+
* choice — on its own it is an advanced affordance, and offering a free-text
|
|
91
|
+
* box beside the dropdown would invite `_blank` being typed into it.
|
|
92
|
+
*/
|
|
93
|
+
export declare const FIELD_LINK_TARGET_NAME: AglynAttributeSchema;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2022 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { FieldComponentType } from "@aglyn/aglyn";
|
|
18
|
+
/**
|
|
19
|
+
* Theme colour for Button and Screen Link.
|
|
20
|
+
*
|
|
21
|
+
* The `{ value: '', label: 'Default' }` option was DELETED (AGL-1453). It could
|
|
22
|
+
* not persist — the attributes form strips `''` on change (AGL-1191) — so the
|
|
23
|
+
* pick silently reverted, and it was a second name for a choice already on the
|
|
24
|
+
* list: MUI's own default for both components is `primary`, offered below.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately NOT replaced with a `'primary'` sentinel, which is where this
|
|
27
|
+
* differs from the props that got one. "Default" means *unset*, and unset is
|
|
28
|
+
* load-bearing: MUI reads a component's props through `useDefaultProps`, which
|
|
29
|
+
* applies a host theme's `components.MuiButton.defaultProps.color` to
|
|
30
|
+
* `undefined` ONLY. A sentinel would pin `primary` and bypass the host's own
|
|
31
|
+
* default — the opposite of what an author asking for "Default" wants. Unset
|
|
32
|
+
* stays expressible through the field's ✕, which persists `null`, and
|
|
33
|
+
* `dropClearedProps` turns that back into `undefined` at the boundary.
|
|
34
|
+
*/ export const FIELD_COLOR = {
|
|
35
|
+
name: 'color',
|
|
36
|
+
description: 'The color of the component. It supports those theme colors that make sense for this component.',
|
|
37
|
+
component: FieldComponentType.SELECT,
|
|
38
|
+
label: 'Theme color',
|
|
39
|
+
options: [
|
|
40
|
+
{
|
|
41
|
+
value: 'inherit',
|
|
42
|
+
label: 'Inherit'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
value: 'primary',
|
|
46
|
+
label: 'Primary'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
value: 'secondary',
|
|
50
|
+
label: 'Secondary'
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
value: 'success',
|
|
54
|
+
label: 'Success'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
value: 'error',
|
|
58
|
+
label: 'Error'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
value: 'info',
|
|
62
|
+
label: 'Info'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
value: 'warning',
|
|
66
|
+
label: 'Warning'
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* App Bar theme colors. Unlike the base FIELD_COLOR (where "Default" means
|
|
72
|
+
* "unset — let the component decide"), MUI AppBar's `color="default"` is a
|
|
73
|
+
* real value DISTINCT from its implicit default (`primary`), so the option
|
|
74
|
+
* must persist. An empty-string option value never can: the attributes form
|
|
75
|
+
* strips `''` on change (ddf's enhancedOnChange maps an emptied field to its
|
|
76
|
+
* clearedValue, and final-form's default parse turns `''` into `undefined`),
|
|
77
|
+
* so the prop key vanished before save and the pick silently reverted on
|
|
78
|
+
* reload (AGL-1191). Persist the explicit `'default'` sentinel instead; an
|
|
79
|
+
* author who wants "unset" clears the field with the ✕ affordance.
|
|
80
|
+
*/ export const FIELD_COLOR_ALT1 = _extends({}, FIELD_COLOR, {
|
|
81
|
+
options: [
|
|
82
|
+
{
|
|
83
|
+
value: 'default',
|
|
84
|
+
label: 'Default'
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
value: 'inherit',
|
|
88
|
+
label: 'Inherit'
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
value: 'transparent',
|
|
92
|
+
label: 'Transparent'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
value: 'primary',
|
|
96
|
+
label: 'Primary'
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
value: 'secondary',
|
|
100
|
+
label: 'Secondary'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
value: 'tertiary',
|
|
104
|
+
label: 'Tertiary'
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
export const FIELD_DISABLED = {
|
|
109
|
+
name: 'disabled',
|
|
110
|
+
description: 'If true, the component is disabled.',
|
|
111
|
+
component: FieldComponentType.SWITCH,
|
|
112
|
+
label: 'Disabled?'
|
|
113
|
+
};
|
|
114
|
+
export const FIELD_FULL_WIDTH = {
|
|
115
|
+
name: 'fullWidth',
|
|
116
|
+
description: 'If true, the button will take up the full width of its container.',
|
|
117
|
+
component: FieldComponentType.SWITCH,
|
|
118
|
+
label: 'Full width?'
|
|
119
|
+
};
|
|
120
|
+
export const FIELD_DISABLE_GUTTERS = {
|
|
121
|
+
name: 'disableGutters',
|
|
122
|
+
description: 'If true, disables gutter padding.',
|
|
123
|
+
component: FieldComponentType.SWITCH,
|
|
124
|
+
label: 'Disable gutters?'
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Size for Button and Screen Link. Pagination replaces the option list.
|
|
128
|
+
*
|
|
129
|
+
* `{ value: '', label: 'Default' }` deleted for the same reason as
|
|
130
|
+
* FIELD_COLOR's (AGL-1453): unpersistable, and a second name for `medium`,
|
|
131
|
+
* which is MUI's own default and is already on the list.
|
|
132
|
+
*/ export const FIELD_SIZE = {
|
|
133
|
+
name: 'size',
|
|
134
|
+
description: 'The size of the component. small is equivalent to the dense button styling.',
|
|
135
|
+
component: FieldComponentType.SELECT,
|
|
136
|
+
label: 'Size',
|
|
137
|
+
options: [
|
|
138
|
+
{
|
|
139
|
+
value: 'inherit',
|
|
140
|
+
label: 'Inherit'
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
value: 'small',
|
|
144
|
+
label: 'Small'
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
value: 'medium',
|
|
148
|
+
label: 'Medium'
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
value: 'large',
|
|
152
|
+
label: 'Large'
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* App Bar positioning.
|
|
158
|
+
*
|
|
159
|
+
* `{ value: '', label: 'Default' }` deleted (AGL-1453): unpersistable, and a
|
|
160
|
+
* second name for `fixed`, MUI AppBar's own default, already on the list.
|
|
161
|
+
*/ export const FIELD_POSITION = {
|
|
162
|
+
name: 'position',
|
|
163
|
+
description: 'The positioning type. The behavior of the different options is described in the MDN web docs. Note: sticky is not universally supported and will fall back to static when unavailable.',
|
|
164
|
+
component: FieldComponentType.SELECT,
|
|
165
|
+
label: 'Position',
|
|
166
|
+
options: [
|
|
167
|
+
{
|
|
168
|
+
value: 'absolute',
|
|
169
|
+
label: 'Absolute'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
value: 'fixed',
|
|
173
|
+
label: 'Fixed'
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
value: 'relative',
|
|
177
|
+
label: 'Relative'
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
value: 'static',
|
|
181
|
+
label: 'Static'
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
value: 'sticky',
|
|
185
|
+
label: 'Sticky'
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Text content of a text-capable component (`children` prop). Pair with the
|
|
191
|
+
* `textEditable` schema flag so editor surfaces know the component renders
|
|
192
|
+
* its children as editable text.
|
|
193
|
+
*/ export const FIELD_TEXT_CONTENT = {
|
|
194
|
+
name: 'children',
|
|
195
|
+
description: 'The text content this element displays.',
|
|
196
|
+
component: FieldComponentType.TEXTAREA,
|
|
197
|
+
label: 'Text'
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Where a link opens, for the elements that render through `AppLink`.
|
|
201
|
+
*
|
|
202
|
+
* `'_self'` is a REAL SENTINEL, not a deletion, for the reason `renderAs`
|
|
203
|
+
* carries one: the attributes form strips `''` before save (AGL-1191), so an
|
|
204
|
+
* `{ value: '', label: 'Same tab' }` option could not persist and a link
|
|
205
|
+
* switched to a new tab would have no route in this dropdown back. It is
|
|
206
|
+
* safe to store because `linkTargetProps` resolves it to no attribute at
|
|
207
|
+
* all, which is exactly what an unset target already renders.
|
|
208
|
+
*
|
|
209
|
+
* Deliberately no separate "New window" option. `target="_blank"` asks for a
|
|
210
|
+
* new browsing context and the browser — not the page — decides whether that
|
|
211
|
+
* is a tab or a window, so a second label would be a second name for one
|
|
212
|
+
* behavior. Authors who need a specific named window pick Custom and name it.
|
|
213
|
+
*/ export const FIELD_LINK_TARGET = {
|
|
214
|
+
name: 'target',
|
|
215
|
+
description: 'Where this opens. Same tab keeps the visitor on the site with their ' + 'history intact, which is what internal navigation should do; New tab ' + 'suits a download or an outside site you want them to come back from.',
|
|
216
|
+
component: FieldComponentType.SELECT,
|
|
217
|
+
label: 'Open link in',
|
|
218
|
+
options: [
|
|
219
|
+
{
|
|
220
|
+
value: '_self',
|
|
221
|
+
label: 'Same tab'
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
value: '_blank',
|
|
225
|
+
label: 'New tab'
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
value: 'custom',
|
|
229
|
+
label: 'Custom window name'
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* The name behind FIELD_LINK_TARGET's Custom choice. Shown only for that
|
|
235
|
+
* choice — on its own it is an advanced affordance, and offering a free-text
|
|
236
|
+
* box beside the dropdown would invite `_blank` being typed into it.
|
|
237
|
+
*/ export const FIELD_LINK_TARGET_NAME = {
|
|
238
|
+
name: 'targetName',
|
|
239
|
+
description: 'Name of the window to open in. Every link sharing a name reuses that ' + 'one window instead of opening another, which is how a set of links ' + 'can drive a single companion window.',
|
|
240
|
+
component: FieldComponentType.TEXT_FIELD,
|
|
241
|
+
label: 'Window name',
|
|
242
|
+
condition: {
|
|
243
|
+
when: 'target',
|
|
244
|
+
is: 'custom'
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
//# sourceMappingURL=field-presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/constants/field-presets.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 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 AglynAttributeSchema,\n FieldComponentType,\n} from '@aglyn/aglyn'\n\n/**\n * Theme colour for Button and Screen Link.\n *\n * The `{ value: '', label: 'Default' }` option was DELETED (AGL-1453). It could\n * not persist — the attributes form strips `''` on change (AGL-1191) — so the\n * pick silently reverted, and it was a second name for a choice already on the\n * list: MUI's own default for both components is `primary`, offered below.\n *\n * Deliberately NOT replaced with a `'primary'` sentinel, which is where this\n * differs from the props that got one. \"Default\" means *unset*, and unset is\n * load-bearing: MUI reads a component's props through `useDefaultProps`, which\n * applies a host theme's `components.MuiButton.defaultProps.color` to\n * `undefined` ONLY. A sentinel would pin `primary` and bypass the host's own\n * default — the opposite of what an author asking for \"Default\" wants. Unset\n * stays expressible through the field's ✕, which persists `null`, and\n * `dropClearedProps` turns that back into `undefined` at the boundary.\n */\nexport const FIELD_COLOR: AglynAttributeSchema = {\n name: 'color',\n description:\n 'The color of the component. It supports those theme colors that make sense for this component.',\n component: FieldComponentType.SELECT,\n label: 'Theme color',\n options: [\n { value: 'inherit', label: 'Inherit' },\n { value: 'primary', label: 'Primary' },\n { value: 'secondary', label: 'Secondary' },\n { value: 'success', label: 'Success' },\n { value: 'error', label: 'Error' },\n { value: 'info', label: 'Info' },\n { value: 'warning', label: 'Warning' },\n ],\n}\n/**\n * App Bar theme colors. Unlike the base FIELD_COLOR (where \"Default\" means\n * \"unset — let the component decide\"), MUI AppBar's `color=\"default\"` is a\n * real value DISTINCT from its implicit default (`primary`), so the option\n * must persist. An empty-string option value never can: the attributes form\n * strips `''` on change (ddf's enhancedOnChange maps an emptied field to its\n * clearedValue, and final-form's default parse turns `''` into `undefined`),\n * so the prop key vanished before save and the pick silently reverted on\n * reload (AGL-1191). Persist the explicit `'default'` sentinel instead; an\n * author who wants \"unset\" clears the field with the ✕ affordance.\n */\nexport const FIELD_COLOR_ALT1: AglynAttributeSchema = {\n ...FIELD_COLOR,\n options: [\n { value: 'default', label: 'Default' },\n { value: 'inherit', label: 'Inherit' },\n { value: 'transparent', label: 'Transparent' },\n { value: 'primary', label: 'Primary' },\n { value: 'secondary', label: 'Secondary' },\n { value: 'tertiary', label: 'Tertiary' },\n ],\n}\nexport const FIELD_DISABLED: AglynAttributeSchema = {\n name: 'disabled',\n description: 'If true, the component is disabled.',\n component: FieldComponentType.SWITCH,\n label: 'Disabled?',\n}\nexport const FIELD_FULL_WIDTH: AglynAttributeSchema = {\n name: 'fullWidth',\n description:\n 'If true, the button will take up the full width of its container.',\n component: FieldComponentType.SWITCH,\n label: 'Full width?',\n}\nexport const FIELD_DISABLE_GUTTERS: AglynAttributeSchema = {\n name: 'disableGutters',\n description: 'If true, disables gutter padding.',\n component: FieldComponentType.SWITCH,\n label: 'Disable gutters?',\n}\n/**\n * Size for Button and Screen Link. Pagination replaces the option list.\n *\n * `{ value: '', label: 'Default' }` deleted for the same reason as\n * FIELD_COLOR's (AGL-1453): unpersistable, and a second name for `medium`,\n * which is MUI's own default and is already on the list.\n */\nexport const FIELD_SIZE: AglynAttributeSchema = {\n name: 'size',\n description:\n 'The size of the component. small is equivalent to the dense button styling.',\n component: FieldComponentType.SELECT,\n label: 'Size',\n options: [\n { value: 'inherit', label: 'Inherit' },\n { value: 'small', label: 'Small' },\n { value: 'medium', label: 'Medium' },\n { value: 'large', label: 'Large' },\n ],\n}\n/**\n * App Bar positioning.\n *\n * `{ value: '', label: 'Default' }` deleted (AGL-1453): unpersistable, and a\n * second name for `fixed`, MUI AppBar's own default, already on the list.\n */\nexport const FIELD_POSITION: AglynAttributeSchema = {\n name: 'position',\n description:\n 'The positioning type. The behavior of the different options is described in the MDN web docs. Note: sticky is not universally supported and will fall back to static when unavailable.',\n component: FieldComponentType.SELECT,\n label: 'Position',\n options: [\n { value: 'absolute', label: 'Absolute' },\n { value: 'fixed', label: 'Fixed' },\n { value: 'relative', label: 'Relative' },\n { value: 'static', label: 'Static' },\n { value: 'sticky', label: 'Sticky' },\n ],\n}\n/**\n * Text content of a text-capable component (`children` prop). Pair with the\n * `textEditable` schema flag so editor surfaces know the component renders\n * its children as editable text.\n */\nexport const FIELD_TEXT_CONTENT: AglynAttributeSchema = {\n name: 'children',\n description: 'The text content this element displays.',\n component: FieldComponentType.TEXTAREA,\n label: 'Text',\n}\n\n/**\n * Where a link opens, for the elements that render through `AppLink`.\n *\n * `'_self'` is a REAL SENTINEL, not a deletion, for the reason `renderAs`\n * carries one: the attributes form strips `''` before save (AGL-1191), so an\n * `{ value: '', label: 'Same tab' }` option could not persist and a link\n * switched to a new tab would have no route in this dropdown back. It is\n * safe to store because `linkTargetProps` resolves it to no attribute at\n * all, which is exactly what an unset target already renders.\n *\n * Deliberately no separate \"New window\" option. `target=\"_blank\"` asks for a\n * new browsing context and the browser — not the page — decides whether that\n * is a tab or a window, so a second label would be a second name for one\n * behavior. Authors who need a specific named window pick Custom and name it.\n */\nexport const FIELD_LINK_TARGET: AglynAttributeSchema = {\n name: 'target',\n description:\n 'Where this opens. Same tab keeps the visitor on the site with their ' +\n 'history intact, which is what internal navigation should do; New tab ' +\n 'suits a download or an outside site you want them to come back from.',\n component: FieldComponentType.SELECT,\n label: 'Open link in',\n options: [\n { value: '_self', label: 'Same tab' },\n { value: '_blank', label: 'New tab' },\n { value: 'custom', label: 'Custom window name' },\n ],\n}\n/**\n * The name behind FIELD_LINK_TARGET's Custom choice. Shown only for that\n * choice — on its own it is an advanced affordance, and offering a free-text\n * box beside the dropdown would invite `_blank` being typed into it.\n */\nexport const FIELD_LINK_TARGET_NAME: AglynAttributeSchema = {\n name: 'targetName',\n description:\n 'Name of the window to open in. Every link sharing a name reuses that ' +\n 'one window instead of opening another, which is how a set of links ' +\n 'can drive a single companion window.',\n component: FieldComponentType.TEXT_FIELD,\n label: 'Window name',\n condition: { when: 'target', is: 'custom' },\n}\n"],"names":["FieldComponentType","FIELD_COLOR","name","description","component","SELECT","label","options","value","FIELD_COLOR_ALT1","FIELD_DISABLED","SWITCH","FIELD_FULL_WIDTH","FIELD_DISABLE_GUTTERS","FIELD_SIZE","FIELD_POSITION","FIELD_TEXT_CONTENT","TEXTAREA","FIELD_LINK_TARGET","FIELD_LINK_TARGET_NAME","TEXT_FIELD","condition","when","is"],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import * as Aglyn from '@aglyn/aglyn';
|
|
18
|
+
/** One entry of the bundle: what the registry is handed for a component. */
|
|
19
|
+
export interface MuiBundleEntry {
|
|
20
|
+
component: any;
|
|
21
|
+
schema: Aglyn.ComponentSchema<any>;
|
|
22
|
+
presets?: Aglyn.PresetSchema[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Where a component id's code lives, and what it is called there (AGL-3141).
|
|
26
|
+
*
|
|
27
|
+
* An id names a module AND an export on it, never a module alone: several
|
|
28
|
+
* modules export more than one element, and the registry needs the component,
|
|
29
|
+
* its schema and — for the element that carries them — its presets by name.
|
|
30
|
+
*/
|
|
31
|
+
export interface MuiComponentSource {
|
|
32
|
+
/** The module, as a thunk, so the bundler gives it a chunk of its own. */
|
|
33
|
+
module: () => Promise<Record<string, unknown>>;
|
|
34
|
+
/** The component's export name on that module. */
|
|
35
|
+
component: string;
|
|
36
|
+
/** Its schema's export name. */
|
|
37
|
+
schema: string;
|
|
38
|
+
/** The export carrying its presets, for the element that ships them. */
|
|
39
|
+
presets?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Every component this bundle can register (AGL-140, AGL-3141).
|
|
43
|
+
*
|
|
44
|
+
* One entry per component keeps register/unregister symmetric — the old
|
|
45
|
+
* hand-maintained lists had drifted, and several components were never
|
|
46
|
+
* unregistered on destroy. It replaces a single array built from sixty static
|
|
47
|
+
* imports, which put every element on every published page while the page
|
|
48
|
+
* rendered about nineteen of them.
|
|
49
|
+
*
|
|
50
|
+
* Exported so the bundle is assertable (AGL-1201): duplicate component or
|
|
51
|
+
* preset ids collapse silently inside the registry's keyed records, so they
|
|
52
|
+
* can only be caught before registration.
|
|
53
|
+
*/
|
|
54
|
+
export declare const MUI_COMPONENT_SOURCES: Readonly<Record<string, MuiComponentSource>>;
|
|
55
|
+
/**
|
|
56
|
+
* The bundle entries for `componentIds` — every component when none are
|
|
57
|
+
* named, which is what the console and the besigner ask for because their
|
|
58
|
+
* palette shows every element.
|
|
59
|
+
*
|
|
60
|
+
* Both paths go through the same map, so there is one statement of where a
|
|
61
|
+
* component comes from. An id the map does not know is dropped rather than
|
|
62
|
+
* resolved to an undefined component: a page whose document carries an
|
|
63
|
+
* element this bundle does not own is a document for another plugin's
|
|
64
|
+
* element, not a reason to register a blank.
|
|
65
|
+
*/
|
|
66
|
+
export declare function loadMuiBundle(componentIds?: readonly string[]): Promise<MuiBundleEntry[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Registers the core MUI component library with the `@aglyn/aglyn` global
|
|
69
|
+
* plugin registry (`AglynNodeRenderer`, `Aglyn.canvas`, ...). This is the
|
|
70
|
+
* platform's core component bundle; feature bundles (commerce,
|
|
71
|
+
* events-calendar, email) declare a dependency on it.
|
|
72
|
+
*
|
|
73
|
+
* `use.componentIds` narrows it to the elements the surface places
|
|
74
|
+
* (AGL-3116/AGL-3141), so a published page fetches those modules and no
|
|
75
|
+
* others. A caller that names nothing gets the whole library, which is what
|
|
76
|
+
* the console and the besigner need and what any surface that cannot say
|
|
77
|
+
* what it places must be given: an element whose component never registered
|
|
78
|
+
* renders NOTHING, silently (AGL-52).
|
|
79
|
+
*/
|
|
80
|
+
export declare function registerMuiPlugin(use?: Aglyn.PluginUse): Promise<void>;
|