@aglyn/shared-ui-jsx 1.0.0-beta.285 → 1.0.0-beta.287

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.285",
3
+ "version": "1.0.0-beta.287",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,11 +25,11 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/shared-data-mdi": "1.0.0-beta.285",
29
- "@aglyn/shared-ui-snackstack": "1.0.0-beta.285",
30
- "@aglyn/shared-ui-theme": "1.0.0-beta.285",
31
- "@aglyn/shared-util-tools": "1.0.0-beta.285",
32
- "@aglyn/shared-util-vendor": "1.0.0-beta.285",
28
+ "@aglyn/shared-data-mdi": "1.0.0-beta.287",
29
+ "@aglyn/shared-ui-snackstack": "1.0.0-beta.287",
30
+ "@aglyn/shared-ui-theme": "1.0.0-beta.287",
31
+ "@aglyn/shared-util-tools": "1.0.0-beta.287",
32
+ "@aglyn/shared-util-vendor": "1.0.0-beta.287",
33
33
  "@mdi/js": "^7.4.47",
34
34
  "@swc/helpers": "0.5.23",
35
35
  "change-case": "^5.4.4",
@@ -40,7 +40,7 @@
40
40
  "lodash-es": "^4.18.1",
41
41
  "mobx": "^7.0.5",
42
42
  "react-frame-component": "^5.3.2",
43
- "react-is": "^19.3.0",
43
+ "react-is": "^19.3.1",
44
44
  "react-use": "^17.6.1",
45
45
  "react-virtuoso": "^4.18.16",
46
46
  "rxjs": "^7.8.2",
@@ -27,6 +27,13 @@ import { type ReactNode } from 'react';
27
27
  * (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).
28
28
  */
29
29
  export type PermissionChoiceValue = 'inherit' | 'grant' | 'deny';
30
+ /**
31
+ * A key a site can narrow (AGL-4047) carries a second choice: on a site where
32
+ * the member's access is narrower than their workspace role, does it follow
33
+ * that site role (`narrow`) or do they keep it (`keep`)? `inherit`: the layer
34
+ * below decides.
35
+ */
36
+ export type PermissionNarrowingValue = 'inherit' | 'narrow' | 'keep';
30
37
  export interface PermissionChoiceItem {
31
38
  key: string;
32
39
  label: string;
@@ -44,6 +51,16 @@ export interface PermissionChoiceItem {
44
51
  inheritHint?: string;
45
52
  /** A reason the row cannot change, shown as the toggle's tooltip. */
46
53
  lockedReason?: string;
54
+ /**
55
+ * The narrowing choice, for a key a site can narrow; absent, the row has
56
+ * none. `effective` is the verdict and where it came from ("Follows the
57
+ * site role · from the Editor role"); `inheritHint` what inherit resolves to.
58
+ */
59
+ narrowing?: {
60
+ choice: PermissionNarrowingValue;
61
+ effective?: string;
62
+ inheritHint?: string;
63
+ };
47
64
  }
48
65
  export interface PermissionChoiceSection {
49
66
  id: string;
@@ -64,6 +81,10 @@ export interface PermissionChoiceListProps {
64
81
  emptyMessage?: ReactNode;
65
82
  /** Offer "set the whole group" on each heading. */
66
83
  groupActions?: boolean;
84
+ /** Sets one key's narrowing choice; absent, the narrowing rows are read-only. */
85
+ onNarrowingChange?: (key: string, choice: PermissionNarrowingValue) => void;
86
+ /** The words before the narrowing choice. */
87
+ narrowingLabel?: string;
67
88
  }
68
89
  export declare function PermissionChoiceList(props: PermissionChoiceListProps): import("react").JSX.Element;
69
90
  export declare namespace PermissionChoiceList {
@@ -1,5 +1,5 @@
1
1
  import { _ as _extends } from "@swc/helpers/_/_extends";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  /**
4
4
  * @license
5
5
  * Copyright 2026 Aglyn LLC
@@ -52,6 +52,63 @@ function ChoiceToggle(props) {
52
52
  }, choice))
53
53
  });
54
54
  }
55
+ const NARROWING_CHOICES = [
56
+ 'inherit',
57
+ 'narrow',
58
+ 'keep'
59
+ ];
60
+ const NARROWING_LABELS = {
61
+ inherit: 'Inherit',
62
+ narrow: 'Follow the site role',
63
+ keep: 'Keep this permission'
64
+ };
65
+ function NarrowingToggle(props) {
66
+ return /*#__PURE__*/ _jsxs(Stack, {
67
+ direction: {
68
+ xs: 'column',
69
+ sm: 'row'
70
+ },
71
+ spacing: 1,
72
+ sx: {
73
+ alignItems: {
74
+ xs: 'flex-start',
75
+ sm: 'center'
76
+ },
77
+ mt: 0.5
78
+ },
79
+ children: [
80
+ /*#__PURE__*/ _jsx(Typography, {
81
+ variant: "caption",
82
+ color: "text.secondary",
83
+ children: props.label
84
+ }),
85
+ /*#__PURE__*/ _jsx(ToggleButtonGroup, {
86
+ size: "small",
87
+ exclusive: true,
88
+ value: props.value,
89
+ disabled: props.disabled,
90
+ "aria-label": props.ariaLabel,
91
+ onChange: (_event, next)=>{
92
+ if (next) props.onChange(next);
93
+ },
94
+ sx: {
95
+ flexWrap: 'wrap'
96
+ },
97
+ children: NARROWING_CHOICES.map((choice)=>/*#__PURE__*/ _jsx(ToggleButton, {
98
+ value: choice,
99
+ color: choice === 'keep' ? 'success' : choice === 'narrow' ? 'warning' : 'standard',
100
+ sx: {
101
+ px: 1,
102
+ py: 0,
103
+ textTransform: 'none',
104
+ typography: 'caption'
105
+ },
106
+ children: NARROWING_LABELS[choice]
107
+ }, choice))
108
+ })
109
+ ]
110
+ });
111
+ }
55
112
  export function PermissionChoiceList(props) {
56
113
  var _props_search, _props_emptyMessage;
57
114
  const labels = _extends({}, DEFAULT_LABELS, props.labels);
@@ -149,6 +206,7 @@ export function PermissionChoiceList(props) {
149
206
  borderRadius: 1
150
207
  },
151
208
  children: section.items.map((item)=>{
209
+ var _props_narrowingLabel;
152
210
  const toggle = /*#__PURE__*/ _jsx("span", {
153
211
  children: /*#__PURE__*/ _jsx(ChoiceToggle, {
154
212
  value: item.choice,
@@ -202,6 +260,29 @@ export function PermissionChoiceList(props) {
202
260
  color: "text.secondary",
203
261
  component: "p",
204
262
  children: item.inheritHint
263
+ }) : null,
264
+ item.narrowing ? /*#__PURE__*/ _jsxs(_Fragment, {
265
+ children: [
266
+ /*#__PURE__*/ _jsx(NarrowingToggle, {
267
+ label: (_props_narrowingLabel = props.narrowingLabel) != null ? _props_narrowingLabel : 'On sites where their role is narrower:',
268
+ value: item.narrowing.choice,
269
+ disabled: props.disabled || Boolean(item.lockedReason) || !props.onNarrowingChange,
270
+ ariaLabel: `${item.label}: on sites where their role is narrower`,
271
+ onChange: (choice)=>props.onNarrowingChange == null ? void 0 : props.onNarrowingChange.call(props, item.key, choice)
272
+ }),
273
+ item.narrowing.effective ? /*#__PURE__*/ _jsx(Typography, {
274
+ variant: "caption",
275
+ color: "text.secondary",
276
+ component: "p",
277
+ children: item.narrowing.effective
278
+ }) : null,
279
+ item.narrowing.choice === 'inherit' && item.narrowing.inheritHint ? /*#__PURE__*/ _jsx(Typography, {
280
+ variant: "caption",
281
+ color: "text.secondary",
282
+ component: "p",
283
+ children: item.narrowing.inheritHint
284
+ }) : null
285
+ ]
205
286
  }) : null
206
287
  ]
207
288
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/permission-choice-list.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\nimport {\n Box,\n Chip,\n Divider,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useId, type ReactNode } from 'react'\n\n/**\n * A grouped, searchable list of permissions with three states each (AGL-4047):\n * inherit (the layer below decides), allow, or deny. Drawn by every editor of\n * a permission map — a custom role, one member's overrides, one collaborator's\n * per-site toggles — so they look and behave alike.\n *\n * Presentation only: the caller decides which keys are offered, how they are\n * grouped, what a search keeps and what \"inherit\" resolves to, and hands the\n * words in. NOT in the `@aglyn/shared-ui-jsx` barrel; subpath-import it\n * (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).\n */\n\nexport type PermissionChoiceValue = 'inherit' | 'grant' | 'deny'\n\nexport interface PermissionChoiceItem {\n key: string\n label: string\n description?: string\n choice: PermissionChoiceValue\n /**\n * The verdict the member ends up with and where it came from\n * (\"Allowed by the Editor role\"), shown under the description.\n */\n effective?: { granted: boolean; source: string }\n /** What inherit resolves to here, when there is one answer (\"Editor default: allowed\"). */\n inheritHint?: string\n /** A reason the row cannot change, shown as the toggle's tooltip. */\n lockedReason?: string\n}\n\nexport interface PermissionChoiceSection {\n id: string\n label: string\n items: PermissionChoiceItem[]\n}\n\nexport interface PermissionChoiceListProps {\n sections: readonly PermissionChoiceSection[]\n /** Sets one key (or, from a group heading, every key of the group) to a choice. */\n onChange: (keys: string[], choice: PermissionChoiceValue) => void\n /** The search box; absent hides it. */\n search?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n /** The words for the three states. */\n labels?: Partial<Record<PermissionChoiceValue, string>>\n /** Shown when a search keeps nothing. */\n emptyMessage?: ReactNode\n /** Offer \"set the whole group\" on each heading. */\n groupActions?: boolean\n}\n\nconst CHOICES: readonly PermissionChoiceValue[] = ['inherit', 'grant', 'deny']\n\nconst DEFAULT_LABELS: Record<PermissionChoiceValue, string> = {\n inherit: 'Inherit',\n grant: 'Allow',\n deny: 'Deny',\n}\n\nfunction ChoiceToggle(props: {\n value: PermissionChoiceValue | null\n onChange: (choice: PermissionChoiceValue) => void\n disabled?: boolean\n labels: Record<PermissionChoiceValue, string>\n ariaLabel: string\n}) {\n return (\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionChoiceValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexShrink: 0 }}\n >\n {CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'grant' ? 'success' : choice === 'deny' ? 'error' : 'standard'}\n sx={{ px: 1.25, py: 0.25, textTransform: 'none' }}\n >\n {props.labels[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n )\n}\n\nexport function PermissionChoiceList(props: PermissionChoiceListProps) {\n const labels = { ...DEFAULT_LABELS, ...props.labels }\n const searchId = useId()\n const visible = props.sections.filter((section) => section.items.length > 0)\n return (\n <Stack spacing={2}>\n {props.onSearchChange ? (\n <TextField\n id={searchId}\n size=\"small\"\n type=\"search\"\n label=\"Search permissions\"\n value={props.search ?? ''}\n onChange={(event) => props.onSearchChange?.(event.target.value)}\n />\n ) : null}\n {visible.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.emptyMessage ?? 'No permission matches your search.'}\n </Typography>\n ) : null}\n {visible.map((section) => {\n const granted = section.items.filter((item) => item.choice === 'grant').length\n const denied = section.items.filter((item) => item.choice === 'deny').length\n const shared = section.items.every((item) => item.choice === section.items[0]?.choice)\n ? (section.items[0]?.choice ?? null)\n : null\n const changeable = section.items.filter((item) => !item.lockedReason).map((item) => item.key)\n return (\n <Box key={section.id} component=\"section\" aria-label={section.label}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, justifyContent: 'space-between', mb: 1 }}\n >\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}>\n <Typography variant=\"subtitle2\" component=\"h3\">\n {section.label}\n </Typography>\n {granted ? <Chip size=\"small\" color=\"success\" variant=\"outlined\" label={`${granted} allowed`} /> : null}\n {denied ? <Chip size=\"small\" color=\"error\" variant=\"outlined\" label={`${denied} denied`} /> : null}\n </Stack>\n {props.groupActions && changeable.length > 1 ? (\n <ChoiceToggle\n value={shared}\n labels={labels}\n disabled={props.disabled}\n ariaLabel={`Set every ${section.label} permission`}\n onChange={(choice) => props.onChange(changeable, choice)}\n />\n ) : null}\n </Stack>\n <Stack divider={<Divider flexItem />} sx={{ border: 1, borderColor: 'divider', borderRadius: 1 }}>\n {section.items.map((item) => {\n const toggle = (\n <span>\n <ChoiceToggle\n value={item.choice}\n labels={labels}\n disabled={props.disabled || Boolean(item.lockedReason)}\n ariaLabel={item.label}\n onChange={(choice) => props.onChange([item.key], choice)}\n />\n </span>\n )\n return (\n <Stack\n key={item.key}\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1.5}\n sx={{ px: 1.5, py: 1, alignItems: { xs: 'stretch', sm: 'center' }, justifyContent: 'space-between' }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\">{item.label}</Typography>\n {item.description ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.description}\n </Typography>\n ) : null}\n {item.effective ? (\n <Typography\n variant=\"caption\"\n component=\"p\"\n color={item.effective.granted ? 'success.main' : 'text.secondary'}\n >\n {`${item.effective.granted ? 'Allowed' : 'Not allowed'} · ${item.effective.source}`}\n </Typography>\n ) : null}\n {item.choice === 'inherit' && item.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.inheritHint}\n </Typography>\n ) : null}\n </Box>\n {item.lockedReason ? <Tooltip title={item.lockedReason}>{toggle}</Tooltip> : toggle}\n </Stack>\n )\n })}\n </Stack>\n </Box>\n )\n })}\n </Stack>\n )\n}\nPermissionChoiceList.displayName = 'PermissionChoiceList'\n\nexport default PermissionChoiceList\n"],"names":["Box","Chip","Divider","Stack","TextField","ToggleButton","ToggleButtonGroup","Tooltip","Typography","useId","CHOICES","DEFAULT_LABELS","inherit","grant","deny","ChoiceToggle","props","size","exclusive","value","disabled","aria-label","ariaLabel","onChange","_event","next","sx","flexShrink","map","choice","color","px","py","textTransform","labels","PermissionChoiceList","searchId","visible","sections","filter","section","items","length","spacing","onSearchChange","id","type","label","search","event","target","variant","emptyMessage","granted","item","denied","shared","every","changeable","lockedReason","key","component","direction","xs","sm","alignItems","justifyContent","mb","flexWrap","rowGap","groupActions","divider","flexItem","border","borderColor","borderRadius","toggle","span","Boolean","minWidth","description","effective","source","inheritHint","title","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/permission-choice-list.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\nimport {\n Box,\n Chip,\n Divider,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useId, type ReactNode } from 'react'\n\n/**\n * A grouped, searchable list of permissions with three states each (AGL-4047):\n * inherit (the layer below decides), allow, or deny. Drawn by every editor of\n * a permission map — a custom role, one member's overrides, one collaborator's\n * per-site toggles — so they look and behave alike.\n *\n * Presentation only: the caller decides which keys are offered, how they are\n * grouped, what a search keeps and what \"inherit\" resolves to, and hands the\n * words in. NOT in the `@aglyn/shared-ui-jsx` barrel; subpath-import it\n * (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).\n */\n\nexport type PermissionChoiceValue = 'inherit' | 'grant' | 'deny'\n\n/**\n * A key a site can narrow (AGL-4047) carries a second choice: on a site where\n * the member's access is narrower than their workspace role, does it follow\n * that site role (`narrow`) or do they keep it (`keep`)? `inherit`: the layer\n * below decides.\n */\nexport type PermissionNarrowingValue = 'inherit' | 'narrow' | 'keep'\n\nexport interface PermissionChoiceItem {\n key: string\n label: string\n description?: string\n choice: PermissionChoiceValue\n /**\n * The verdict the member ends up with and where it came from\n * (\"Allowed by the Editor role\"), shown under the description.\n */\n effective?: { granted: boolean; source: string }\n /** What inherit resolves to here, when there is one answer (\"Editor default: allowed\"). */\n inheritHint?: string\n /** A reason the row cannot change, shown as the toggle's tooltip. */\n lockedReason?: string\n /**\n * The narrowing choice, for a key a site can narrow; absent, the row has\n * none. `effective` is the verdict and where it came from (\"Follows the\n * site role · from the Editor role\"); `inheritHint` what inherit resolves to.\n */\n narrowing?: { choice: PermissionNarrowingValue; effective?: string; inheritHint?: string }\n}\n\nexport interface PermissionChoiceSection {\n id: string\n label: string\n items: PermissionChoiceItem[]\n}\n\nexport interface PermissionChoiceListProps {\n sections: readonly PermissionChoiceSection[]\n /** Sets one key (or, from a group heading, every key of the group) to a choice. */\n onChange: (keys: string[], choice: PermissionChoiceValue) => void\n /** The search box; absent hides it. */\n search?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n /** The words for the three states. */\n labels?: Partial<Record<PermissionChoiceValue, string>>\n /** Shown when a search keeps nothing. */\n emptyMessage?: ReactNode\n /** Offer \"set the whole group\" on each heading. */\n groupActions?: boolean\n /** Sets one key's narrowing choice; absent, the narrowing rows are read-only. */\n onNarrowingChange?: (key: string, choice: PermissionNarrowingValue) => void\n /** The words before the narrowing choice. */\n narrowingLabel?: string\n}\n\nconst CHOICES: readonly PermissionChoiceValue[] = ['inherit', 'grant', 'deny']\n\nconst DEFAULT_LABELS: Record<PermissionChoiceValue, string> = {\n inherit: 'Inherit',\n grant: 'Allow',\n deny: 'Deny',\n}\n\nfunction ChoiceToggle(props: {\n value: PermissionChoiceValue | null\n onChange: (choice: PermissionChoiceValue) => void\n disabled?: boolean\n labels: Record<PermissionChoiceValue, string>\n ariaLabel: string\n}) {\n return (\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionChoiceValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexShrink: 0 }}\n >\n {CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'grant' ? 'success' : choice === 'deny' ? 'error' : 'standard'}\n sx={{ px: 1.25, py: 0.25, textTransform: 'none' }}\n >\n {props.labels[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n )\n}\n\nconst NARROWING_CHOICES: readonly PermissionNarrowingValue[] = ['inherit', 'narrow', 'keep']\n\nconst NARROWING_LABELS: Record<PermissionNarrowingValue, string> = {\n inherit: 'Inherit',\n narrow: 'Follow the site role',\n keep: 'Keep this permission',\n}\n\nfunction NarrowingToggle(props: {\n label: string\n value: PermissionNarrowingValue\n onChange: (choice: PermissionNarrowingValue) => void\n disabled?: boolean\n ariaLabel: string\n}) {\n return (\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, mt: 0.5 }}\n >\n <Typography variant=\"caption\" color=\"text.secondary\">\n {props.label}\n </Typography>\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionNarrowingValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexWrap: 'wrap' }}\n >\n {NARROWING_CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'keep' ? 'success' : choice === 'narrow' ? 'warning' : 'standard'}\n sx={{ px: 1, py: 0, textTransform: 'none', typography: 'caption' }}\n >\n {NARROWING_LABELS[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n </Stack>\n )\n}\n\nexport function PermissionChoiceList(props: PermissionChoiceListProps) {\n const labels = { ...DEFAULT_LABELS, ...props.labels }\n const searchId = useId()\n const visible = props.sections.filter((section) => section.items.length > 0)\n return (\n <Stack spacing={2}>\n {props.onSearchChange ? (\n <TextField\n id={searchId}\n size=\"small\"\n type=\"search\"\n label=\"Search permissions\"\n value={props.search ?? ''}\n onChange={(event) => props.onSearchChange?.(event.target.value)}\n />\n ) : null}\n {visible.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.emptyMessage ?? 'No permission matches your search.'}\n </Typography>\n ) : null}\n {visible.map((section) => {\n const granted = section.items.filter((item) => item.choice === 'grant').length\n const denied = section.items.filter((item) => item.choice === 'deny').length\n const shared = section.items.every((item) => item.choice === section.items[0]?.choice)\n ? (section.items[0]?.choice ?? null)\n : null\n const changeable = section.items.filter((item) => !item.lockedReason).map((item) => item.key)\n return (\n <Box key={section.id} component=\"section\" aria-label={section.label}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, justifyContent: 'space-between', mb: 1 }}\n >\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}>\n <Typography variant=\"subtitle2\" component=\"h3\">\n {section.label}\n </Typography>\n {granted ? <Chip size=\"small\" color=\"success\" variant=\"outlined\" label={`${granted} allowed`} /> : null}\n {denied ? <Chip size=\"small\" color=\"error\" variant=\"outlined\" label={`${denied} denied`} /> : null}\n </Stack>\n {props.groupActions && changeable.length > 1 ? (\n <ChoiceToggle\n value={shared}\n labels={labels}\n disabled={props.disabled}\n ariaLabel={`Set every ${section.label} permission`}\n onChange={(choice) => props.onChange(changeable, choice)}\n />\n ) : null}\n </Stack>\n <Stack divider={<Divider flexItem />} sx={{ border: 1, borderColor: 'divider', borderRadius: 1 }}>\n {section.items.map((item) => {\n const toggle = (\n <span>\n <ChoiceToggle\n value={item.choice}\n labels={labels}\n disabled={props.disabled || Boolean(item.lockedReason)}\n ariaLabel={item.label}\n onChange={(choice) => props.onChange([item.key], choice)}\n />\n </span>\n )\n return (\n <Stack\n key={item.key}\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1.5}\n sx={{ px: 1.5, py: 1, alignItems: { xs: 'stretch', sm: 'center' }, justifyContent: 'space-between' }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\">{item.label}</Typography>\n {item.description ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.description}\n </Typography>\n ) : null}\n {item.effective ? (\n <Typography\n variant=\"caption\"\n component=\"p\"\n color={item.effective.granted ? 'success.main' : 'text.secondary'}\n >\n {`${item.effective.granted ? 'Allowed' : 'Not allowed'} · ${item.effective.source}`}\n </Typography>\n ) : null}\n {item.choice === 'inherit' && item.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.inheritHint}\n </Typography>\n ) : null}\n {item.narrowing ? (\n <>\n <NarrowingToggle\n label={props.narrowingLabel ?? 'On sites where their role is narrower:'}\n value={item.narrowing.choice}\n disabled={props.disabled || Boolean(item.lockedReason) || !props.onNarrowingChange}\n ariaLabel={`${item.label}: on sites where their role is narrower`}\n onChange={(choice) => props.onNarrowingChange?.(item.key, choice)}\n />\n {item.narrowing.effective ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.narrowing.effective}\n </Typography>\n ) : null}\n {item.narrowing.choice === 'inherit' && item.narrowing.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.narrowing.inheritHint}\n </Typography>\n ) : null}\n </>\n ) : null}\n </Box>\n {item.lockedReason ? <Tooltip title={item.lockedReason}>{toggle}</Tooltip> : toggle}\n </Stack>\n )\n })}\n </Stack>\n </Box>\n )\n })}\n </Stack>\n )\n}\nPermissionChoiceList.displayName = 'PermissionChoiceList'\n\nexport default PermissionChoiceList\n"],"names":["Box","Chip","Divider","Stack","TextField","ToggleButton","ToggleButtonGroup","Tooltip","Typography","useId","CHOICES","DEFAULT_LABELS","inherit","grant","deny","ChoiceToggle","props","size","exclusive","value","disabled","aria-label","ariaLabel","onChange","_event","next","sx","flexShrink","map","choice","color","px","py","textTransform","labels","NARROWING_CHOICES","NARROWING_LABELS","narrow","keep","NarrowingToggle","direction","xs","sm","spacing","alignItems","mt","variant","label","flexWrap","typography","PermissionChoiceList","searchId","visible","sections","filter","section","items","length","onSearchChange","id","type","search","event","target","emptyMessage","granted","item","denied","shared","every","changeable","lockedReason","key","component","justifyContent","mb","rowGap","groupActions","divider","flexItem","border","borderColor","borderRadius","toggle","span","Boolean","minWidth","description","effective","source","inheritHint","narrowing","narrowingLabel","onNarrowingChange","title","displayName"],"mappings":"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"}