@aglyn/shared-ui-jsx 1.0.0-beta.258 → 1.0.0-beta.260

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/shared-ui-jsx",
3
- "version": "1.0.0-beta.258",
3
+ "version": "1.0.0-beta.260",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,10 +25,10 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/shared-data-mdi": "1.0.0-beta.258",
29
- "@aglyn/shared-ui-theme": "1.0.0-beta.258",
30
- "@aglyn/shared-util-tools": "1.0.0-beta.258",
31
- "@aglyn/shared-util-vendor": "1.0.0-beta.258",
28
+ "@aglyn/shared-data-mdi": "1.0.0-beta.260",
29
+ "@aglyn/shared-ui-theme": "1.0.0-beta.260",
30
+ "@aglyn/shared-util-tools": "1.0.0-beta.260",
31
+ "@aglyn/shared-util-vendor": "1.0.0-beta.260",
32
32
  "@mdi/js": "^7.4.47",
33
33
  "@swc/helpers": "0.5.23",
34
34
  "change-case": "^5.4.4",
@@ -15,6 +15,12 @@ export interface BlockedControlProps {
15
15
  children: ReactElement<{
16
16
  disabled?: boolean;
17
17
  }>;
18
+ /**
19
+ * Let the wrapper take the full width, for a control that is `fullWidth`
20
+ * or stretched by its stack. The wrapping span is otherwise as wide as its
21
+ * content, which shrinks such a control the moment it is blocked.
22
+ */
23
+ fullWidth?: boolean;
18
24
  }
19
25
  /**
20
26
  * Renders a control disabled with the reason attached, or passes it through
@@ -44,7 +50,7 @@ export interface BlockedControlProps {
44
50
  * of what rendered. It exists so a console stops promising what the server
45
51
  * will refuse.
46
52
  */
47
- export declare function BlockedControl({ blocked, reason, children }: BlockedControlProps): import("react").JSX.Element;
53
+ export declare function BlockedControl({ blocked, reason, children, fullWidth }: BlockedControlProps): import("react").JSX.Element;
48
54
  export declare namespace BlockedControl {
49
55
  var displayName: string;
50
56
  var aglyn: boolean;
@@ -44,7 +44,7 @@ import { cloneElement, isValidElement } from "react";
44
44
  * agreeing. THIS IS NOT A SECURITY BOUNDARY: the server refuses regardless
45
45
  * of what rendered. It exists so a console stops promising what the server
46
46
  * will refuse.
47
- */ export function BlockedControl({ blocked, reason, children }) {
47
+ */ export function BlockedControl({ blocked, reason, children, fullWidth }) {
48
48
  if (!blocked || !/*#__PURE__*/ isValidElement(children)) return children;
49
49
  return /*#__PURE__*/ _jsx(Tooltip, {
50
50
  title: reason,
@@ -52,7 +52,13 @@ import { cloneElement, isValidElement } from "react";
52
52
  component: "span",
53
53
  "aria-label": reason,
54
54
  title: reason,
55
- sx: {
55
+ sx: fullWidth ? {
56
+ display: 'flex',
57
+ width: '100%',
58
+ '& > *': {
59
+ flex: 1
60
+ }
61
+ } : {
56
62
  display: 'inline-flex'
57
63
  },
58
64
  children: /*#__PURE__*/ cloneElement(children, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/blocked-control.component.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'use client'\n\nimport { Box, Tooltip } from '@mui/material'\nimport { cloneElement, isValidElement, type ReactElement } from 'react'\n\nexport interface BlockedControlProps {\n /**\n * Whether the viewer's standing is RESOLVED and refused. Never true while\n * a claim is still loading: rendering the refusal in that window flashes a\n * disabled button at everybody, including the people who may use it.\n */\n blocked: boolean\n /** Why, in one sentence. Shown on hover, and to a screen reader. */\n reason: string\n /**\n * A single control that accepts a `disabled` prop — MUI's Button,\n * IconButton, Switch, TextField and friends all do.\n */\n children: ReactElement<{ disabled?: boolean }>\n}\n\n/**\n * Renders a control disabled with the reason attached, or passes it through\n * untouched.\n *\n * DISABLED WITH THE REASON, NOT HIDDEN. Both are defensible and the choice is\n * made here once rather than at every gate. Hiding leaves a reader unable to\n * see that the capability exists at all, and the commonest support act is\n * routing — \"this needs someone with the super role\" is an answer they can\n * give in one message; \"I see no such button\" turns into an investigation of\n * whether the feature shipped.\n *\n * ## Two details that are the whole reason this is shared\n *\n * The tooltip wraps a `span`, not the control: MUI does not fire pointer\n * events on a disabled button, so a tooltip attached directly to one never\n * appears — which would leave a dead button and no reason at all, the exact\n * failure this exists to stop.\n *\n * And the reason lands on the span as a real `aria-label` and `title`, not\n * only inside the Tooltip's popper. An explanation that appears only on\n * hover says nothing to a screen reader and nothing on a touch device.\n *\n * Both were got right once and then copied; AGL-2113 is the precedent for\n * what copies do — five quota readouts grew their own phrasing and stopped\n * agreeing. THIS IS NOT A SECURITY BOUNDARY: the server refuses regardless\n * of what rendered. It exists so a console stops promising what the server\n * will refuse.\n */\nexport function BlockedControl({ blocked, reason, children }: BlockedControlProps) {\n if (!blocked || !isValidElement(children)) return children\n return (\n <Tooltip title={reason}>\n <Box\n component=\"span\"\n aria-label={reason}\n title={reason}\n sx={{ display: 'inline-flex' }}\n >\n {cloneElement(children, { disabled: true })}\n </Box>\n </Tooltip>\n )\n}\n\nBlockedControl.displayName = 'BlockedControl'\nBlockedControl.aglyn = true\n\nexport default BlockedControl\n"],"names":["Box","Tooltip","cloneElement","isValidElement","BlockedControl","blocked","reason","children","title","component","aria-label","sx","display","disabled","displayName","aglyn"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,GAAG,EAAEC,OAAO,QAAQ,gBAAe;AAC5C,SAASC,YAAY,EAAEC,cAAc,QAA2B,QAAO;AAkBvE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASC,eAAe,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,EAAuB;IAC/E,IAAI,CAACF,WAAW,eAACF,eAAeI,WAAW,OAAOA;IAClD,qBACE,KAACN;QAAQO,OAAOF;kBACd,cAAA,KAACN;YACCS,WAAU;YACVC,cAAYJ;YACZE,OAAOF;YACPK,IAAI;gBAAEC,SAAS;YAAc;sBAE5BV,cAAAA,aAAaK,UAAU;gBAAEM,UAAU;YAAK;;;AAIjD;AAEAT,eAAeU,WAAW,GAAG;AAC7BV,eAAeW,KAAK,GAAG;AAEvB,eAAeX,eAAc"}
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/blocked-control.component.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'use client'\n\nimport { Box, Tooltip } from '@mui/material'\nimport { cloneElement, isValidElement, type ReactElement } from 'react'\n\nexport interface BlockedControlProps {\n /**\n * Whether the viewer's standing is RESOLVED and refused. Never true while\n * a claim is still loading: rendering the refusal in that window flashes a\n * disabled button at everybody, including the people who may use it.\n */\n blocked: boolean\n /** Why, in one sentence. Shown on hover, and to a screen reader. */\n reason: string\n /**\n * A single control that accepts a `disabled` prop — MUI's Button,\n * IconButton, Switch, TextField and friends all do.\n */\n children: ReactElement<{ disabled?: boolean }>\n /**\n * Let the wrapper take the full width, for a control that is `fullWidth`\n * or stretched by its stack. The wrapping span is otherwise as wide as its\n * content, which shrinks such a control the moment it is blocked.\n */\n fullWidth?: boolean\n}\n\n/**\n * Renders a control disabled with the reason attached, or passes it through\n * untouched.\n *\n * DISABLED WITH THE REASON, NOT HIDDEN. Both are defensible and the choice is\n * made here once rather than at every gate. Hiding leaves a reader unable to\n * see that the capability exists at all, and the commonest support act is\n * routing — \"this needs someone with the super role\" is an answer they can\n * give in one message; \"I see no such button\" turns into an investigation of\n * whether the feature shipped.\n *\n * ## Two details that are the whole reason this is shared\n *\n * The tooltip wraps a `span`, not the control: MUI does not fire pointer\n * events on a disabled button, so a tooltip attached directly to one never\n * appears — which would leave a dead button and no reason at all, the exact\n * failure this exists to stop.\n *\n * And the reason lands on the span as a real `aria-label` and `title`, not\n * only inside the Tooltip's popper. An explanation that appears only on\n * hover says nothing to a screen reader and nothing on a touch device.\n *\n * Both were got right once and then copied; AGL-2113 is the precedent for\n * what copies do — five quota readouts grew their own phrasing and stopped\n * agreeing. THIS IS NOT A SECURITY BOUNDARY: the server refuses regardless\n * of what rendered. It exists so a console stops promising what the server\n * will refuse.\n */\nexport function BlockedControl({ blocked, reason, children, fullWidth }: BlockedControlProps) {\n if (!blocked || !isValidElement(children)) return children\n return (\n <Tooltip title={reason}>\n <Box\n component=\"span\"\n aria-label={reason}\n title={reason}\n sx={fullWidth ? { display: 'flex', width: '100%', '& > *': { flex: 1 } } : { display: 'inline-flex' }}\n >\n {cloneElement(children, { disabled: true })}\n </Box>\n </Tooltip>\n )\n}\n\nBlockedControl.displayName = 'BlockedControl'\nBlockedControl.aglyn = true\n\nexport default BlockedControl\n"],"names":["Box","Tooltip","cloneElement","isValidElement","BlockedControl","blocked","reason","children","fullWidth","title","component","aria-label","sx","display","width","flex","disabled","displayName","aglyn"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,GAAG,EAAEC,OAAO,QAAQ,gBAAe;AAC5C,SAASC,YAAY,EAAEC,cAAc,QAA2B,QAAO;AAwBvE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASC,eAAe,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAuB;IAC1F,IAAI,CAACH,WAAW,eAACF,eAAeI,WAAW,OAAOA;IAClD,qBACE,KAACN;QAAQQ,OAAOH;kBACd,cAAA,KAACN;YACCU,WAAU;YACVC,cAAYL;YACZG,OAAOH;YACPM,IAAIJ,YAAY;gBAAEK,SAAS;gBAAQC,OAAO;gBAAQ,SAAS;oBAAEC,MAAM;gBAAE;YAAE,IAAI;gBAAEF,SAAS;YAAc;sBAEnGX,cAAAA,aAAaK,UAAU;gBAAES,UAAU;YAAK;;;AAIjD;AAEAZ,eAAea,WAAW,GAAG;AAC7Bb,eAAec,KAAK,GAAG;AAEvB,eAAed,eAAc"}
@@ -0,0 +1,43 @@
1
+ import { type AlertProps } from '@mui/material';
2
+ import type { ReactNode } from 'react';
3
+ export interface PrerequisiteNoticeProps {
4
+ /**
5
+ * What the feature needs first and what it unlocks, in one or two
6
+ * sentences: "Connect Stripe to take card payments at the register."
7
+ */
8
+ children: ReactNode;
9
+ /**
10
+ * Where the operator fixes it. Without one the notice still names the
11
+ * step; a notice that cannot link is better than a control that vanishes.
12
+ */
13
+ href?: string;
14
+ /** The link's label — the page or action it opens. Defaults to "Set it up". */
15
+ actionLabel?: string;
16
+ /**
17
+ * `info` for a step that unlocks something optional, `warning` when a
18
+ * setting already saved cannot work until the step is done (a deposit set
19
+ * on a store that cannot charge).
20
+ */
21
+ severity?: Extract<AlertProps['severity'], 'info' | 'warning'>;
22
+ /** Extra layout on the alert (margins in a stack, mostly). */
23
+ sx?: AlertProps['sx'];
24
+ }
25
+ /**
26
+ * Says what a feature needs before it can work, and links to where that is
27
+ * done.
28
+ *
29
+ * A control that silently disappears or fails only after it is pressed reads
30
+ * as a missing feature, and the operator has no way to learn that one setup
31
+ * step stands between them and it. This is the one place the console states a
32
+ * prerequisite an operator can fix themselves: connecting Stripe, adding a
33
+ * ship-from address, a plan that includes the feature. A gate the operator
34
+ * cannot act on — a deployment that has not configured a vendor — stays
35
+ * hidden instead, since naming it would point at a step nobody on the
36
+ * workspace can take.
37
+ *
38
+ * Pair it with `BlockedControl` when the gated control stays on screen: the
39
+ * notice carries the link, the disabled control carries the same reason on
40
+ * hover and for a screen reader.
41
+ */
42
+ export declare function PrerequisiteNotice(props: PrerequisiteNoticeProps): import("react").JSX.Element;
43
+ export default PrerequisiteNotice;
@@ -0,0 +1,53 @@
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
+ */ 'use client';
17
+ import { jsx as _jsx } from "react/jsx-runtime";
18
+ import { Alert } from "@mui/material";
19
+ import { AppLink } from "./app-link.js";
20
+ /**
21
+ * Says what a feature needs before it can work, and links to where that is
22
+ * done.
23
+ *
24
+ * A control that silently disappears or fails only after it is pressed reads
25
+ * as a missing feature, and the operator has no way to learn that one setup
26
+ * step stands between them and it. This is the one place the console states a
27
+ * prerequisite an operator can fix themselves: connecting Stripe, adding a
28
+ * ship-from address, a plan that includes the feature. A gate the operator
29
+ * cannot act on — a deployment that has not configured a vendor — stays
30
+ * hidden instead, since naming it would point at a step nobody on the
31
+ * workspace can take.
32
+ *
33
+ * Pair it with `BlockedControl` when the gated control stays on screen: the
34
+ * notice carries the link, the disabled control carries the same reason on
35
+ * hover and for a screen reader.
36
+ */ export function PrerequisiteNotice(props) {
37
+ const { children, href, actionLabel = 'Set it up', severity = 'info', sx } = props;
38
+ return /*#__PURE__*/ _jsx(Alert, {
39
+ severity: severity,
40
+ sx: sx,
41
+ action: href ? /*#__PURE__*/ _jsx(AppLink, {
42
+ componentVariant: "button",
43
+ color: "inherit",
44
+ size: "small",
45
+ href: href,
46
+ children: actionLabel
47
+ }) : undefined,
48
+ children: children
49
+ });
50
+ }
51
+ export default PrerequisiteNotice;
52
+
53
+ //# sourceMappingURL=prerequisite-notice.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/prerequisite-notice.component.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'use client'\n\nimport { Alert, type AlertProps } from '@mui/material'\nimport type { ReactNode } from 'react'\nimport { AppLink } from './app-link'\n\nexport interface PrerequisiteNoticeProps {\n /**\n * What the feature needs first and what it unlocks, in one or two\n * sentences: \"Connect Stripe to take card payments at the register.\"\n */\n children: ReactNode\n /**\n * Where the operator fixes it. Without one the notice still names the\n * step; a notice that cannot link is better than a control that vanishes.\n */\n href?: string\n /** The link's label — the page or action it opens. Defaults to \"Set it up\". */\n actionLabel?: string\n /**\n * `info` for a step that unlocks something optional, `warning` when a\n * setting already saved cannot work until the step is done (a deposit set\n * on a store that cannot charge).\n */\n severity?: Extract<AlertProps['severity'], 'info' | 'warning'>\n /** Extra layout on the alert (margins in a stack, mostly). */\n sx?: AlertProps['sx']\n}\n\n/**\n * Says what a feature needs before it can work, and links to where that is\n * done.\n *\n * A control that silently disappears or fails only after it is pressed reads\n * as a missing feature, and the operator has no way to learn that one setup\n * step stands between them and it. This is the one place the console states a\n * prerequisite an operator can fix themselves: connecting Stripe, adding a\n * ship-from address, a plan that includes the feature. A gate the operator\n * cannot act on — a deployment that has not configured a vendor — stays\n * hidden instead, since naming it would point at a step nobody on the\n * workspace can take.\n *\n * Pair it with `BlockedControl` when the gated control stays on screen: the\n * notice carries the link, the disabled control carries the same reason on\n * hover and for a screen reader.\n */\nexport function PrerequisiteNotice(props: PrerequisiteNoticeProps) {\n const { children, href, actionLabel = 'Set it up', severity = 'info', sx } = props\n return (\n <Alert\n severity={severity}\n sx={sx}\n action={\n href ? (\n <AppLink componentVariant=\"button\" color=\"inherit\" size=\"small\" href={href}>\n {actionLabel}\n </AppLink>\n ) : undefined\n }\n >\n {children}\n </Alert>\n )\n}\n\nexport default PrerequisiteNotice\n"],"names":["Alert","AppLink","PrerequisiteNotice","props","children","href","actionLabel","severity","sx","action","componentVariant","color","size","undefined"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,KAAK,QAAyB,gBAAe;AAEtD,SAASC,OAAO,QAAQ,gBAAY;AAyBpC;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,SAASC,mBAAmBC,KAA8B;IAC/D,MAAM,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,cAAc,WAAW,EAAEC,WAAW,MAAM,EAAEC,EAAE,EAAE,GAAGL;IAC7E,qBACE,KAACH;QACCO,UAAUA;QACVC,IAAIA;QACJC,QACEJ,qBACE,KAACJ;YAAQS,kBAAiB;YAASC,OAAM;YAAUC,MAAK;YAAQP,MAAMA;sBACnEC;aAEDO;kBAGLT;;AAGP;AAEA,eAAeF,mBAAkB"}