@aglyn/shared-ui-jsx 1.0.0-beta.229 → 1.0.0-beta.231

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.
Files changed (40) hide show
  1. package/package.json +5 -5
  2. package/src/lib/components/copy-field.component.d.ts +25 -0
  3. package/src/lib/components/copy-field.component.js +77 -0
  4. package/src/lib/components/copy-field.component.js.map +1 -0
  5. package/src/lib/components/download-cost-badge.component.d.ts +37 -0
  6. package/src/lib/components/download-cost-badge.component.js +89 -0
  7. package/src/lib/components/download-cost-badge.component.js.map +1 -0
  8. package/src/lib/components/file-drop-zone.component.d.ts +48 -0
  9. package/src/lib/components/file-drop-zone.component.js +173 -0
  10. package/src/lib/components/file-drop-zone.component.js.map +1 -0
  11. package/src/lib/components/list-query-notices.component.d.ts +1 -18
  12. package/src/lib/components/list-query-notices.component.js +1 -11
  13. package/src/lib/components/list-query-notices.component.js.map +1 -1
  14. package/src/lib/components/searchable-virtual-list.component.d.ts +72 -0
  15. package/src/lib/components/searchable-virtual-list.component.js +212 -0
  16. package/src/lib/components/searchable-virtual-list.component.js.map +1 -0
  17. package/src/lib/components/site-live-notice.component.d.ts +39 -0
  18. package/src/lib/components/site-live-notice.component.js +95 -0
  19. package/src/lib/components/site-live-notice.component.js.map +1 -0
  20. package/src/lib/components/status-chip.component.d.ts +26 -0
  21. package/src/lib/components/status-chip.component.js +48 -0
  22. package/src/lib/components/status-chip.component.js.map +1 -0
  23. package/src/lib/const/list-filter-sentence.d.ts +1 -24
  24. package/src/lib/const/list-filter-sentence.js +3 -105
  25. package/src/lib/const/list-filter-sentence.js.map +1 -1
  26. package/src/lib/const/list-filter.d.ts +1 -219
  27. package/src/lib/const/list-filter.js +4 -282
  28. package/src/lib/const/list-filter.js.map +1 -1
  29. package/src/lib/const/list-grid-filter.d.ts +4 -25
  30. package/src/lib/const/list-grid-filter.js +20 -44
  31. package/src/lib/const/list-grid-filter.js.map +1 -1
  32. package/src/lib/const/list-query-plan.d.ts +1 -154
  33. package/src/lib/const/list-query-plan.js +4 -610
  34. package/src/lib/const/list-query-plan.js.map +1 -1
  35. package/src/lib/hooks/use-client-pagination.d.ts +25 -0
  36. package/src/lib/hooks/use-client-pagination.js +65 -0
  37. package/src/lib/hooks/use-client-pagination.js.map +1 -0
  38. package/src/lib/hooks/use-in-view.d.ts +16 -0
  39. package/src/lib/hooks/use-in-view.js +66 -0
  40. package/src/lib/hooks/use-in-view.js.map +1 -0
@@ -0,0 +1,72 @@
1
+ import { type ReactNode } from 'react';
2
+ /** One choice of a list's filter chips. */
3
+ export interface SearchableVirtualListFilterOption {
4
+ value: string;
5
+ label: string;
6
+ }
7
+ export interface SearchableVirtualListProps<T> {
8
+ /** The rows to show, already searched and filtered by the caller. */
9
+ items: readonly T[];
10
+ itemKey: (item: T, index: number) => string;
11
+ renderItem: (item: T, index: number) => ReactNode;
12
+ /** The search box; the caller decides what a word matches. */
13
+ search: {
14
+ value: string;
15
+ onChange: (value: string) => void;
16
+ label: string;
17
+ placeholder?: string;
18
+ };
19
+ /**
20
+ * One row of chips that narrows the list to one choice, with an "All" chip
21
+ * first. Absent, the list has no chips.
22
+ */
23
+ filters?: {
24
+ label: string;
25
+ options: readonly SearchableVirtualListFilterOption[];
26
+ /** The chosen option's value, or `''` for all. */
27
+ value: string;
28
+ onChange: (value: string) => void;
29
+ allLabel?: string;
30
+ };
31
+ /** Scrolls with the rows, above them: a pinned section, a heading. */
32
+ header?: ReactNode;
33
+ /** A line under the controls, such as how many rows match. */
34
+ summary?: ReactNode;
35
+ loading?: boolean;
36
+ /** Placeholder rows while loading. */
37
+ loadingRows?: number;
38
+ /** The height of a placeholder row, in px. */
39
+ loadingRowHeight?: number;
40
+ error?: {
41
+ message: string;
42
+ onRetry?: () => void;
43
+ } | null;
44
+ /** What an empty list says; shown when `items` is empty and nothing is loading. */
45
+ empty: {
46
+ label: ReactNode;
47
+ description?: ReactNode;
48
+ action?: ReactNode;
49
+ };
50
+ /**
51
+ * The list's height. Absent, it fills its parent, which must give it one:
52
+ * a flex column with a height, a dialog's content.
53
+ */
54
+ height?: number | string;
55
+ /** The gap between rows, in theme spacing units. */
56
+ gap?: number;
57
+ }
58
+ /**
59
+ * A long list a person searches, narrows by a row of chips and scrolls, of
60
+ * which only the rows on screen are drawn (AGL-3656, first for the font
61
+ * picker's 1,950 families): the search box, the chips, the list, and its
62
+ * loading, failed and empty states, in the console's own components.
63
+ *
64
+ * The caller owns the words and the chosen chip and hands in the rows they
65
+ * leave, so the list never decides what a search matches. NOT in the barrel:
66
+ * subpath-import it (`@aglyn/shared-ui-jsx/components/searchable-virtual-list.component`).
67
+ */
68
+ export declare function SearchableVirtualList<T>(props: SearchableVirtualListProps<T>): import("react").JSX.Element;
69
+ export declare namespace SearchableVirtualList {
70
+ var displayName: string;
71
+ }
72
+ export default SearchableVirtualList;
@@ -0,0 +1,212 @@
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, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
+ import { mdiClose, mdiMagnify } from "@aglyn/shared-data-mdi";
19
+ import { Alert, Box, Button, Chip, IconButton, InputAdornment, Skeleton, Stack, TextField, Typography } from "@mui/material";
20
+ import { useCallback } from "react";
21
+ import { Virtuoso } from "react-virtuoso";
22
+ import EmptyState from "./empty-state.component.js";
23
+ import MdiIcon from "./mdi-icon/mdi-icon.js";
24
+ /**
25
+ * A long list a person searches, narrows by a row of chips and scrolls, of
26
+ * which only the rows on screen are drawn (AGL-3656, first for the font
27
+ * picker's 1,950 families): the search box, the chips, the list, and its
28
+ * loading, failed and empty states, in the console's own components.
29
+ *
30
+ * The caller owns the words and the chosen chip and hands in the rows they
31
+ * leave, so the list never decides what a search matches. NOT in the barrel:
32
+ * subpath-import it (`@aglyn/shared-ui-jsx/components/searchable-virtual-list.component`).
33
+ */ export function SearchableVirtualList(props) {
34
+ var _filters_allLabel;
35
+ const { items, itemKey, renderItem, search, filters, header, summary, loading = false, loadingRows = 6, loadingRowHeight = 96, error = null, empty, height, gap = 1 } = props;
36
+ const computeItemKey = useCallback((index)=>itemKey(items[index], index), [
37
+ itemKey,
38
+ items
39
+ ]);
40
+ const itemContent = useCallback((index)=>/*#__PURE__*/ _jsx(Box, {
41
+ sx: {
42
+ pb: gap
43
+ },
44
+ children: renderItem(items[index], index)
45
+ }), [
46
+ gap,
47
+ items,
48
+ renderItem
49
+ ]);
50
+ const Header = useCallback(()=>/*#__PURE__*/ _jsx(_Fragment, {
51
+ children: header != null ? header : null
52
+ }), [
53
+ header
54
+ ]);
55
+ let body;
56
+ if (error) {
57
+ body = /*#__PURE__*/ _jsx(Alert, {
58
+ severity: "error",
59
+ action: error.onRetry ? /*#__PURE__*/ _jsx(Button, {
60
+ color: "inherit",
61
+ size: "small",
62
+ onClick: error.onRetry,
63
+ children: 'Try again'
64
+ }) : undefined,
65
+ children: error.message
66
+ });
67
+ } else if (loading) {
68
+ body = /*#__PURE__*/ _jsx(Stack, {
69
+ spacing: gap,
70
+ "aria-busy": true,
71
+ "aria-label": "Loading",
72
+ children: Array.from({
73
+ length: loadingRows
74
+ }, (_, index)=>/*#__PURE__*/ _jsx(Skeleton, {
75
+ variant: "rounded",
76
+ height: loadingRowHeight
77
+ }, index))
78
+ });
79
+ } else if (!items.length) {
80
+ body = /*#__PURE__*/ _jsxs(Box, {
81
+ children: [
82
+ header,
83
+ /*#__PURE__*/ _jsx(EmptyState, {
84
+ compact: true,
85
+ label: empty.label,
86
+ description: empty.description,
87
+ action: empty.action
88
+ })
89
+ ]
90
+ });
91
+ } else {
92
+ body = /*#__PURE__*/ _jsx(Virtuoso, {
93
+ // Fills the column it is given, or the height it is told.
94
+ style: height === undefined ? {
95
+ flex: '1 1 auto',
96
+ minHeight: 0
97
+ } : {
98
+ height: '100%'
99
+ },
100
+ totalCount: items.length,
101
+ computeItemKey: computeItemKey,
102
+ itemContent: itemContent,
103
+ components: header ? {
104
+ Header
105
+ } : undefined
106
+ });
107
+ }
108
+ return /*#__PURE__*/ _jsxs(Stack, {
109
+ spacing: 1.5,
110
+ sx: {
111
+ minHeight: 0,
112
+ minWidth: 0,
113
+ width: '100%',
114
+ flex: height === undefined ? '1 1 auto' : undefined
115
+ },
116
+ children: [
117
+ /*#__PURE__*/ _jsx(TextField, {
118
+ size: "small",
119
+ fullWidth: true,
120
+ // A text box and not `type="search"`: the browser's own clear
121
+ // control would sit beside this one.
122
+ type: "text",
123
+ label: search.label,
124
+ placeholder: search.placeholder,
125
+ value: search.value,
126
+ onChange: (event)=>search.onChange(event.target.value),
127
+ slotProps: {
128
+ htmlInput: {
129
+ inputMode: 'search',
130
+ enterKeyHint: 'search'
131
+ },
132
+ input: {
133
+ startAdornment: /*#__PURE__*/ _jsx(InputAdornment, {
134
+ position: "start",
135
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
136
+ path: mdiMagnify.path
137
+ })
138
+ }),
139
+ endAdornment: search.value ? /*#__PURE__*/ _jsx(InputAdornment, {
140
+ position: "end",
141
+ children: /*#__PURE__*/ _jsx(IconButton, {
142
+ size: "small",
143
+ edge: "end",
144
+ "aria-label": "Clear search",
145
+ onClick: ()=>search.onChange(''),
146
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
147
+ path: mdiClose.path
148
+ })
149
+ })
150
+ }) : undefined
151
+ }
152
+ }
153
+ }),
154
+ filters ? /*#__PURE__*/ _jsx(Stack, {
155
+ direction: "row",
156
+ spacing: 1,
157
+ role: "radiogroup",
158
+ "aria-label": filters.label,
159
+ sx: {
160
+ // One row that scrolls sideways on a phone rather than wrapping
161
+ // into a block of chips above a short list.
162
+ overflowX: 'auto',
163
+ flexWrap: 'nowrap',
164
+ pb: 0.5,
165
+ scrollbarWidth: 'none',
166
+ '& > *': {
167
+ flexShrink: 0
168
+ }
169
+ },
170
+ children: [
171
+ {
172
+ value: '',
173
+ label: (_filters_allLabel = filters.allLabel) != null ? _filters_allLabel : 'All'
174
+ },
175
+ ...filters.options
176
+ ].map((option)=>{
177
+ const selected = filters.value === option.value;
178
+ return /*#__PURE__*/ _jsx(Chip, {
179
+ role: "radio",
180
+ "aria-checked": selected,
181
+ "aria-label": option.label,
182
+ label: option.label,
183
+ size: "small",
184
+ color: selected ? 'primary' : 'default',
185
+ variant: selected ? 'filled' : 'outlined',
186
+ onClick: ()=>filters.onChange(option.value)
187
+ }, option.value || '__all');
188
+ })
189
+ }) : null,
190
+ summary ? /*#__PURE__*/ _jsx(Typography, {
191
+ variant: "caption",
192
+ color: "text.secondary",
193
+ component: "div",
194
+ children: summary
195
+ }) : null,
196
+ /*#__PURE__*/ _jsx(Box, {
197
+ sx: {
198
+ minHeight: 0,
199
+ flex: height === undefined ? '1 1 auto' : undefined,
200
+ height: height === undefined ? undefined : height,
201
+ display: 'flex',
202
+ flexDirection: 'column'
203
+ },
204
+ children: body
205
+ })
206
+ ]
207
+ });
208
+ }
209
+ SearchableVirtualList.displayName = 'SearchableVirtualList';
210
+ export default SearchableVirtualList;
211
+
212
+ //# sourceMappingURL=searchable-virtual-list.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/searchable-virtual-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'use client'\n\nimport { mdiClose, mdiMagnify } from '@aglyn/shared-data-mdi'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n IconButton,\n InputAdornment,\n Skeleton,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { type ReactNode, useCallback } from 'react'\nimport { Virtuoso } from 'react-virtuoso'\nimport EmptyState from './empty-state.component'\nimport MdiIcon from './mdi-icon/mdi-icon'\n\n/** One choice of a list's filter chips. */\nexport interface SearchableVirtualListFilterOption {\n value: string\n label: string\n}\n\nexport interface SearchableVirtualListProps<T> {\n /** The rows to show, already searched and filtered by the caller. */\n items: readonly T[]\n itemKey: (item: T, index: number) => string\n renderItem: (item: T, index: number) => ReactNode\n /** The search box; the caller decides what a word matches. */\n search: {\n value: string\n onChange: (value: string) => void\n label: string\n placeholder?: string\n }\n /**\n * One row of chips that narrows the list to one choice, with an \"All\" chip\n * first. Absent, the list has no chips.\n */\n filters?: {\n label: string\n options: readonly SearchableVirtualListFilterOption[]\n /** The chosen option's value, or `''` for all. */\n value: string\n onChange: (value: string) => void\n allLabel?: string\n }\n /** Scrolls with the rows, above them: a pinned section, a heading. */\n header?: ReactNode\n /** A line under the controls, such as how many rows match. */\n summary?: ReactNode\n loading?: boolean\n /** Placeholder rows while loading. */\n loadingRows?: number\n /** The height of a placeholder row, in px. */\n loadingRowHeight?: number\n error?: { message: string; onRetry?: () => void } | null\n /** What an empty list says; shown when `items` is empty and nothing is loading. */\n empty: { label: ReactNode; description?: ReactNode; action?: ReactNode }\n /**\n * The list's height. Absent, it fills its parent, which must give it one:\n * a flex column with a height, a dialog's content.\n */\n height?: number | string\n /** The gap between rows, in theme spacing units. */\n gap?: number\n}\n\n/**\n * A long list a person searches, narrows by a row of chips and scrolls, of\n * which only the rows on screen are drawn (AGL-3656, first for the font\n * picker's 1,950 families): the search box, the chips, the list, and its\n * loading, failed and empty states, in the console's own components.\n *\n * The caller owns the words and the chosen chip and hands in the rows they\n * leave, so the list never decides what a search matches. NOT in the barrel:\n * subpath-import it (`@aglyn/shared-ui-jsx/components/searchable-virtual-list.component`).\n */\nexport function SearchableVirtualList<T>(props: SearchableVirtualListProps<T>) {\n const {\n items,\n itemKey,\n renderItem,\n search,\n filters,\n header,\n summary,\n loading = false,\n loadingRows = 6,\n loadingRowHeight = 96,\n error = null,\n empty,\n height,\n gap = 1,\n } = props\n const computeItemKey = useCallback(\n (index: number) => itemKey(items[index] as T, index),\n [itemKey, items],\n )\n const itemContent = useCallback(\n (index: number) => (\n <Box sx={{ pb: gap }}>{renderItem(items[index] as T, index)}</Box>\n ),\n [gap, items, renderItem],\n )\n const Header = useCallback(() => <>{header ?? null}</>, [header])\n\n let body: ReactNode\n if (error) {\n body = (\n <Alert\n severity=\"error\"\n action={\n error.onRetry ? (\n <Button color=\"inherit\" size=\"small\" onClick={error.onRetry}>\n {'Try again'}\n </Button>\n ) : undefined\n }\n >\n {error.message}\n </Alert>\n )\n } else if (loading) {\n body = (\n <Stack spacing={gap} aria-busy aria-label=\"Loading\">\n {Array.from({ length: loadingRows }, (_, index) => (\n <Skeleton key={index} variant=\"rounded\" height={loadingRowHeight} />\n ))}\n </Stack>\n )\n } else if (!items.length) {\n body = (\n <Box>\n {header}\n <EmptyState compact label={empty.label} description={empty.description} action={empty.action} />\n </Box>\n )\n } else {\n body = (\n <Virtuoso\n // Fills the column it is given, or the height it is told.\n style={height === undefined ? { flex: '1 1 auto', minHeight: 0 } : { height: '100%' }}\n totalCount={items.length}\n computeItemKey={computeItemKey}\n itemContent={itemContent}\n components={header ? { Header } : undefined}\n />\n )\n }\n\n return (\n <Stack\n spacing={1.5}\n sx={{ minHeight: 0, minWidth: 0, width: '100%', flex: height === undefined ? '1 1 auto' : undefined }}\n >\n <TextField\n size=\"small\"\n fullWidth\n // A text box and not `type=\"search\"`: the browser's own clear\n // control would sit beside this one.\n type=\"text\"\n label={search.label}\n placeholder={search.placeholder}\n value={search.value}\n onChange={(event) => search.onChange(event.target.value)}\n slotProps={{\n htmlInput: { inputMode: 'search', enterKeyHint: 'search' },\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <MdiIcon path={mdiMagnify.path} />\n </InputAdornment>\n ),\n endAdornment: search.value ? (\n <InputAdornment position=\"end\">\n <IconButton\n size=\"small\"\n edge=\"end\"\n aria-label=\"Clear search\"\n onClick={() => search.onChange('')}\n >\n <MdiIcon path={mdiClose.path} />\n </IconButton>\n </InputAdornment>\n ) : undefined,\n },\n }}\n />\n {filters ? (\n <Stack\n direction=\"row\"\n spacing={1}\n role=\"radiogroup\"\n aria-label={filters.label}\n sx={{\n // One row that scrolls sideways on a phone rather than wrapping\n // into a block of chips above a short list.\n overflowX: 'auto',\n flexWrap: 'nowrap',\n pb: 0.5,\n scrollbarWidth: 'none',\n '& > *': { flexShrink: 0 },\n }}\n >\n {[{ value: '', label: filters.allLabel ?? 'All' }, ...filters.options].map((option) => {\n const selected = filters.value === option.value\n return (\n <Chip\n key={option.value || '__all'}\n role=\"radio\"\n aria-checked={selected}\n aria-label={option.label}\n label={option.label}\n size=\"small\"\n color={selected ? 'primary' : 'default'}\n variant={selected ? 'filled' : 'outlined'}\n onClick={() => filters.onChange(option.value)}\n />\n )\n })}\n </Stack>\n ) : null}\n {summary ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n {summary}\n </Typography>\n ) : null}\n <Box\n sx={{\n minHeight: 0,\n flex: height === undefined ? '1 1 auto' : undefined,\n height: height === undefined ? undefined : height,\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {body}\n </Box>\n </Stack>\n )\n}\nSearchableVirtualList.displayName = 'SearchableVirtualList'\n\nexport default SearchableVirtualList\n"],"names":["mdiClose","mdiMagnify","Alert","Box","Button","Chip","IconButton","InputAdornment","Skeleton","Stack","TextField","Typography","useCallback","Virtuoso","EmptyState","MdiIcon","SearchableVirtualList","props","filters","items","itemKey","renderItem","search","header","summary","loading","loadingRows","loadingRowHeight","error","empty","height","gap","computeItemKey","index","itemContent","sx","pb","Header","body","severity","action","onRetry","color","size","onClick","undefined","message","spacing","aria-busy","aria-label","Array","from","length","_","variant","compact","label","description","style","flex","minHeight","totalCount","components","minWidth","width","fullWidth","type","placeholder","value","onChange","event","target","slotProps","htmlInput","inputMode","enterKeyHint","input","startAdornment","position","path","endAdornment","edge","direction","role","overflowX","flexWrap","scrollbarWidth","flexShrink","allLabel","options","map","option","selected","aria-checked","component","display","flexDirection","displayName"],"mappings":"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"}
@@ -0,0 +1,39 @@
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
+ export declare const SITE_LIVE_NOTICE_TITLE = "Your site is live";
18
+ export declare const SITE_LIVE_NOTICE_BODY = "Your pages are published, and anyone can visit your site now.";
19
+ export interface SiteLiveNoticeProps {
20
+ /** The site's public address; without one the notice says it is live and offers only the pages. */
21
+ liveUrl: string | null;
22
+ /** The console's page list for the site, where the pages are edited. */
23
+ pagesHref: string | null;
24
+ /** The heading's level, for the page or dialog it sits in. */
25
+ headingComponent?: 'h1' | 'h2' | 'h3';
26
+ }
27
+ /**
28
+ * What a person sees the moment their site goes live: that it is live, the
29
+ * address visitors use, and the two things to do next — look at it, or edit
30
+ * its pages. Shared by every path that publishes a new site (the starter, the
31
+ * guided AI start) so a site goes live in the same words whichever way it
32
+ * was made.
33
+ *
34
+ * It exists because nothing said so. A starter site is published the moment
35
+ * it is chosen, and a person who was never told read their analytics window
36
+ * ("14 days") as a countdown to launch.
37
+ */
38
+ export declare function SiteLiveNotice({ liveUrl, pagesHref, headingComponent }: SiteLiveNoticeProps): import("react").JSX.Element;
39
+ export default SiteLiveNotice;
@@ -0,0 +1,95 @@
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, jsxs as _jsxs } from "react/jsx-runtime";
18
+ import Button from "@mui/material/Button";
19
+ import Link from "@mui/material/Link";
20
+ import Stack from "@mui/material/Stack";
21
+ import Typography from "@mui/material/Typography";
22
+ import AppLink from "./app-link.js";
23
+ export const SITE_LIVE_NOTICE_TITLE = 'Your site is live';
24
+ export const SITE_LIVE_NOTICE_BODY = 'Your pages are published, and anyone can visit your site now.';
25
+ /**
26
+ * What a person sees the moment their site goes live: that it is live, the
27
+ * address visitors use, and the two things to do next — look at it, or edit
28
+ * its pages. Shared by every path that publishes a new site (the starter, the
29
+ * guided AI start) so a site goes live in the same words whichever way it
30
+ * was made.
31
+ *
32
+ * It exists because nothing said so. A starter site is published the moment
33
+ * it is chosen, and a person who was never told read their analytics window
34
+ * ("14 days") as a countdown to launch.
35
+ */ export function SiteLiveNotice({ liveUrl, pagesHref, headingComponent = 'h2' }) {
36
+ return /*#__PURE__*/ _jsxs(Stack, {
37
+ spacing: 2,
38
+ children: [
39
+ /*#__PURE__*/ _jsxs(Stack, {
40
+ spacing: 0.5,
41
+ children: [
42
+ /*#__PURE__*/ _jsx(Typography, {
43
+ variant: "h5",
44
+ component: headingComponent,
45
+ children: SITE_LIVE_NOTICE_TITLE
46
+ }),
47
+ /*#__PURE__*/ _jsx(Typography, {
48
+ variant: "body1",
49
+ color: "text.secondary",
50
+ children: SITE_LIVE_NOTICE_BODY
51
+ }),
52
+ liveUrl ? /*#__PURE__*/ _jsx(Link, {
53
+ href: liveUrl,
54
+ target: "_blank",
55
+ rel: "noopener noreferrer",
56
+ variant: "body1",
57
+ sx: {
58
+ wordBreak: 'break-all'
59
+ },
60
+ children: liveUrl.replace(/^https?:\/\//, '')
61
+ }) : null
62
+ ]
63
+ }),
64
+ /*#__PURE__*/ _jsxs(Stack, {
65
+ direction: {
66
+ xs: 'column',
67
+ sm: 'row'
68
+ },
69
+ spacing: 2,
70
+ children: [
71
+ liveUrl ? // The live site, in a tab of its own: the console stays where it is.
72
+ /*#__PURE__*/ _jsx(Button, {
73
+ variant: "contained",
74
+ size: "large",
75
+ component: "a",
76
+ href: liveUrl,
77
+ target: "_blank",
78
+ rel: "noopener noreferrer",
79
+ children: 'View your site'
80
+ }) : null,
81
+ pagesHref ? /*#__PURE__*/ _jsx(Button, {
82
+ variant: liveUrl ? 'outlined' : 'contained',
83
+ size: "large",
84
+ component: AppLink,
85
+ href: pagesHref,
86
+ children: 'Edit your pages'
87
+ }) : null
88
+ ]
89
+ })
90
+ ]
91
+ });
92
+ }
93
+ export default SiteLiveNotice;
94
+
95
+ //# sourceMappingURL=site-live-notice.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/site-live-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\n'use client'\n\nimport Button from '@mui/material/Button'\nimport Link from '@mui/material/Link'\nimport Stack from '@mui/material/Stack'\nimport Typography from '@mui/material/Typography'\nimport AppLink from './app-link'\n\nexport const SITE_LIVE_NOTICE_TITLE = 'Your site is live'\nexport const SITE_LIVE_NOTICE_BODY = 'Your pages are published, and anyone can visit your site now.'\n\nexport interface SiteLiveNoticeProps {\n /** The site's public address; without one the notice says it is live and offers only the pages. */\n liveUrl: string | null\n /** The console's page list for the site, where the pages are edited. */\n pagesHref: string | null\n /** The heading's level, for the page or dialog it sits in. */\n headingComponent?: 'h1' | 'h2' | 'h3'\n}\n\n/**\n * What a person sees the moment their site goes live: that it is live, the\n * address visitors use, and the two things to do next — look at it, or edit\n * its pages. Shared by every path that publishes a new site (the starter, the\n * guided AI start) so a site goes live in the same words whichever way it\n * was made.\n *\n * It exists because nothing said so. A starter site is published the moment\n * it is chosen, and a person who was never told read their analytics window\n * (\"14 days\") as a countdown to launch.\n */\nexport function SiteLiveNotice({ liveUrl, pagesHref, headingComponent = 'h2' }: SiteLiveNoticeProps) {\n return (\n <Stack spacing={2}>\n <Stack spacing={0.5}>\n <Typography variant=\"h5\" component={headingComponent}>\n {SITE_LIVE_NOTICE_TITLE}\n </Typography>\n <Typography variant=\"body1\" color=\"text.secondary\">\n {SITE_LIVE_NOTICE_BODY}\n </Typography>\n {liveUrl ? (\n <Link href={liveUrl} target=\"_blank\" rel=\"noopener noreferrer\" variant=\"body1\" sx={{ wordBreak: 'break-all' }}>\n {liveUrl.replace(/^https?:\\/\\//, '')}\n </Link>\n ) : null}\n </Stack>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {liveUrl ? (\n // The live site, in a tab of its own: the console stays where it is.\n <Button variant=\"contained\" size=\"large\" component=\"a\" href={liveUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {'View your site'}\n </Button>\n ) : null}\n {pagesHref ? (\n <Button variant={liveUrl ? 'outlined' : 'contained'} size=\"large\" component={AppLink} href={pagesHref}>\n {'Edit your pages'}\n </Button>\n ) : null}\n </Stack>\n </Stack>\n )\n}\n\nexport default SiteLiveNotice\n"],"names":["Button","Link","Stack","Typography","AppLink","SITE_LIVE_NOTICE_TITLE","SITE_LIVE_NOTICE_BODY","SiteLiveNotice","liveUrl","pagesHref","headingComponent","spacing","variant","component","color","href","target","rel","sx","wordBreak","replace","direction","xs","sm","size"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;AAEA,OAAOA,YAAY,uBAAsB;AACzC,OAAOC,UAAU,qBAAoB;AACrC,OAAOC,WAAW,sBAAqB;AACvC,OAAOC,gBAAgB,2BAA0B;AACjD,OAAOC,aAAa,gBAAY;AAEhC,OAAO,MAAMC,yBAAyB,oBAAmB;AACzD,OAAO,MAAMC,wBAAwB,gEAA+D;AAWpG;;;;;;;;;;CAUC,GACD,OAAO,SAASC,eAAe,EAAEC,OAAO,EAAEC,SAAS,EAAEC,mBAAmB,IAAI,EAAuB;IACjG,qBACE,MAACR;QAAMS,SAAS;;0BACd,MAACT;gBAAMS,SAAS;;kCACd,KAACR;wBAAWS,SAAQ;wBAAKC,WAAWH;kCACjCL;;kCAEH,KAACF;wBAAWS,SAAQ;wBAAQE,OAAM;kCAC/BR;;oBAEFE,wBACC,KAACP;wBAAKc,MAAMP;wBAASQ,QAAO;wBAASC,KAAI;wBAAsBL,SAAQ;wBAAQM,IAAI;4BAAEC,WAAW;wBAAY;kCACzGX,QAAQY,OAAO,CAAC,gBAAgB;yBAEjC;;;0BAEN,MAAClB;gBAAMmB,WAAW;oBAAEC,IAAI;oBAAUC,IAAI;gBAAM;gBAAGZ,SAAS;;oBACrDH,UACC,qEAAqE;kCACrE,KAACR;wBAAOY,SAAQ;wBAAYY,MAAK;wBAAQX,WAAU;wBAAIE,MAAMP;wBAASQ,QAAO;wBAASC,KAAI;kCACvF;yBAED;oBACHR,0BACC,KAACT;wBAAOY,SAASJ,UAAU,aAAa;wBAAagB,MAAK;wBAAQX,WAAWT;wBAASW,MAAMN;kCACzF;yBAED;;;;;AAIZ;AAEA,eAAeF,eAAc"}
@@ -0,0 +1,26 @@
1
+ import type { ReactElement } from 'react';
2
+ /**
3
+ * What a status says about the thing it labels. The five tones are the
4
+ * theme's own palette roles, so a status reads the same in every card.
5
+ */
6
+ export type StatusTone = 'neutral' | 'info' | 'success' | 'warning' | 'error';
7
+ export interface StatusChipProps {
8
+ label: string;
9
+ tone?: StatusTone;
10
+ /** An icon before the label, such as an `MdiIcon`. */
11
+ icon?: ReactElement;
12
+ /** Outlined for a quiet status beside other content; filled to stand out. */
13
+ variant?: 'filled' | 'outlined';
14
+ 'data-testid'?: string;
15
+ }
16
+ /**
17
+ * A record's state as a small chip — On, Connected, Needs attention
18
+ * (AGL-3637). Plugins mapped each status to a hand-picked MUI `Chip` color
19
+ * per card, and the same state came out in different colors on different
20
+ * cards; a tone names what the state means and the theme picks the color.
21
+ */
22
+ export declare function StatusChip(props: StatusChipProps): import("react").JSX.Element;
23
+ export declare namespace StatusChip {
24
+ var displayName: string;
25
+ }
26
+ export default StatusChip;
@@ -0,0 +1,48 @@
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 { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ import Chip from "@mui/material/Chip";
20
+ const TONE_COLOR = {
21
+ neutral: 'default',
22
+ info: 'info',
23
+ success: 'success',
24
+ warning: 'warning',
25
+ error: 'error'
26
+ };
27
+ /**
28
+ * A record's state as a small chip — On, Connected, Needs attention
29
+ * (AGL-3637). Plugins mapped each status to a hand-picked MUI `Chip` color
30
+ * per card, and the same state came out in different colors on different
31
+ * cards; a tone names what the state means and the theme picks the color.
32
+ */ export function StatusChip(props) {
33
+ const { label, tone = 'neutral', icon, variant = 'filled' } = props;
34
+ return /*#__PURE__*/ _jsx(Chip, _extends({
35
+ size: "small",
36
+ label: label,
37
+ color: TONE_COLOR[tone],
38
+ variant: variant
39
+ }, icon ? {
40
+ icon
41
+ } : {}, {
42
+ "data-testid": props['data-testid']
43
+ }));
44
+ }
45
+ StatusChip.displayName = 'StatusChip';
46
+ export default StatusChip;
47
+
48
+ //# sourceMappingURL=status-chip.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/status-chip.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 Chip, { type ChipProps } from '@mui/material/Chip'\nimport type { ReactElement } from 'react'\n\n/**\n * What a status says about the thing it labels. The five tones are the\n * theme's own palette roles, so a status reads the same in every card.\n */\nexport type StatusTone = 'neutral' | 'info' | 'success' | 'warning' | 'error'\n\nconst TONE_COLOR: Readonly<Record<StatusTone, ChipProps['color']>> = {\n neutral: 'default',\n info: 'info',\n success: 'success',\n warning: 'warning',\n error: 'error',\n}\n\nexport interface StatusChipProps {\n label: string\n tone?: StatusTone\n /** An icon before the label, such as an `MdiIcon`. */\n icon?: ReactElement\n /** Outlined for a quiet status beside other content; filled to stand out. */\n variant?: 'filled' | 'outlined'\n 'data-testid'?: string\n}\n\n/**\n * A record's state as a small chip — On, Connected, Needs attention\n * (AGL-3637). Plugins mapped each status to a hand-picked MUI `Chip` color\n * per card, and the same state came out in different colors on different\n * cards; a tone names what the state means and the theme picks the color.\n */\nexport function StatusChip(props: StatusChipProps) {\n const { label, tone = 'neutral', icon, variant = 'filled' } = props\n return (\n <Chip\n size=\"small\"\n label={label}\n color={TONE_COLOR[tone]}\n variant={variant}\n {...(icon ? { icon } : {})}\n data-testid={props['data-testid']}\n />\n )\n}\nStatusChip.displayName = 'StatusChip'\n\nexport default StatusChip\n"],"names":["Chip","TONE_COLOR","neutral","info","success","warning","error","StatusChip","props","label","tone","icon","variant","size","color","data-testid","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,OAAOA,UAA8B,qBAAoB;AASzD,MAAMC,aAA+D;IACnEC,SAAS;IACTC,MAAM;IACNC,SAAS;IACTC,SAAS;IACTC,OAAO;AACT;AAYA;;;;;CAKC,GACD,OAAO,SAASC,WAAWC,KAAsB;IAC/C,MAAM,EAAEC,KAAK,EAAEC,OAAO,SAAS,EAAEC,IAAI,EAAEC,UAAU,QAAQ,EAAE,GAAGJ;IAC9D,qBACE,KAACR;QACCa,MAAK;QACLJ,OAAOA;QACPK,OAAOb,UAAU,CAACS,KAAK;QACvBE,SAASA;OACJD,OAAO;QAAEA;IAAK,IAAI,CAAC;QACxBI,eAAaP,KAAK,CAAC,cAAc;;AAGvC;AACAD,WAAWS,WAAW,GAAG;AAEzB,eAAeT,WAAU"}
@@ -14,27 +14,4 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- import type { ListFilterField } from './list-filter';
18
- import type { ListFilterClause, ListFilterOption } from './list-grid-filter';
19
- /**
20
- * How an operator reads on a chip or in a sentence — "Owner is Dana",
21
- * "Created on or after 1 Jan". One map so every list that shows its
22
- * clauses back spells them the same way; an operator nothing here names
23
- * is shown as itself rather than hidden.
24
- */
25
- export declare function listFilterOperatorLabel(op: string): string;
26
- export declare const listFilterDay: (raw: string) => Date;
27
- /**
28
- * How a clause reads as a sentence — "Owner is Dana", "Created on or after
29
- * 1 Jan", "Reason is any of Bounced, Complained": its header, its operator,
30
- * and its value by the label of the option it names.
31
- *
32
- * ONE wording, used by the chips over a list and by the notices that say a
33
- * clause was not applied (`listQueryRefusals`), so the two cannot describe
34
- * the same clause differently.
35
- */
36
- export declare function listFilterClauseSentence(clause: ListFilterClause, context: {
37
- fields: readonly ListFilterField[];
38
- headers?: Readonly<Record<string, string>>;
39
- options?: Readonly<Record<string, readonly ListFilterOption[]>>;
40
- }): string;
17
+ export * from '@aglyn/shared-util-tools/list-query/list-filter-sentence';