@crisp-ui-kit/crisp 0.23.3 → 0.23.5
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/dist/cjs/components/fileupload/fileupload.js +1 -1
- package/dist/cjs/components/fileupload/fileupload.recipe.js +4 -0
- package/dist/cjs/components/toast/toast.js +2 -2
- package/dist/cjs/product/recordstable/recordstable.js +7 -1
- package/dist/cjs/product/recordstable/recordstable.recipe.js +4 -1
- package/dist/esm/components/fileupload/fileupload.js +1 -1
- package/dist/esm/components/fileupload/fileupload.recipe.js +4 -0
- package/dist/esm/components/toast/toast.js +2 -2
- package/dist/esm/product/recordstable/recordstable.js +7 -1
- package/dist/esm/product/recordstable/recordstable.recipe.js +4 -1
- package/dist/fileupload.css +4 -0
- package/dist/recordstable.css +4 -1
- package/dist/styles.css +8 -1
- package/package.json +1 -1
|
@@ -114,5 +114,5 @@ function FileUpload({ className, labels, "aria-label": ariaLabel, accept, disabl
|
|
|
114
114
|
// instead means attaching them here; without inputRef, `openFilePicker`
|
|
115
115
|
// finds no input and returns silently, so the dropzone opens nothing.
|
|
116
116
|
inputRef, dropzoneRef, } = api;
|
|
117
|
-
return ((0, jsx_runtime_1.jsxs)("div", { ...rest, className: (0, fileupload_recipe_1.fileuploadRecipe)({ className }), children: [(0, jsx_runtime_1.jsxs)("button", { ...dropzoneProps, ref: dropzoneRef, type: "button", className: "fileupload-zone", tabIndex: disabled ? -1 : 0, "aria-label": ariaLabel ?? t.hint, disabled: disabled, "data-dragging": dragging ? "" : undefined, "data-disabled": disabled ? "" : undefined, "data-invalid": invalid ? "" : undefined, onClick: () => openFilePicker(), children: [(0, jsx_runtime_1.jsx)("span", { className: "fileupload-title", children: t.title }), (0, jsx_runtime_1.jsx)("span", { className: "fileupload-hint", children: t.hint })] }), (0, jsx_runtime_1.jsx)("input", { ...hiddenInputProps, ref: inputRef, className: "fileupload-input" }), acceptedFileEntries.length > 0 && ((0, jsx_runtime_1.jsx)("ul", { className: "fileupload-list", children: acceptedFileEntries.map((entry) => ((0, jsx_runtime_1.jsxs)("li", { className: "fileupload-item", "data-status": entry.status, children: [(0, jsx_runtime_1.jsx)("span", { className: "fileupload-item-name", children: entry.file.name }), entry.status === "uploading" && entry.progress != null && ((0, jsx_runtime_1.jsx)("span", { className: "fileupload-progress", role: "progressbar", "aria-valuenow": Math.round(entry.progress), "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": entry.file.name, children: (0, jsx_runtime_1.jsx)("span", { className: "fileupload-progress-fill", style: { width: `${entry.progress}%` } }) })), (0, jsx_runtime_1.jsx)("span", { className: "fileupload-item-size", children: formatSize(entry.file.size) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "fileupload-remove", "aria-label": `${t.remove}: ${entry.file.name}`, onClick: () => removeFileEntry(entry.id), children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 13, strokeWidth: 2 }) })] }, entry.id))) })),
|
|
117
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ...rest, className: (0, fileupload_recipe_1.fileuploadRecipe)({ className }), children: [(0, jsx_runtime_1.jsxs)("button", { ...dropzoneProps, ref: dropzoneRef, type: "button", className: "fileupload-zone", tabIndex: disabled ? -1 : 0, "aria-label": ariaLabel ?? t.hint, disabled: disabled, "data-dragging": dragging ? "" : undefined, "data-disabled": disabled ? "" : undefined, "data-invalid": invalid ? "" : undefined, onClick: () => openFilePicker(), children: [(0, jsx_runtime_1.jsx)("span", { className: "fileupload-title", children: t.title }), (0, jsx_runtime_1.jsx)("span", { className: "fileupload-hint", children: t.hint })] }), (0, jsx_runtime_1.jsx)("input", { ...hiddenInputProps, ref: inputRef, className: "fileupload-input" }), acceptedFileEntries.length > 0 && ((0, jsx_runtime_1.jsx)("ul", { className: "fileupload-list", children: acceptedFileEntries.map((entry) => ((0, jsx_runtime_1.jsxs)("li", { className: "fileupload-item", "data-status": entry.status, children: [(0, jsx_runtime_1.jsx)("span", { className: "fileupload-item-name", children: entry.file.name }), entry.status === "uploading" && entry.progress != null && ((0, jsx_runtime_1.jsx)("span", { className: "fileupload-progress", role: "progressbar", "aria-valuenow": Math.round(entry.progress), "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": entry.file.name, children: (0, jsx_runtime_1.jsx)("span", { className: "fileupload-progress-fill", style: { width: `${entry.progress}%` } }) })), (0, jsx_runtime_1.jsx)("span", { className: "fileupload-item-size", children: formatSize(entry.file.size) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "fileupload-remove", "aria-label": `${t.remove}: ${entry.file.name}`, onClick: () => removeFileEntry(entry.id), children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 13, strokeWidth: 2 }) })] }, entry.id))) })), (0, jsx_runtime_1.jsx)("ul", { className: "fileupload-errors", "aria-live": "polite", children: rejections.map((r) => ((0, jsx_runtime_1.jsx)("li", { className: "fileupload-error", children: `${r.file.name}: ${r.errors.map((e) => t.errors[e] ?? e).join(" ")}` }, r.file.name))) })] }));
|
|
118
118
|
}
|
|
@@ -92,6 +92,10 @@ const config = (0, core_1.defineRecipe)({
|
|
|
92
92
|
& .fileupload-remove:focus-visible { outline-color: ${tokens_1.contract.strokeFocusRing}; }
|
|
93
93
|
|
|
94
94
|
& .fileupload-errors { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["0.5"]}; margin: 0; padding: 0; list-style: none; }
|
|
95
|
+
/* out of flow while empty, so the always-mounted live region costs no
|
|
96
|
+
layout: display:none would take it out of the accessibility tree, which
|
|
97
|
+
is the one thing it exists to be in */
|
|
98
|
+
& .fileupload-errors:empty { position: absolute; }
|
|
95
99
|
& .fileupload-error { color: ${tokens_1.contract.bgDanger}; font-size: ${tokens_1.contract.text.md}; line-height: 18px; }
|
|
96
100
|
`,
|
|
97
101
|
variants: {},
|
|
@@ -48,7 +48,7 @@ const ICONS = {
|
|
|
48
48
|
};
|
|
49
49
|
function ToastCard({ item, onClose, dismissLabel, }) {
|
|
50
50
|
const Icon = ICONS[item.tone ?? "info"];
|
|
51
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "toast",
|
|
51
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "toast", "data-tone": item.tone ?? "info", children: [(0, jsx_runtime_1.jsx)("span", { className: "toast-icon", children: (0, jsx_runtime_1.jsx)(Icon, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "toast-body", children: [(0, jsx_runtime_1.jsx)("div", { className: "toast-title", children: item.title }), item.description != null && ((0, jsx_runtime_1.jsx)("div", { className: "toast-desc", children: item.description })), item.action && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "toast-action", onClick: () => {
|
|
52
52
|
item.action?.onClick();
|
|
53
53
|
onClose();
|
|
54
54
|
}, children: item.action.label }))] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "toast-close", "aria-label": dismissLabel, onClick: onClose, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 15, strokeWidth: 2, "aria-hidden": "true" }) })] }));
|
|
@@ -84,7 +84,7 @@ function ToastProvider({ children, duration = 4000, dismissLabel = "Dismiss", re
|
|
|
84
84
|
return () => map.forEach(clearTimeout);
|
|
85
85
|
}, []);
|
|
86
86
|
const api = React.useMemo(() => ({ toast, dismiss }), [toast, dismiss]);
|
|
87
|
-
return ((0, jsx_runtime_1.jsxs)(ToastContext.Provider, { value: api, children: [children, (0, jsx_runtime_1.jsx)("div", { className: (0, toast_recipe_1.toastRecipe)(), children: (0, jsx_runtime_1.jsx)("div", { className: "toast-viewport", role: "region", "aria-label": regionLabel, children: items.map((t) => ((0, jsx_runtime_1.jsx)(ToastCard, { item: t, onClose: () => dismiss(t.id), dismissLabel: dismissLabel }, t.id))) }) })] }));
|
|
87
|
+
return ((0, jsx_runtime_1.jsxs)(ToastContext.Provider, { value: api, children: [children, (0, jsx_runtime_1.jsx)("div", { className: (0, toast_recipe_1.toastRecipe)(), children: (0, jsx_runtime_1.jsx)("div", { className: "toast-viewport", role: "region", "aria-label": regionLabel, "aria-live": "polite", "aria-atomic": "false", children: items.map((t) => ((0, jsx_runtime_1.jsx)(ToastCard, { item: t, onClose: () => dismiss(t.id), dismissLabel: dismissLabel }, t.id))) }) })] }));
|
|
88
88
|
}
|
|
89
89
|
ToastProvider.displayName = "ToastProvider";
|
|
90
90
|
function useToast() {
|
|
@@ -1045,7 +1045,13 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
1045
1045
|
const canEdit = canEditCol(col);
|
|
1046
1046
|
const isPicker = isPickerCol(col);
|
|
1047
1047
|
const isEditing = editing?.id === row.id && editing?.key === col.key;
|
|
1048
|
-
|
|
1048
|
+
// The first column is the record's NAME — it is what the row
|
|
1049
|
+
// is, not a value the row has. As a `<th scope="row">` a
|
|
1050
|
+
// screen reader reads "Google, Employees, 182,000" across the
|
|
1051
|
+
// row instead of a bare "182,000", and the same header is
|
|
1052
|
+
// repeated in every cell's context (#231).
|
|
1053
|
+
const Cell = (i === 0 ? "th" : "td");
|
|
1054
|
+
return ((0, jsx_runtime_1.jsxs)(Cell, { scope: i === 0 ? "row" : undefined, className: `recordstable-td${i === 0 ? " recordstable-col-entity" : ""}${canEdit ? " recordstable-td--editable" : ""}${isPicker ? " recordstable-td--picker" : ""}`, "data-enriched": col.enriched ? "" : undefined, "data-selected": selCell?.id === row.id && selCell?.key === col.key
|
|
1049
1055
|
? ""
|
|
1050
1056
|
: undefined, onClick: () => {
|
|
1051
1057
|
if (isPicker)
|
|
@@ -56,7 +56,10 @@ ${(0, tabletoolbar_chrome_1.toolbarChromeBody)("recordstable")}
|
|
|
56
56
|
& .recordstable-addcol button:hover { background: ${tokens_1.contract.bgRaised}; color: ${tokens_1.contract.fgPrimary}; }
|
|
57
57
|
|
|
58
58
|
/* cells */
|
|
59
|
-
|
|
59
|
+
/* font-weight is explicit because the first cell of each row is a
|
|
60
|
+
th[scope=row] — the record's name is what the row IS — and a th
|
|
61
|
+
defaults to bold. Measured before the change and unchanged after: 400. */
|
|
62
|
+
& .recordstable-td { font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.regular}; color: ${tokens_1.contract.fgPrimary}; background: ${tokens_1.contract.bgSurface}; cursor: default; }
|
|
60
63
|
& .recordstable-td--editable { cursor: text; }
|
|
61
64
|
/* keyboard/click cell selection (spreadsheet-style) */
|
|
62
65
|
& .recordstable-td[data-selected] { outline: 2px solid ${tokens_1.contract.bgBrandSolid}; outline-offset: -2px; border-radius: ${tokens_1.contract.radius.sm}; z-index: 3; }
|
|
@@ -77,5 +77,5 @@ export function FileUpload({ className, labels, "aria-label": ariaLabel, accept,
|
|
|
77
77
|
// instead means attaching them here; without inputRef, `openFilePicker`
|
|
78
78
|
// finds no input and returns silently, so the dropzone opens nothing.
|
|
79
79
|
inputRef, dropzoneRef, } = api;
|
|
80
|
-
return (_jsxs("div", { ...rest, className: fileuploadRecipe({ className }), children: [_jsxs("button", { ...dropzoneProps, ref: dropzoneRef, type: "button", className: "fileupload-zone", tabIndex: disabled ? -1 : 0, "aria-label": ariaLabel ?? t.hint, disabled: disabled, "data-dragging": dragging ? "" : undefined, "data-disabled": disabled ? "" : undefined, "data-invalid": invalid ? "" : undefined, onClick: () => openFilePicker(), children: [_jsx("span", { className: "fileupload-title", children: t.title }), _jsx("span", { className: "fileupload-hint", children: t.hint })] }), _jsx("input", { ...hiddenInputProps, ref: inputRef, className: "fileupload-input" }), acceptedFileEntries.length > 0 && (_jsx("ul", { className: "fileupload-list", children: acceptedFileEntries.map((entry) => (_jsxs("li", { className: "fileupload-item", "data-status": entry.status, children: [_jsx("span", { className: "fileupload-item-name", children: entry.file.name }), entry.status === "uploading" && entry.progress != null && (_jsx("span", { className: "fileupload-progress", role: "progressbar", "aria-valuenow": Math.round(entry.progress), "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": entry.file.name, children: _jsx("span", { className: "fileupload-progress-fill", style: { width: `${entry.progress}%` } }) })), _jsx("span", { className: "fileupload-item-size", children: formatSize(entry.file.size) }), _jsx("button", { type: "button", className: "fileupload-remove", "aria-label": `${t.remove}: ${entry.file.name}`, onClick: () => removeFileEntry(entry.id), children: _jsx(X, { size: 13, strokeWidth: 2 }) })] }, entry.id))) })),
|
|
80
|
+
return (_jsxs("div", { ...rest, className: fileuploadRecipe({ className }), children: [_jsxs("button", { ...dropzoneProps, ref: dropzoneRef, type: "button", className: "fileupload-zone", tabIndex: disabled ? -1 : 0, "aria-label": ariaLabel ?? t.hint, disabled: disabled, "data-dragging": dragging ? "" : undefined, "data-disabled": disabled ? "" : undefined, "data-invalid": invalid ? "" : undefined, onClick: () => openFilePicker(), children: [_jsx("span", { className: "fileupload-title", children: t.title }), _jsx("span", { className: "fileupload-hint", children: t.hint })] }), _jsx("input", { ...hiddenInputProps, ref: inputRef, className: "fileupload-input" }), acceptedFileEntries.length > 0 && (_jsx("ul", { className: "fileupload-list", children: acceptedFileEntries.map((entry) => (_jsxs("li", { className: "fileupload-item", "data-status": entry.status, children: [_jsx("span", { className: "fileupload-item-name", children: entry.file.name }), entry.status === "uploading" && entry.progress != null && (_jsx("span", { className: "fileupload-progress", role: "progressbar", "aria-valuenow": Math.round(entry.progress), "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": entry.file.name, children: _jsx("span", { className: "fileupload-progress-fill", style: { width: `${entry.progress}%` } }) })), _jsx("span", { className: "fileupload-item-size", children: formatSize(entry.file.size) }), _jsx("button", { type: "button", className: "fileupload-remove", "aria-label": `${t.remove}: ${entry.file.name}`, onClick: () => removeFileEntry(entry.id), children: _jsx(X, { size: 13, strokeWidth: 2 }) })] }, entry.id))) })), _jsx("ul", { className: "fileupload-errors", "aria-live": "polite", children: rejections.map((r) => (_jsx("li", { className: "fileupload-error", children: `${r.file.name}: ${r.errors.map((e) => t.errors[e] ?? e).join(" ")}` }, r.file.name))) })] }));
|
|
81
81
|
}
|
|
@@ -89,6 +89,10 @@ const config = defineRecipe({
|
|
|
89
89
|
& .fileupload-remove:focus-visible { outline-color: ${c.strokeFocusRing}; }
|
|
90
90
|
|
|
91
91
|
& .fileupload-errors { display: flex; flex-direction: column; gap: ${c.space["0.5"]}; margin: 0; padding: 0; list-style: none; }
|
|
92
|
+
/* out of flow while empty, so the always-mounted live region costs no
|
|
93
|
+
layout: display:none would take it out of the accessibility tree, which
|
|
94
|
+
is the one thing it exists to be in */
|
|
95
|
+
& .fileupload-errors:empty { position: absolute; }
|
|
92
96
|
& .fileupload-error { color: ${c.bgDanger}; font-size: ${c.text.md}; line-height: 18px; }
|
|
93
97
|
`,
|
|
94
98
|
variants: {},
|
|
@@ -11,7 +11,7 @@ const ICONS = {
|
|
|
11
11
|
};
|
|
12
12
|
function ToastCard({ item, onClose, dismissLabel, }) {
|
|
13
13
|
const Icon = ICONS[item.tone ?? "info"];
|
|
14
|
-
return (_jsxs("div", { className: "toast",
|
|
14
|
+
return (_jsxs("div", { className: "toast", "data-tone": item.tone ?? "info", children: [_jsx("span", { className: "toast-icon", children: _jsx(Icon, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }), _jsxs("div", { className: "toast-body", children: [_jsx("div", { className: "toast-title", children: item.title }), item.description != null && (_jsx("div", { className: "toast-desc", children: item.description })), item.action && (_jsx("button", { type: "button", className: "toast-action", onClick: () => {
|
|
15
15
|
item.action?.onClick();
|
|
16
16
|
onClose();
|
|
17
17
|
}, children: item.action.label }))] }), _jsx("button", { type: "button", className: "toast-close", "aria-label": dismissLabel, onClick: onClose, children: _jsx(X, { size: 15, strokeWidth: 2, "aria-hidden": "true" }) })] }));
|
|
@@ -47,7 +47,7 @@ export function ToastProvider({ children, duration = 4000, dismissLabel = "Dismi
|
|
|
47
47
|
return () => map.forEach(clearTimeout);
|
|
48
48
|
}, []);
|
|
49
49
|
const api = React.useMemo(() => ({ toast, dismiss }), [toast, dismiss]);
|
|
50
|
-
return (_jsxs(ToastContext.Provider, { value: api, children: [children, _jsx("div", { className: toastRecipe(), children: _jsx("div", { className: "toast-viewport", role: "region", "aria-label": regionLabel, children: items.map((t) => (_jsx(ToastCard, { item: t, onClose: () => dismiss(t.id), dismissLabel: dismissLabel }, t.id))) }) })] }));
|
|
50
|
+
return (_jsxs(ToastContext.Provider, { value: api, children: [children, _jsx("div", { className: toastRecipe(), children: _jsx("div", { className: "toast-viewport", role: "region", "aria-label": regionLabel, "aria-live": "polite", "aria-atomic": "false", children: items.map((t) => (_jsx(ToastCard, { item: t, onClose: () => dismiss(t.id), dismissLabel: dismissLabel }, t.id))) }) })] }));
|
|
51
51
|
}
|
|
52
52
|
ToastProvider.displayName = "ToastProvider";
|
|
53
53
|
export function useToast() {
|
|
@@ -1005,7 +1005,13 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
1005
1005
|
const canEdit = canEditCol(col);
|
|
1006
1006
|
const isPicker = isPickerCol(col);
|
|
1007
1007
|
const isEditing = editing?.id === row.id && editing?.key === col.key;
|
|
1008
|
-
|
|
1008
|
+
// The first column is the record's NAME — it is what the row
|
|
1009
|
+
// is, not a value the row has. As a `<th scope="row">` a
|
|
1010
|
+
// screen reader reads "Google, Employees, 182,000" across the
|
|
1011
|
+
// row instead of a bare "182,000", and the same header is
|
|
1012
|
+
// repeated in every cell's context (#231).
|
|
1013
|
+
const Cell = (i === 0 ? "th" : "td");
|
|
1014
|
+
return (_jsxs(Cell, { scope: i === 0 ? "row" : undefined, className: `recordstable-td${i === 0 ? " recordstable-col-entity" : ""}${canEdit ? " recordstable-td--editable" : ""}${isPicker ? " recordstable-td--picker" : ""}`, "data-enriched": col.enriched ? "" : undefined, "data-selected": selCell?.id === row.id && selCell?.key === col.key
|
|
1009
1015
|
? ""
|
|
1010
1016
|
: undefined, onClick: () => {
|
|
1011
1017
|
if (isPicker)
|
|
@@ -53,7 +53,10 @@ ${toolbarChromeBody("recordstable")}
|
|
|
53
53
|
& .recordstable-addcol button:hover { background: ${c.bgRaised}; color: ${c.fgPrimary}; }
|
|
54
54
|
|
|
55
55
|
/* cells */
|
|
56
|
-
|
|
56
|
+
/* font-weight is explicit because the first cell of each row is a
|
|
57
|
+
th[scope=row] — the record's name is what the row IS — and a th
|
|
58
|
+
defaults to bold. Measured before the change and unchanged after: 400. */
|
|
59
|
+
& .recordstable-td { font-size: ${c.text.lg}; font-weight: ${c.weight.regular}; color: ${c.fgPrimary}; background: ${c.bgSurface}; cursor: default; }
|
|
57
60
|
& .recordstable-td--editable { cursor: text; }
|
|
58
61
|
/* keyboard/click cell selection (spreadsheet-style) */
|
|
59
62
|
& .recordstable-td[data-selected] { outline: 2px solid ${c.bgBrandSolid}; outline-offset: -2px; border-radius: ${c.radius.sm}; z-index: 3; }
|
package/dist/fileupload.css
CHANGED
|
@@ -72,6 +72,10 @@
|
|
|
72
72
|
& .fileupload-remove:focus-visible { outline-color: var(--stroke-focus-ring); }
|
|
73
73
|
|
|
74
74
|
& .fileupload-errors { display: flex; flex-direction: column; gap: var(--space-0-5); margin: 0; padding: 0; list-style: none; }
|
|
75
|
+
/* out of flow while empty, so the always-mounted live region costs no
|
|
76
|
+
layout: display:none would take it out of the accessibility tree, which
|
|
77
|
+
is the one thing it exists to be in */
|
|
78
|
+
& .fileupload-errors:empty { position: absolute; }
|
|
75
79
|
& .fileupload-error { color: var(--bg-danger); font-size: var(--text-md); line-height: 18px; }
|
|
76
80
|
|
|
77
81
|
}
|
package/dist/recordstable.css
CHANGED
|
@@ -101,7 +101,10 @@
|
|
|
101
101
|
& .recordstable-addcol button:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
102
102
|
|
|
103
103
|
/* cells */
|
|
104
|
-
|
|
104
|
+
/* font-weight is explicit because the first cell of each row is a
|
|
105
|
+
th[scope=row] — the record's name is what the row IS — and a th
|
|
106
|
+
defaults to bold. Measured before the change and unchanged after: 400. */
|
|
107
|
+
& .recordstable-td { font-size: var(--text-lg); font-weight: var(--weight-regular); color: var(--fg-primary); background: var(--bg-surface); cursor: default; }
|
|
105
108
|
& .recordstable-td--editable { cursor: text; }
|
|
106
109
|
/* keyboard/click cell selection (spreadsheet-style) */
|
|
107
110
|
& .recordstable-td[data-selected] { outline: 2px solid var(--bg-brand-solid); outline-offset: -2px; border-radius: var(--radius-sm); z-index: 3; }
|
package/dist/styles.css
CHANGED
|
@@ -950,6 +950,10 @@
|
|
|
950
950
|
& .fileupload-remove:focus-visible { outline-color: var(--stroke-focus-ring); }
|
|
951
951
|
|
|
952
952
|
& .fileupload-errors { display: flex; flex-direction: column; gap: var(--space-0-5); margin: 0; padding: 0; list-style: none; }
|
|
953
|
+
/* out of flow while empty, so the always-mounted live region costs no
|
|
954
|
+
layout: display:none would take it out of the accessibility tree, which
|
|
955
|
+
is the one thing it exists to be in */
|
|
956
|
+
& .fileupload-errors:empty { position: absolute; }
|
|
953
957
|
& .fileupload-error { color: var(--bg-danger); font-size: var(--text-md); line-height: 18px; }
|
|
954
958
|
|
|
955
959
|
}
|
|
@@ -2499,7 +2503,10 @@
|
|
|
2499
2503
|
& .recordstable-addcol button:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
2500
2504
|
|
|
2501
2505
|
/* cells */
|
|
2502
|
-
|
|
2506
|
+
/* font-weight is explicit because the first cell of each row is a
|
|
2507
|
+
th[scope=row] — the record's name is what the row IS — and a th
|
|
2508
|
+
defaults to bold. Measured before the change and unchanged after: 400. */
|
|
2509
|
+
& .recordstable-td { font-size: var(--text-lg); font-weight: var(--weight-regular); color: var(--fg-primary); background: var(--bg-surface); cursor: default; }
|
|
2503
2510
|
& .recordstable-td--editable { cursor: text; }
|
|
2504
2511
|
/* keyboard/click cell selection (spreadsheet-style) */
|
|
2505
2512
|
& .recordstable-td[data-selected] { outline: 2px solid var(--bg-brand-solid); outline-offset: -2px; border-radius: var(--radius-sm); z-index: 3; }
|