@crisp-ui-kit/crisp 0.57.1 → 0.57.3
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/authshell.css +9 -4
- package/dist/authshell.layered.css +9 -4
- package/dist/badge.css +3 -3
- package/dist/badge.layered.css +3 -3
- package/dist/board.css +28 -8
- package/dist/board.layered.css +28 -8
- package/dist/bottomsheet.css +26 -0
- package/dist/bottomsheet.d.ts +7 -0
- package/dist/bottomsheet.layered.css +28 -0
- package/dist/button.css +10 -6
- package/dist/button.d.ts +2 -2
- package/dist/button.layered.css +10 -6
- package/dist/checkbox.css +7 -3
- package/dist/checkbox.layered.css +7 -3
- package/dist/chip.css +16 -1
- package/dist/chip.d.ts +3 -1
- package/dist/chip.layered.css +16 -1
- package/dist/chipgroup.css +5 -0
- package/dist/chipgroup.d.ts +7 -0
- package/dist/chipgroup.layered.css +7 -0
- package/dist/cjs/components/badge/badge.recipe.js +22 -8
- package/dist/cjs/components/bottomsheet/bottomsheet.js +90 -0
- package/dist/cjs/components/bottomsheet/bottomsheet.recipe.js +77 -0
- package/dist/cjs/components/bottomsheet/index.js +9 -0
- package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/cjs/components/button/button.recipe.js +67 -15
- package/dist/cjs/components/checkbox/checkbox.recipe.js +61 -9
- package/dist/cjs/components/chip/chip.js +14 -2
- package/dist/cjs/components/chip/chip.recipe.js +72 -2
- package/dist/cjs/components/chipgroup/chipgroup.js +51 -0
- package/dist/cjs/components/chipgroup/chipgroup.recipe.js +36 -0
- package/dist/cjs/components/chipgroup/index.js +7 -0
- package/dist/cjs/components/datatable/datatable.js +5 -1
- package/dist/cjs/components/datatable/datatable.recipe.js +21 -6
- package/dist/cjs/components/datepickerfield/datepickerfield.js +2 -2
- package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +16 -3
- package/dist/cjs/components/dialog/dialog.recipe.js +21 -10
- package/dist/cjs/components/emptystate/emptystate.recipe.js +7 -2
- package/dist/cjs/components/fileupload/fileupload.js +21 -4
- package/dist/cjs/components/input/index.js +2 -1
- package/dist/cjs/components/input/input.js +31 -1
- package/dist/cjs/components/input/input.recipe.js +16 -9
- package/dist/cjs/components/menu/menu.js +18 -2
- package/dist/cjs/components/menu/menu.recipe.js +21 -7
- package/dist/cjs/components/menusheet/index.js +9 -0
- package/dist/cjs/components/menusheet/menusheet.js +133 -0
- package/dist/cjs/components/menusheet/menusheet.recipe.js +103 -0
- package/dist/cjs/components/multiselect/multiselect.js +1 -1
- package/dist/cjs/components/multiselect/multiselect.recipe.js +33 -9
- package/dist/cjs/components/select/select.js +1 -1
- package/dist/cjs/components/select/select.recipe.js +38 -12
- package/dist/cjs/components/snackbar/index.js +8 -0
- package/dist/cjs/components/snackbar/snackbar.js +121 -0
- package/dist/cjs/components/snackbar/snackbar.recipe.js +71 -0
- package/dist/cjs/components/table/table.recipe.js +7 -1
- package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
- package/dist/cjs/components/tabletoolbar/tabletoolbar.js +37 -12
- package/dist/cjs/components/tabs/tabs.js +10 -4
- package/dist/cjs/components/tabs/tabs.recipe.js +23 -6
- package/dist/cjs/components/textarea/textarea.recipe.js +11 -8
- package/dist/cjs/core/floating-portal.js +7 -4
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/product/authshell/authshell.recipe.js +5 -1
- package/dist/cjs/product/command/command.recipe.js +4 -1
- package/dist/cjs/product/comments/comments.js +7 -2
- package/dist/cjs/product/comments/comments.recipe.js +25 -7
- package/dist/cjs/product/inbox/inbox.js +11 -3
- package/dist/cjs/product/memberssettings/index.js +6 -0
- package/dist/cjs/product/memberssettings/memberssettings.js +99 -0
- package/dist/cjs/product/memberssettings/memberssettings.recipe.js +83 -0
- package/dist/cjs/product/notificationssettings/index.js +5 -0
- package/dist/cjs/product/notificationssettings/notificationssettings.js +19 -0
- package/dist/cjs/product/notificationssettings/notificationssettings.recipe.js +44 -0
- package/dist/cjs/product/recordpage/index.js +2 -1
- package/dist/cjs/product/recordpage/recordpage.js +106 -9
- package/dist/cjs/product/recordpage/recordpage.recipe.js +68 -6
- package/dist/cjs/product/workspacegeneralsettings/index.js +5 -0
- package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.js +21 -0
- package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +51 -0
- package/dist/cjs/tokens/contract.js +1 -0
- package/dist/cjs/tokens/elevation.js +8 -5
- package/dist/cjs/tokens/palette.js +28 -8
- package/dist/cjs/tokens/scale.js +44 -2
- package/dist/cjs/tokens/semantic.js +2 -0
- package/dist/columncalc.css +15 -7
- package/dist/columncalc.layered.css +15 -7
- package/dist/command.css +23 -19
- package/dist/command.layered.css +23 -19
- package/dist/comments.css +28 -19
- package/dist/comments.d.ts +2 -2
- package/dist/comments.layered.css +28 -19
- package/dist/datatable.css +171 -71
- package/dist/datatable.layered.css +171 -71
- package/dist/datepicker.css +13 -41
- package/dist/datepicker.layered.css +13 -41
- package/dist/datepickerfield.css +12 -3
- package/dist/datepickerfield.d.ts +2 -2
- package/dist/datepickerfield.layered.css +12 -3
- package/dist/dialog.css +12 -7
- package/dist/dialog.layered.css +12 -7
- package/dist/emptystate.css +5 -3
- package/dist/emptystate.layered.css +5 -3
- package/dist/esm/components/badge/badge.recipe.js +22 -8
- package/dist/esm/components/bottomsheet/bottomsheet.js +52 -0
- package/dist/esm/components/bottomsheet/bottomsheet.recipe.js +74 -0
- package/dist/esm/components/bottomsheet/index.js +2 -0
- package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/esm/components/button/button.recipe.js +68 -16
- package/dist/esm/components/checkbox/checkbox.recipe.js +61 -9
- package/dist/esm/components/chip/chip.js +14 -2
- package/dist/esm/components/chip/chip.recipe.js +72 -2
- package/dist/esm/components/chipgroup/chipgroup.js +15 -0
- package/dist/esm/components/chipgroup/chipgroup.recipe.js +33 -0
- package/dist/esm/components/chipgroup/index.js +2 -0
- package/dist/esm/components/datatable/datatable.js +5 -1
- package/dist/esm/components/datatable/datatable.recipe.js +21 -6
- package/dist/esm/components/datepickerfield/datepickerfield.js +2 -2
- package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +16 -3
- package/dist/esm/components/dialog/dialog.recipe.js +22 -11
- package/dist/esm/components/emptystate/emptystate.recipe.js +7 -2
- package/dist/esm/components/fileupload/fileupload.js +20 -5
- package/dist/esm/components/input/index.js +1 -1
- package/dist/esm/components/input/input.js +30 -0
- package/dist/esm/components/input/input.recipe.js +17 -10
- package/dist/esm/components/menu/menu.js +18 -2
- package/dist/esm/components/menu/menu.recipe.js +21 -7
- package/dist/esm/components/menusheet/index.js +2 -0
- package/dist/esm/components/menusheet/menusheet.js +95 -0
- package/dist/esm/components/menusheet/menusheet.recipe.js +100 -0
- package/dist/esm/components/multiselect/multiselect.js +1 -1
- package/dist/esm/components/multiselect/multiselect.recipe.js +33 -9
- package/dist/esm/components/select/select.js +1 -1
- package/dist/esm/components/select/select.recipe.js +38 -12
- package/dist/esm/components/snackbar/index.js +2 -0
- package/dist/esm/components/snackbar/snackbar.js +84 -0
- package/dist/esm/components/snackbar/snackbar.recipe.js +68 -0
- package/dist/esm/components/table/table.recipe.js +7 -1
- package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
- package/dist/esm/components/tabletoolbar/tabletoolbar.js +37 -12
- package/dist/esm/components/tabs/tabs.js +10 -4
- package/dist/esm/components/tabs/tabs.recipe.js +23 -6
- package/dist/esm/components/textarea/textarea.recipe.js +12 -9
- package/dist/esm/core/floating-portal.js +7 -4
- package/dist/esm/index.js +7 -0
- package/dist/esm/product/authshell/authshell.recipe.js +5 -1
- package/dist/esm/product/command/command.recipe.js +4 -1
- package/dist/esm/product/comments/comments.js +7 -2
- package/dist/esm/product/comments/comments.recipe.js +25 -7
- package/dist/esm/product/inbox/inbox.js +11 -3
- package/dist/esm/product/memberssettings/index.js +1 -0
- package/dist/esm/product/memberssettings/memberssettings.js +62 -0
- package/dist/esm/product/memberssettings/memberssettings.recipe.js +80 -0
- package/dist/esm/product/notificationssettings/index.js +1 -0
- package/dist/esm/product/notificationssettings/notificationssettings.js +16 -0
- package/dist/esm/product/notificationssettings/notificationssettings.recipe.js +41 -0
- package/dist/esm/product/recordpage/index.js +1 -1
- package/dist/esm/product/recordpage/recordpage.js +106 -10
- package/dist/esm/product/recordpage/recordpage.recipe.js +68 -6
- package/dist/esm/product/workspacegeneralsettings/index.js +1 -0
- package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.js +18 -0
- package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +48 -0
- package/dist/esm/tokens/contract.js +2 -1
- package/dist/esm/tokens/elevation.js +8 -5
- package/dist/esm/tokens/palette.js +28 -8
- package/dist/esm/tokens/scale.js +43 -1
- package/dist/esm/tokens/semantic.js +2 -0
- package/dist/fileupload.css +3 -1
- package/dist/fileupload.layered.css +3 -1
- package/dist/input.css +6 -4
- package/dist/input.layered.css +6 -4
- package/dist/listpage.css +3 -1
- package/dist/listpage.layered.css +3 -1
- package/dist/memberssettings.css +67 -0
- package/dist/memberssettings.d.ts +7 -0
- package/dist/memberssettings.layered.css +69 -0
- package/dist/menu.css +2 -2
- package/dist/menu.layered.css +2 -2
- package/dist/menusheet.css +36 -0
- package/dist/menusheet.d.ts +7 -0
- package/dist/menusheet.layered.css +38 -0
- package/dist/multiselect.css +13 -6
- package/dist/multiselect.layered.css +13 -6
- package/dist/native/tokens.d.ts +2 -1
- package/dist/native/tokens.js +20 -3
- package/dist/notificationssettings.css +22 -0
- package/dist/notificationssettings.d.ts +7 -0
- package/dist/notificationssettings.layered.css +24 -0
- package/dist/objectsettings.css +4 -4
- package/dist/objectsettings.layered.css +4 -4
- package/dist/recordpage.css +90 -23
- package/dist/recordpage.layered.css +90 -23
- package/dist/recordpanel.css +35 -16
- package/dist/recordpanel.layered.css +35 -16
- package/dist/resizablepanel.css +8 -5
- package/dist/resizablepanel.layered.css +8 -5
- package/dist/richtext.css +24 -8
- package/dist/richtext.layered.css +24 -8
- package/dist/savedviews.css +9 -2
- package/dist/savedviews.layered.css +9 -2
- package/dist/select.css +25 -5
- package/dist/select.layered.css +25 -5
- package/dist/settingsshell.css +2 -3
- package/dist/settingsshell.layered.css +2 -3
- package/dist/slider.css +6 -27
- package/dist/slider.layered.css +6 -27
- package/dist/snackbar.css +24 -0
- package/dist/snackbar.d.ts +7 -0
- package/dist/snackbar.layered.css +26 -0
- package/dist/statcard.css +3 -1
- package/dist/statcard.layered.css +3 -1
- package/dist/styles.css +911 -354
- package/dist/styles.layered.css +911 -354
- package/dist/table.css +35 -12
- package/dist/table.layered.css +35 -12
- package/dist/tabletoolbar.css +35 -24
- package/dist/tabletoolbar.layered.css +35 -24
- package/dist/tabs.css +18 -4
- package/dist/tabs.layered.css +18 -4
- package/dist/textarea.css +2 -6
- package/dist/textarea.layered.css +2 -6
- package/dist/themepicker.css +2 -1
- package/dist/themepicker.layered.css +2 -1
- package/dist/tokens.css +13 -2
- package/dist/tokens.json +20 -3
- package/dist/types/components/bottomsheet/bottomsheet.d.ts +35 -0
- package/dist/types/components/bottomsheet/bottomsheet.recipe.d.ts +3 -0
- package/dist/types/components/bottomsheet/index.d.ts +2 -0
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +9 -1
- package/dist/types/components/button/button.d.ts +2 -0
- package/dist/types/components/button/button.recipe.d.ts +24 -6
- package/dist/types/components/checkbox/checkbox.recipe.d.ts +28 -5
- package/dist/types/components/chip/chip.d.ts +22 -0
- package/dist/types/components/chip/chip.recipe.d.ts +49 -1
- package/dist/types/components/chipgroup/chipgroup.d.ts +14 -0
- package/dist/types/components/chipgroup/chipgroup.recipe.d.ts +5 -0
- package/dist/types/components/chipgroup/index.d.ts +2 -0
- package/dist/types/components/datatable/datatable.d.ts +19 -0
- package/dist/types/components/datepickerfield/datepickerfield.d.ts +4 -1
- package/dist/types/components/datepickerfield/datepickerfield.recipe.d.ts +18 -3
- package/dist/types/components/fileupload/fileupload.d.ts +26 -0
- package/dist/types/components/input/index.d.ts +1 -1
- package/dist/types/components/input/input.d.ts +72 -0
- package/dist/types/components/menusheet/index.d.ts +2 -0
- package/dist/types/components/menusheet/menusheet.d.ts +42 -0
- package/dist/types/components/menusheet/menusheet.recipe.d.ts +3 -0
- package/dist/types/components/snackbar/index.d.ts +2 -0
- package/dist/types/components/snackbar/snackbar.d.ts +36 -0
- package/dist/types/components/snackbar/snackbar.recipe.d.ts +5 -0
- package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +28 -1
- package/dist/types/components/tabs/tabs.d.ts +11 -1
- package/dist/types/core/floating-portal.d.ts +6 -5
- package/dist/types/index.d.ts +7 -0
- package/dist/types/product/comments/comments.d.ts +9 -3
- package/dist/types/product/comments/comments.recipe.d.ts +12 -2
- package/dist/types/product/inbox/inbox.d.ts +13 -1
- package/dist/types/product/memberssettings/index.d.ts +1 -0
- package/dist/types/product/memberssettings/memberssettings.d.ts +85 -0
- package/dist/types/product/memberssettings/memberssettings.recipe.d.ts +3 -0
- package/dist/types/product/notificationssettings/index.d.ts +1 -0
- package/dist/types/product/notificationssettings/notificationssettings.d.ts +37 -0
- package/dist/types/product/notificationssettings/notificationssettings.recipe.d.ts +3 -0
- package/dist/types/product/recordpage/index.d.ts +1 -1
- package/dist/types/product/recordpage/recordpage.d.ts +99 -2
- package/dist/types/product/workspacegeneralsettings/index.d.ts +1 -0
- package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.d.ts +48 -0
- package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.recipe.d.ts +3 -0
- package/dist/types/tokens/contract.d.ts +4 -1
- package/dist/types/tokens/elevation.d.ts +8 -5
- package/dist/types/tokens/palette.d.ts +9 -1
- package/dist/types/tokens/scale.d.ts +11 -1
- package/dist/types/tokens/semantic.d.ts +2 -0
- package/dist/wheelpicker.css +4 -2
- package/dist/wheelpicker.layered.css +4 -2
- package/dist/workspacegeneralsettings.css +30 -0
- package/dist/workspacegeneralsettings.d.ts +7 -0
- package/dist/workspacegeneralsettings.layered.css +32 -0
- package/package.json +36 -1
|
@@ -179,6 +179,11 @@ const toolbarChromeBody = (p) => ` & .${namespace_1.CLASS_PREFIX}${p}-menu-he
|
|
|
179
179
|
& .${namespace_1.CLASS_PREFIX}${p}-fchip-x:hover { background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 10%, transparent); color: ${tokens_1.contract.fgPrimary}; }
|
|
180
180
|
& .${namespace_1.CLASS_PREFIX}${p}-spacer { flex: 1; }
|
|
181
181
|
& .${namespace_1.CLASS_PREFIX}${p}-count { font-size: ${tokens_1.contract.text.md}; color: ${tokens_1.contract.fgMuted}; }
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
/* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
|
|
183
|
+
the accent (#0298d9) only clears 3.23:1 with white; the darker sibling
|
|
184
|
+
clears 4.5:1+, same fix already applied to Button/Badge/Avatar (#897).
|
|
185
|
+
Hover is a brightness filter on the new fill, not bgBrandSolidPressed
|
|
186
|
+
(that token stays tuned for the lighter accent's own consumers). */
|
|
187
|
+
& .${namespace_1.CLASS_PREFIX}${p}-new { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1"]}; height: ${tokens_1.contract.size.row}; padding: 0 ${tokens_1.contract.space["2.5"]}; border: none; border-radius: ${tokens_1.contract.radius.md}; background: ${tokens_1.contract.bgBrandContrast}; color: ${tokens_1.contract.fgOnBrand}; font-family: inherit; font-size: ${tokens_1.contract.text.md}; font-weight: ${tokens_1.contract.weight.medium}; cursor: pointer; transition: filter .12s; }
|
|
188
|
+
& .${namespace_1.CLASS_PREFIX}${p}-new:hover { filter: brightness(0.96); }`;
|
|
184
189
|
exports.toolbarChromeBody = toolbarChromeBody;
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ToolbarTool = void 0;
|
|
36
|
+
exports.ToolbarTool = exports.toolbarOperatorLabels = void 0;
|
|
37
37
|
exports.applyFilters = applyFilters;
|
|
38
38
|
exports.applySorts = applySorts;
|
|
39
39
|
exports.TableToolbar = TableToolbar;
|
|
@@ -83,7 +83,7 @@ function ViewBarSlot({ target, children, }) {
|
|
|
83
83
|
// file, not per call site, and three independently attributed tags for
|
|
84
84
|
// the same name over-counts against that (it expects one per name).
|
|
85
85
|
const RtlChevronRight = ({ size, className, }) => ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { "data-rtl-flip": "", size: size, strokeWidth: 1.75, className: className }));
|
|
86
|
-
|
|
86
|
+
exports.toolbarOperatorLabels = {
|
|
87
87
|
contains: "contains",
|
|
88
88
|
doesnotcontain: "does not contain",
|
|
89
89
|
startswith: "starts with",
|
|
@@ -104,6 +104,33 @@ const OP_LABELS = {
|
|
|
104
104
|
before: "before",
|
|
105
105
|
after: "after",
|
|
106
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* crisp/#962: resolves each operator word through four layers, explicit
|
|
109
|
+
* prop winning, same "prop beats provider beats built-in" order as every
|
|
110
|
+
* other label in this file — `operatorLabels` prop, then a
|
|
111
|
+
* `CrispMessagesProvider`'s `componentDefaults.tableToolbar` (the new,
|
|
112
|
+
* discoverable, typed override), then the OLD whole-`CrispMessages`-
|
|
113
|
+
* dictionary-keyed-by-English-string lookup this file already had (kept
|
|
114
|
+
* so a consumer who already added entries there keeps working, unchanged),
|
|
115
|
+
* then the hardcoded English word. Not `useCrispMessage` in a loop over 13
|
|
116
|
+
* keys — that breaks the rules of hooks the same reason `useCrispMessages`
|
|
117
|
+
* itself exists (see that hook's own doc comment).
|
|
118
|
+
*/
|
|
119
|
+
function useToolbarOperatorLabels(operatorLabels, crispMessages) {
|
|
120
|
+
const providerLabels = (0, core_1.useCrispComponentDefaults)("tableToolbar");
|
|
121
|
+
return React.useMemo(() => {
|
|
122
|
+
const resolved = {};
|
|
123
|
+
for (const op of Object.keys(exports.toolbarOperatorLabels)) {
|
|
124
|
+
const builtIn = exports.toolbarOperatorLabels[op];
|
|
125
|
+
resolved[op] =
|
|
126
|
+
operatorLabels?.[op] ??
|
|
127
|
+
providerLabels?.[op] ??
|
|
128
|
+
crispMessages[builtIn] ??
|
|
129
|
+
builtIn;
|
|
130
|
+
}
|
|
131
|
+
return resolved;
|
|
132
|
+
}, [operatorLabels, providerLabels, crispMessages]);
|
|
133
|
+
}
|
|
107
134
|
// #619: order and label set match Attio's own text-filter operator picker
|
|
108
135
|
// verbatim (measured live, per RecordsTable's own #578 port of the same
|
|
109
136
|
// set: contains · does not contain · starts with · ends with · is · is not ·
|
|
@@ -368,7 +395,7 @@ function applySorts(rows, sorts, get = (row, key) => row[key]) {
|
|
|
368
395
|
* this (Sort: Due date/Assignee/Creation date; Filter: Assignee/Record/
|
|
369
396
|
* Created by), which one shared list can't reproduce.
|
|
370
397
|
*/
|
|
371
|
-
function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: filterColumnsProp, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel: sortLabelProp, filterLabel: filterLabelProp, reorderSortLabel: reorderSortLabelProp, noSortsLabel: noSortsLabelProp, addSortLabel: addSortLabelProp, learnSortingLabel: learnSortingLabelProp, selectConditionLabel: selectConditionLabelProp, sortFieldLabel: sortFieldLabelProp, sortDirectionLabel: sortDirectionLabelProp, removeSortLabel: removeSortLabelProp, filterFieldLabel: filterFieldLabelProp, filterFieldPlaceholder: filterFieldPlaceholderProp, filterValuePlaceholder: filterValuePlaceholderProp, filterOptionsLabel: filterOptionsLabelProp, deleteFilterLabel: deleteFilterLabelProp, ascendingLabel: ascendingLabelProp, descendingLabel: descendingLabelProp, sortTriggerLabel, filterTriggerLabel, inline, showSort = true, showViewSettings = true, viewSettingsRef, importExportRef, viewColumns: viewColumnsProp, shownKeys: shownKeysProp, defaultShownKeys, onShownKeysChange, viewSettingsLabel: viewSettingsLabelProp, reorderAttributeLabel: reorderAttributeLabelProp, hideAttributeLabel, addAttributeToViewLabel: addAttributeToViewLabelProp, searchAttributesPlaceholder: searchAttributesPlaceholderProp, importExportLabel: importExportLabelProp, onImportCsv, onExportCsv, onExportExcel, importExportHelpHref, importCsvLabel: importCsvLabelProp, exportCsvLabel: exportCsvLabelProp, exportExcelLabel: exportExcelLabelProp, learnImportExportLabel: learnImportExportLabelProp, backLabel: backLabelProp, nestedFieldPlaceholder, ...rest }) {
|
|
398
|
+
function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: filterColumnsProp, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel: sortLabelProp, filterLabel: filterLabelProp, reorderSortLabel: reorderSortLabelProp, noSortsLabel: noSortsLabelProp, addSortLabel: addSortLabelProp, learnSortingLabel: learnSortingLabelProp, selectConditionLabel: selectConditionLabelProp, sortFieldLabel: sortFieldLabelProp, sortDirectionLabel: sortDirectionLabelProp, removeSortLabel: removeSortLabelProp, filterFieldLabel: filterFieldLabelProp, filterFieldPlaceholder: filterFieldPlaceholderProp, filterValuePlaceholder: filterValuePlaceholderProp, filterOptionsLabel: filterOptionsLabelProp, deleteFilterLabel: deleteFilterLabelProp, operatorLabels, ascendingLabel: ascendingLabelProp, descendingLabel: descendingLabelProp, sortTriggerLabel, filterTriggerLabel, inline, showSort = true, showViewSettings = true, viewSettingsRef, importExportRef, viewColumns: viewColumnsProp, shownKeys: shownKeysProp, defaultShownKeys, onShownKeysChange, viewSettingsLabel: viewSettingsLabelProp, reorderAttributeLabel: reorderAttributeLabelProp, hideAttributeLabel, addAttributeToViewLabel: addAttributeToViewLabelProp, searchAttributesPlaceholder: searchAttributesPlaceholderProp, importExportLabel: importExportLabelProp, onImportCsv, onExportCsv, onExportExcel, importExportHelpHref, importCsvLabel: importCsvLabelProp, exportCsvLabel: exportCsvLabelProp, exportExcelLabel: exportExcelLabelProp, learnImportExportLabel: learnImportExportLabelProp, backLabel: backLabelProp, nestedFieldPlaceholder, ...rest }) {
|
|
372
399
|
// crisp/#471: an explicit prop always wins; missing, it reads the nearest
|
|
373
400
|
// CrispMessagesProvider's translation of the English default below, or
|
|
374
401
|
// that default itself with no provider — unchanged from before this
|
|
@@ -401,12 +428,12 @@ function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: fi
|
|
|
401
428
|
const exportExcelLabel = (0, core_1.useCrispMessage)(exportExcelLabelProp, "Export view as Excel");
|
|
402
429
|
const learnImportExportLabel = (0, core_1.useCrispMessage)(learnImportExportLabelProp, "Learn about imports and exports");
|
|
403
430
|
const backLabel = (0, core_1.useCrispMessage)(backLabelProp, "Back");
|
|
404
|
-
// OP_LABELS' own words ("contains", "is", "is any of", …) have no prop of
|
|
405
|
-
// their own — a whole lookup table, not one string — so they translate
|
|
406
|
-
// straight from the provider's dictionary at the two spots they render
|
|
407
|
-
// (#628, #673 below), same fallback order as every resolved constant
|
|
408
|
-
// above.
|
|
409
431
|
const crispMessages = (0, core_1.useCrispMessages)();
|
|
432
|
+
// crisp/#962: `operatorLabels` prop + `componentDefaults.tableToolbar`,
|
|
433
|
+
// layered over the old whole-dictionary lookup — see
|
|
434
|
+
// `useToolbarOperatorLabels`'s own doc comment for the full resolution
|
|
435
|
+
// order.
|
|
436
|
+
const opLabels = useToolbarOperatorLabels(operatorLabels, crispMessages);
|
|
410
437
|
// Each side falls back to the shared `columns` independently — a caller
|
|
411
438
|
// that only overrides one (Filter's own Record/Created by, say) still
|
|
412
439
|
// gets `columns` on the other, unchanged from before either prop existed.
|
|
@@ -842,9 +869,7 @@ function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: fi
|
|
|
842
869
|
return ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-toolgroup", children: [(0, jsx_runtime_1.jsxs)("span", { className: "crisp-tabletoolbar-fcond", "data-complete": complete ? "" : undefined, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--field", "data-menu-trigger": true, "aria-haspopup": "dialog", "aria-expanded": fieldOpen, onClick: () => {
|
|
843
870
|
setFieldPickerPath([]);
|
|
844
871
|
setOpenMenu(fieldOpen ? null : `ffield:${cond.id}`);
|
|
845
|
-
}, children: [col?.icon ? (0, jsx_runtime_1.jsx)(col.icon, { size: 14, strokeWidth: 1.75 }) : null, colPath.length > 1 ? ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fcond-path", children: colPath.map((c, i) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [i > 0 && ((0, jsx_runtime_1.jsx)(RtlChevronRight, { size: 14, className: "crisp-tabletoolbar-fcond-path-sep" })), (0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fcond-path-seg", children: c.label })] }, c.key))) })) : (col?.label)] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--op", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": opOpen, onClick: () => setOpenMenu(opOpen ? null : `fop:${cond.id}`), children: cond.op
|
|
846
|
-
? (crispMessages[OP_LABELS[cond.op]] ?? OP_LABELS[cond.op])
|
|
847
|
-
: selectConditionLabel }), showValueSeg && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--val", "data-menu-trigger": true, "aria-haspopup": "dialog", "aria-expanded": valOpen, onClick: () => setOpenMenu(valOpen ? null : `fval:${cond.id}`), children: cond.op === "isanyof"
|
|
872
|
+
}, children: [col?.icon ? (0, jsx_runtime_1.jsx)(col.icon, { size: 14, strokeWidth: 1.75 }) : null, colPath.length > 1 ? ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fcond-path", children: colPath.map((c, i) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [i > 0 && ((0, jsx_runtime_1.jsx)(RtlChevronRight, { size: 14, className: "crisp-tabletoolbar-fcond-path-sep" })), (0, jsx_runtime_1.jsx)("span", { className: "crisp-tabletoolbar-fcond-path-seg", children: c.label })] }, c.key))) })) : (col?.label)] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--op", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": opOpen, onClick: () => setOpenMenu(opOpen ? null : `fop:${cond.id}`), children: cond.op ? opLabels[cond.op] : selectConditionLabel }), showValueSeg && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--val", "data-menu-trigger": true, "aria-haspopup": "dialog", "aria-expanded": valOpen, onClick: () => setOpenMenu(valOpen ? null : `fval:${cond.id}`), children: cond.op === "isanyof"
|
|
848
873
|
? cond.values?.length
|
|
849
874
|
? isAnyOfSummary(cond.values)
|
|
850
875
|
: filterValuePlaceholder
|
|
@@ -852,7 +877,7 @@ function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: fi
|
|
|
852
877
|
? col?.type === "date"
|
|
853
878
|
? formatFilterDate(cond.value)
|
|
854
879
|
: cond.value
|
|
855
|
-
: filterValuePlaceholder })), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--kebab", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && ((0, jsx_runtime_1.jsx)("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: (0, jsx_runtime_1.jsxs)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item crisp-tabletoolbar-menu-item--danger", onClick: () => removeFilter(cond.id), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 16, strokeWidth: 1.75 }), deleteFilterLabel] }) })), fieldOpen && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabletoolbar-menu", role: "dialog", "aria-label": filterFieldLabel, children: nestedFieldPicker(filterColumns, (key) => changeFilterField(cond.id, key), filterFieldPlaceholder, filterFieldLabel) })), opOpen && ((0, jsx_runtime_1.jsx)("div", { ref: opMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--op", role: "menu", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, onKeyDown: onOpKeyDown, children: opsFor(col).map((op) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => pickOp(cond.id, op), children: [
|
|
880
|
+
: filterValuePlaceholder })), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-tabletoolbar-fcond-seg crisp-tabletoolbar-fcond-seg--kebab", "data-menu-trigger": true, "aria-haspopup": "menu", "aria-expanded": kebabOpen, "aria-label": `${col?.label} ${filterOptionsLabel}`, onClick: () => setOpenMenu(kebabOpen ? null : `fkebab:${cond.id}`), children: (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 13, strokeWidth: 2 }) })] }), kebabOpen && ((0, jsx_runtime_1.jsx)("div", { ref: kebabMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--right crisp-tabletoolbar-menu--hdr", role: "menu", "aria-label": `${col?.label} ${filterOptionsLabel}`, onKeyDown: onKebabKeyDown, children: (0, jsx_runtime_1.jsxs)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item crisp-tabletoolbar-menu-item--danger", onClick: () => removeFilter(cond.id), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 16, strokeWidth: 1.75 }), deleteFilterLabel] }) })), fieldOpen && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabletoolbar-menu", role: "dialog", "aria-label": filterFieldLabel, children: nestedFieldPicker(filterColumns, (key) => changeFilterField(cond.id, key), filterFieldPlaceholder, filterFieldLabel) })), opOpen && ((0, jsx_runtime_1.jsx)("div", { ref: opMenuRef, className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--op", role: "menu", "aria-label": `${col?.label} ${crispMessages.condition ?? "condition"}`, onKeyDown: onOpKeyDown, children: opsFor(col).map((op) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "menuitem", className: "crisp-tabletoolbar-menu-item", "data-on": cond.op === op ? "" : undefined, onClick: () => pickOp(cond.id, op), children: [opLabels[op], cond.op === op ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "crisp-tabletoolbar-menu-check", size: 15, strokeWidth: 1.75 })) : null] }, op))) })), valOpen && showValueSeg && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabletoolbar-menu crisp-tabletoolbar-menu--val", role: "dialog", "aria-label": `${col?.label} filter value`, children: cond.op === "isanyof" && col?.values ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { className: "crisp-tabletoolbar-menu-input", placeholder: filterValuePlaceholder, "aria-label": `${col?.label} filter values`,
|
|
856
881
|
// biome-ignore lint/a11y/noAutofocus: focus the search field
|
|
857
882
|
autoFocus: true, value: anyOfQuery, onChange: (e) => setAnyOfQuery(e.target.value) }), col.values
|
|
858
883
|
.filter((v) => v
|
|
@@ -46,7 +46,7 @@ const tabs_keyboard_1 = require("./tabs-keyboard");
|
|
|
46
46
|
* Home/End jump); activation follows focus. Controlled via
|
|
47
47
|
* `value`/`onValueChange`, or uncontrolled from `defaultValue`.
|
|
48
48
|
*/
|
|
49
|
-
function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, moreLabel = (n) => `+${n} more`, moreMenuLabel = "More tabs", className, fill, "aria-label": ariaLabel, ...rest }) {
|
|
49
|
+
function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, moreLabel = (n) => `+${n} more`, moreMenuLabel = "More tabs", overflow = "collapse", className, fill, "aria-label": ariaLabel, ...rest }) {
|
|
50
50
|
// Scoped to this instance: `tab-${value}` and `panel-${value}` are global,
|
|
51
51
|
// so two tab bars sharing a value mint the same id twice and every
|
|
52
52
|
// aria-labelledby resolves to the first one (#227).
|
|
@@ -93,6 +93,12 @@ function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, mor
|
|
|
93
93
|
const [hiddenFrom, setHiddenFrom] = React.useState(null);
|
|
94
94
|
const moreRef = React.useRef(null);
|
|
95
95
|
React.useLayoutEffect(() => {
|
|
96
|
+
// crisp#908: "scroll" never collapses anything -- the row scrolls
|
|
97
|
+
// instead, so there is nothing to measure or hide.
|
|
98
|
+
if (overflow !== "collapse") {
|
|
99
|
+
setHiddenFrom(null);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
96
102
|
const list = listRef.current;
|
|
97
103
|
if (!list || tabs.length === 0)
|
|
98
104
|
return;
|
|
@@ -133,7 +139,7 @@ function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, mor
|
|
|
133
139
|
const ro = new ResizeObserver(recompute);
|
|
134
140
|
ro.observe(list);
|
|
135
141
|
return () => ro.disconnect();
|
|
136
|
-
}, [tabs, active]);
|
|
142
|
+
}, [tabs, active, overflow]);
|
|
137
143
|
const hiddenTabs = hiddenFrom == null ? [] : tabs.slice(hiddenFrom);
|
|
138
144
|
const { onKeyDown, tabIndexFor } = (0, tabs_keyboard_1.useTablistKeyboard)({
|
|
139
145
|
tabs,
|
|
@@ -141,11 +147,11 @@ function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, mor
|
|
|
141
147
|
select,
|
|
142
148
|
listRef,
|
|
143
149
|
});
|
|
144
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tabs_recipe_1.tabsRecipe)({ fill, className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { ref: listRef, className: "crisp-tabs-list", role: "tablist", "aria-label": ariaLabel, onKeyDown: onKeyDown, children: [leading && (0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-leading", children: leading }), tabs.map((t, i) => {
|
|
150
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, tabs_recipe_1.tabsRecipe)({ fill, className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { ref: listRef, className: "crisp-tabs-list", "data-overflow": overflow, role: "tablist", "aria-label": ariaLabel, onKeyDown: onKeyDown, children: [leading && (0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-leading", children: leading }), tabs.map((t, i) => {
|
|
145
151
|
const selected = t.value === active;
|
|
146
152
|
const overflowHidden = hiddenFrom != null && i >= hiddenFrom;
|
|
147
153
|
return ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", id: tabId(t.value), "aria-selected": selected, "aria-controls": children && selected ? panelId(t.value) : undefined, tabIndex: overflowHidden ? -1 : tabIndexFor(t.value), "data-value": t.value, "data-selected": selected ? "" : undefined, "data-tabs-overflow-hidden": overflowHidden ? "" : undefined, disabled: t.disabled, className: "crisp-tabs-tab", onClick: () => select(t.value), children: [t.icon, (0, jsx_runtime_1.jsx)("span", { className: "tabs-tab-label", children: t.label }), t.badge != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-tab-badge", children: t.badge }))] }, t.value));
|
|
148
|
-
}), (0, jsx_runtime_1.jsx)("span", { ref: moreRef, className: "crisp-tabs-more", "data-tabs-overflow-hidden": hiddenTabs.length === 0 ? "" : undefined, children: (0, jsx_runtime_1.jsx)(menu_1.Menu, { "aria-label": moreMenuLabel, trigger: (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabs-tab", children: [(0, jsx_runtime_1.jsx)("span", { className: "tabs-tab-label", children: moreLabel(hiddenTabs.length) }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })] }), children: hiddenTabs.map((t) => ((0, jsx_runtime_1.jsxs)(menu_1.MenuItem, { icon: t.icon, onSelect: () => select(t.value), children: [t.label, t.badge != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-tab-badge", children: t.badge }))] }, t.value))) }) }), indicator && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-indicator", style: {
|
|
154
|
+
}), overflow === "collapse" && ((0, jsx_runtime_1.jsx)("span", { ref: moreRef, className: "crisp-tabs-more", "data-tabs-overflow-hidden": hiddenTabs.length === 0 ? "" : undefined, children: (0, jsx_runtime_1.jsx)(menu_1.Menu, { "aria-label": moreMenuLabel, trigger: (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-tabs-tab", children: [(0, jsx_runtime_1.jsx)("span", { className: "tabs-tab-label", children: moreLabel(hiddenTabs.length) }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })] }), children: hiddenTabs.map((t) => ((0, jsx_runtime_1.jsxs)(menu_1.MenuItem, { icon: t.icon, onSelect: () => select(t.value), children: [t.label, t.badge != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-tab-badge", children: t.badge }))] }, t.value))) }) })), indicator && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-tabs-indicator", style: {
|
|
149
155
|
width: indicator.width,
|
|
150
156
|
transform: `translateX(${indicator.left}px)`,
|
|
151
157
|
} }))] }), children && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-tabs-panel", role: "tabpanel", id: panelId(active), "aria-labelledby": tabId(active),
|
|
@@ -8,10 +8,20 @@ const tokens_1 = require("../../tokens");
|
|
|
8
8
|
// baseline needs, reserved as bottom padding so it's real box height and not
|
|
9
9
|
// paint that trailing content can sit on top of. The bar carries 12px inline
|
|
10
10
|
// padding too, and draws its own full-width `::after` baseline in
|
|
11
|
-
// borderSubtle at its bottom edge, spanning that padding.
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
11
|
+
// borderSubtle at its bottom edge, spanning that padding.
|
|
12
|
+
//
|
|
13
|
+
// your-moon/crisp#934: the selected tab used to be a light
|
|
14
|
+
// filled pill (bg #fbfbfb + inset ring borderSubtle, r8) with a 1px ink
|
|
15
|
+
// underline on top of it. Owner-directed: underline tabs, no fill pill --
|
|
16
|
+
// seed-design's own `tab.yaml` has no `root.color` property at all, at any
|
|
17
|
+
// state (selected/hover/pressed); selection is carried purely by the label
|
|
18
|
+
// darkening (muted -> ink, unchanged, already matched seed) plus the
|
|
19
|
+
// existing underline (already `fgPrimary`, "same colour as selected text,
|
|
20
|
+
// not brand" -- also already matched seed). Only the selected pill's own
|
|
21
|
+
// fill/ring is removed here; unselected tabs keep their existing subtle
|
|
22
|
+
// hover tint (a desktop hover affordance seed's spec doesn't need to
|
|
23
|
+
// consider one way or the other, and the owner didn't ask to remove).
|
|
24
|
+
// Inactive tabs are muted and fill to a subtle pill on hover. Each tab carries
|
|
15
25
|
// a 16px leading icon and an optional count badge. Measured from the live
|
|
16
26
|
// app: bar `padding: 0 12px 8px`, 28px pills, 4/8 padding, 6px icon-label
|
|
17
27
|
// gap, 14/500 labels. The count badge (crisp#697, re-measured against a
|
|
@@ -48,11 +58,18 @@ const config = (0, core_1.defineRecipe)({
|
|
|
48
58
|
|
|
49
59
|
& .crisp-tabs-list { position: relative; display: flex; align-items: center; gap: ${tokens_1.contract.space["1"]}; box-sizing: content-box; height: ${tokens_1.contract.size.row}; padding: 0 ${tokens_1.contract.space["3"]} ${tokens_1.contract.space["2"]}; flex-shrink: 0; }
|
|
50
60
|
& .crisp-tabs-list::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: ${tokens_1.contract.borderSubtle}; }
|
|
61
|
+
/* crisp#908: an alternative to the "+N more" collapse above (crisp#863) --
|
|
62
|
+
a consumer opts into a single scrolling row instead (Naver/Kakao's own
|
|
63
|
+
pattern, docs/study/korean/), never both at once. No new visual value:
|
|
64
|
+
reuses the same list gap/tab geometry, only adds overflow-x + snap. */
|
|
65
|
+
& .crisp-tabs-list[data-overflow="scroll"] { overflow-x: auto; flex-wrap: nowrap; scroll-snap-type: x mandatory; scrollbar-width: none; }
|
|
66
|
+
& .crisp-tabs-list[data-overflow="scroll"]::-webkit-scrollbar { display: none; }
|
|
67
|
+
& .crisp-tabs-list[data-overflow="scroll"] .crisp-tabs-tab { flex-shrink: 0; scroll-snap-align: start; }
|
|
51
68
|
& .crisp-tabs-leading { display: inline-flex; align-items: center; margin-inline-end: ${tokens_1.contract.space["1"]}; }
|
|
52
|
-
& .crisp-tabs-tab { position: relative; display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: 28px; margin: 0; padding: 0 ${tokens_1.contract.space["2"]}; border: none; background: none;
|
|
69
|
+
& .crisp-tabs-tab { position: relative; display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: 28px; margin: 0; padding: 0 ${tokens_1.contract.space["2"]}; border: none; background: none; border-radius: ${tokens_1.contract.radius.md}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; letter-spacing: -0.14px; color: ${tokens_1.contract.fgMuted}; cursor: pointer; white-space: nowrap; transition: color .12s ease, background-color .12s ease; }
|
|
53
70
|
& .crisp-tabs-tab svg { flex-shrink: 0; opacity: 0.85; }
|
|
54
71
|
& .crisp-tabs-tab:hover:not([data-selected]) { background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 4%, transparent); color: ${tokens_1.contract.fgPrimary}; }
|
|
55
|
-
& .crisp-tabs-tab[data-selected] { color: ${tokens_1.contract.fgPrimary};
|
|
72
|
+
& .crisp-tabs-tab[data-selected] { color: ${tokens_1.contract.fgPrimary}; }
|
|
56
73
|
& .crisp-tabs-tab:focus-visible { outline: 2px solid ${tokens_1.contract.bgBrandSolid}; outline-offset: 1px; }
|
|
57
74
|
& .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; height: 14px; padding: 0 ${tokens_1.contract.space["1"]}; border-radius: 4px; background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 4%, transparent); box-shadow: inset 0 0 0 1px ${tokens_1.contract.borderSubtle}; font-size: 10px; line-height: 14px; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgNeutralSoft}; }
|
|
58
75
|
& .crisp-tabs-tab[data-selected] .crisp-tabs-tab-badge { color: ${tokens_1.contract.fgPrimary}; }
|
|
@@ -3,14 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.textareaRecipe = void 0;
|
|
4
4
|
const core_1 = require("../../core");
|
|
5
5
|
const tokens_1 = require("../../tokens");
|
|
6
|
-
// A multiline text field:
|
|
6
|
+
// A multiline text field: a real 1px border (radius 8), 14px text, and an
|
|
7
7
|
// optional character counter pinned bottom-right (12px, muted). Focus rings
|
|
8
8
|
// the field brand.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
10
|
+
// your-moon/crisp#920: the rest-state edge used to be `elevation.textField`,
|
|
11
|
+
// a `box-shadow` ring (#466's fix for a real typed field's 1px ring, not
|
|
12
|
+
// `field`'s button-chrome glow/drop-shadow layers) -- now a real `border`,
|
|
13
|
+
// matching Input's own #914/#910 technique and seed-design's `text-input.yaml`
|
|
14
|
+
// (an actual border that THICKENS on focus/invalid via the ::after overlay
|
|
15
|
+
// below, not a fixed-width ring that only recolors). `borderDefault` is
|
|
16
|
+
// seed's own `stroke.neutral-weak`, already the crisp token's exact value.
|
|
14
17
|
//
|
|
15
18
|
// The inset is seed-design's, not Attio's -- the second deliberate divergence
|
|
16
19
|
// after the focus treatment. seed's text-input sets its inline inset to
|
|
@@ -27,10 +30,10 @@ const config = (0, core_1.defineRecipe)({
|
|
|
27
30
|
|
|
28
31
|
& .crisp-textarea-field {
|
|
29
32
|
box-sizing: border-box; display: block; width: 100%; min-height: 80px; resize: vertical;
|
|
30
|
-
margin: 0; padding: ${tokens_1.contract.space["2.5"]} 14px; border
|
|
31
|
-
background: ${tokens_1.contract.bgSurface};
|
|
33
|
+
margin: 0; padding: ${tokens_1.contract.space["2.5"]} 14px; border-radius: ${tokens_1.contract.radius.md};
|
|
34
|
+
background: ${tokens_1.contract.bgSurface}; border: 1px solid ${tokens_1.contract.borderDefault};
|
|
32
35
|
font-family: inherit; font-size: ${tokens_1.contract.text.lg}; line-height: 20px; color: ${tokens_1.contract.fgPrimary};
|
|
33
|
-
outline: none;
|
|
36
|
+
outline: none;
|
|
34
37
|
-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
35
38
|
}
|
|
36
39
|
& .crisp-textarea-field::placeholder { color: ${tokens_1.contract.fgMuted}; }
|
|
@@ -52,10 +52,11 @@ const react_dom_1 = require("react-dom");
|
|
|
52
52
|
* `Dialog` was rendering offset by the dialog's own box instead of anchored
|
|
53
53
|
* to its trigger.
|
|
54
54
|
*
|
|
55
|
-
* Every caller renders this conditionally on its own `open` state
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
55
|
+
* Every caller renders this conditionally on its own `open` state. A fixture
|
|
56
|
+
* CAN set that true at mount (crisp#964 needs exactly that, to give Menu's
|
|
57
|
+
* roving-tabindex guard something to inspect), so this checks for `window`
|
|
58
|
+
* itself rather than assuming the caller never does — the same guard
|
|
59
|
+
* `@zag-js/react`'s own `Portal` uses for the identical reason.
|
|
59
60
|
*
|
|
60
61
|
* `sourceRef` is the caller's own root — still in its original DOM position,
|
|
61
62
|
* never portaled — used to carry a `data-theme` set on some ancestor of it
|
|
@@ -71,6 +72,8 @@ const react_dom_1 = require("react-dom");
|
|
|
71
72
|
* element carrying that attribute.
|
|
72
73
|
*/
|
|
73
74
|
function FloatingPortal({ children, sourceRef, }) {
|
|
75
|
+
if (typeof window === "undefined")
|
|
76
|
+
return children;
|
|
74
77
|
const theme = sourceRef.current
|
|
75
78
|
?.closest("[data-theme]")
|
|
76
79
|
?.getAttribute("data-theme");
|
package/dist/cjs/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __exportStar(require("./components/avatar"), exports);
|
|
|
24
24
|
__exportStar(require("./components/avatargroup"), exports);
|
|
25
25
|
__exportStar(require("./components/badge"), exports);
|
|
26
26
|
__exportStar(require("./components/barchart"), exports);
|
|
27
|
+
__exportStar(require("./components/bottomsheet"), exports);
|
|
27
28
|
__exportStar(require("./components/breadcrumb"), exports);
|
|
28
29
|
__exportStar(require("./components/bulkbar"), exports);
|
|
29
30
|
__exportStar(require("./components/button"), exports);
|
|
@@ -31,6 +32,7 @@ __exportStar(require("./components/callout"), exports);
|
|
|
31
32
|
__exportStar(require("./components/card"), exports);
|
|
32
33
|
__exportStar(require("./components/checkbox"), exports);
|
|
33
34
|
__exportStar(require("./components/chip"), exports);
|
|
35
|
+
__exportStar(require("./components/chipgroup"), exports);
|
|
34
36
|
__exportStar(require("./components/columncalc"), exports);
|
|
35
37
|
__exportStar(require("./components/composewindow"), exports);
|
|
36
38
|
__exportStar(require("./components/contextmenu"), exports);
|
|
@@ -52,6 +54,7 @@ __exportStar(require("./components/kbd"), exports);
|
|
|
52
54
|
__exportStar(require("./components/linechart"), exports);
|
|
53
55
|
__exportStar(require("./components/mentionchip"), exports);
|
|
54
56
|
__exportStar(require("./components/menu"), exports);
|
|
57
|
+
__exportStar(require("./components/menusheet"), exports);
|
|
55
58
|
__exportStar(require("./components/middletruncate"), exports);
|
|
56
59
|
__exportStar(require("./components/multiselect"), exports);
|
|
57
60
|
__exportStar(require("./components/personchip"), exports);
|
|
@@ -65,6 +68,7 @@ __exportStar(require("./components/select"), exports);
|
|
|
65
68
|
__exportStar(require("./components/skeleton"), exports);
|
|
66
69
|
__exportStar(require("./components/skiplink"), exports);
|
|
67
70
|
__exportStar(require("./components/slider"), exports);
|
|
71
|
+
__exportStar(require("./components/snackbar"), exports);
|
|
68
72
|
__exportStar(require("./components/spinner"), exports);
|
|
69
73
|
__exportStar(require("./components/stagebar"), exports);
|
|
70
74
|
__exportStar(require("./components/statcard"), exports);
|
|
@@ -99,7 +103,9 @@ __exportStar(require("./product/headerbar"), exports);
|
|
|
99
103
|
__exportStar(require("./product/importdialog"), exports);
|
|
100
104
|
__exportStar(require("./product/inbox"), exports);
|
|
101
105
|
__exportStar(require("./product/listpage"), exports);
|
|
106
|
+
__exportStar(require("./product/memberssettings"), exports);
|
|
102
107
|
__exportStar(require("./product/navitem"), exports);
|
|
108
|
+
__exportStar(require("./product/notificationssettings"), exports);
|
|
103
109
|
__exportStar(require("./product/objectsettings"), exports);
|
|
104
110
|
__exportStar(require("./product/onboarding"), exports);
|
|
105
111
|
__exportStar(require("./product/recordpage"), exports);
|
|
@@ -114,5 +120,6 @@ __exportStar(require("./product/tasklist"), exports);
|
|
|
114
120
|
__exportStar(require("./product/themepicker"), exports);
|
|
115
121
|
__exportStar(require("./product/trialbanner"), exports);
|
|
116
122
|
__exportStar(require("./product/viewtoggle"), exports);
|
|
123
|
+
__exportStar(require("./product/workspacegeneralsettings"), exports);
|
|
117
124
|
// design tokens + recipe core (for building custom components)
|
|
118
125
|
__exportStar(require("./tokens"), exports);
|
|
@@ -43,7 +43,11 @@ const config = (0, core_1.defineRecipe)({
|
|
|
43
43
|
& .crisp-authshell-progress-fill { height: 2px; background: ${tokens_1.contract.fgPrimary}; border-radius: 4px; transition: width .2s; }
|
|
44
44
|
|
|
45
45
|
& .crisp-authshell-logo { margin-top: ${tokens_1.contract.space["8"]}; min-height: 24px; display: flex; align-items: center; gap: ${tokens_1.contract.space["2.5"]}; }
|
|
46
|
-
|
|
46
|
+
/* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
|
|
47
|
+
the accent (#0298d9) only clears 3.23:1 with white; the darker
|
|
48
|
+
sibling clears 4.5:1+, same fix already applied to Button/Badge/
|
|
49
|
+
Avatar (#897). */
|
|
50
|
+
& .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: ${tokens_1.contract.radius.md}; background: ${tokens_1.contract.bgBrandContrast}; color: #fff; display: flex; align-items: center; justify-content: center; }
|
|
47
51
|
& .crisp-authshell-logo-text { display: flex; flex-direction: column; line-height: 1.2; }
|
|
48
52
|
& .crisp-authshell-logo-title { font-size: ${tokens_1.contract.text.xl}; font-weight: ${tokens_1.contract.weight.bold}; letter-spacing: -0.2px; color: ${tokens_1.contract.fgPrimary}; }
|
|
49
53
|
& .crisp-authshell-logo-subtitle { font-size: ${tokens_1.contract.text.sm}; color: ${tokens_1.contract.fgMuted}; }
|
|
@@ -32,7 +32,10 @@ const config = (0, core_1.defineRecipe)({
|
|
|
32
32
|
& .crisp-command-list > .crisp-command-group-label:first-child { padding-top: ${tokens_1.contract.space["1"]}; }
|
|
33
33
|
& .crisp-command-footer { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 44px; padding: 0 ${tokens_1.contract.space["2.5"]}; border-top: 1px solid ${tokens_1.contract.borderSubtle}; }
|
|
34
34
|
& .crisp-command-footer-nav { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; font-size: ${tokens_1.contract.text.sm}; color: ${tokens_1.contract.fgMuted}; }
|
|
35
|
-
|
|
35
|
+
/* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
|
|
36
|
+
the accent (#0298d9) only clears 3.23:1 with white; the darker sibling
|
|
37
|
+
clears 4.5:1+, same fix already applied to Button/Badge/Avatar (#897). */
|
|
38
|
+
& .crisp-command-footer-action { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; height: 28px; max-width: 60%; padding: 0 ${tokens_1.contract.space["1"]} 0 ${tokens_1.contract.space["2.5"]}; border: none; border-radius: ${tokens_1.contract.radius.md}; background: ${tokens_1.contract.bgBrandContrast}; color: ${tokens_1.contract.fgOnBrand}; font-family: inherit; font-size: ${tokens_1.contract.text.md}; font-weight: ${tokens_1.contract.weight.medium}; cursor: pointer; }
|
|
36
39
|
& .crisp-command-footer-action:disabled { opacity: 0.5; cursor: default; }
|
|
37
40
|
& .crisp-command-footer-action-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
38
41
|
& .crisp-command-footer-key { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius.sm}; background: rgba(255,255,255,0.22); font-size: ${tokens_1.contract.text.xs}; }
|
|
@@ -315,8 +315,13 @@ function CommentRow({ comment, replyLabel, reactLabel, resolveLabel, moreLabel,
|
|
|
315
315
|
* nothing on its own beyond that data. See `CommentCountBadge` for the
|
|
316
316
|
* separate row affordance (P-051) — deliberately NOT part of this
|
|
317
317
|
* component, since it lives in a table cell this component doesn't own.
|
|
318
|
+
*
|
|
319
|
+
* `variant="drawer"` (default) is today's measured 320px + left-border
|
|
320
|
+
* look; `variant="pane"` (crisp#960) fills its container's width instead,
|
|
321
|
+
* for a consumer embedding this in a full-width tab pane rather than a
|
|
322
|
+
* true slide-over/drawer.
|
|
318
323
|
*/
|
|
319
|
-
function CommentsPanel({ threads, currentUserId, subject, subjectIcon, showResolved = false, onShowResolvedChange, onlyMine = false, onOnlyMineChange, activeThreadId: activeThreadIdProp, onActiveThreadChange, onPost, onReact, onResolve, onDelete, onCopyLink, emojiOptions = DEFAULT_EMOJI, mentionTrigger = "@", renderMentionPicker, onClose, closeLabel: closeLabelProp, backLabel: backLabelProp, title: titleProp, threadTitle: threadTitleProp, breadcrumbPrefix: breadcrumbPrefixProp, composerPlaceholder: composerPlaceholderProp, replyPlaceholder: replyPlaceholderProp, postLabel: postLabelProp, replyPostLabel: replyPostLabelProp, emptyLabel, filterLabel: filterLabelProp, showResolvedLabel: showResolvedLabelProp, onlyMineLabel: onlyMineLabelProp, replyActionLabel: replyActionLabelProp, reactActionLabel: reactActionLabelProp, resolveActionLabel: resolveActionLabelProp, resolvedByYouLabel: resolvedByYouLabelProp, resolvedByLabel, moreActionsLabel: moreActionsLabelProp, copyLinkLabel: copyLinkLabelProp, deleteLabel: deleteLabelProp, addReactionLabel: addReactionLabelProp, reactionSearchLabel: reactionSearchLabelProp, deleteConfirmTitle: deleteConfirmTitleProp, deleteConfirmBody: deleteConfirmBodyProp, deleteConfirmActionLabel: deleteConfirmActionLabelProp, cancelLabel: cancelLabelProp, composerMentionToolLabel: composerMentionToolLabelProp, className, ...rest }) {
|
|
324
|
+
function CommentsPanel({ threads, currentUserId, subject, subjectIcon, showResolved = false, onShowResolvedChange, onlyMine = false, onOnlyMineChange, activeThreadId: activeThreadIdProp, onActiveThreadChange, onPost, onReact, onResolve, onDelete, onCopyLink, emojiOptions = DEFAULT_EMOJI, mentionTrigger = "@", renderMentionPicker, onClose, closeLabel: closeLabelProp, backLabel: backLabelProp, title: titleProp, threadTitle: threadTitleProp, breadcrumbPrefix: breadcrumbPrefixProp, composerPlaceholder: composerPlaceholderProp, replyPlaceholder: replyPlaceholderProp, postLabel: postLabelProp, replyPostLabel: replyPostLabelProp, emptyLabel, filterLabel: filterLabelProp, showResolvedLabel: showResolvedLabelProp, onlyMineLabel: onlyMineLabelProp, replyActionLabel: replyActionLabelProp, reactActionLabel: reactActionLabelProp, resolveActionLabel: resolveActionLabelProp, resolvedByYouLabel: resolvedByYouLabelProp, resolvedByLabel, moreActionsLabel: moreActionsLabelProp, copyLinkLabel: copyLinkLabelProp, deleteLabel: deleteLabelProp, addReactionLabel: addReactionLabelProp, reactionSearchLabel: reactionSearchLabelProp, deleteConfirmTitle: deleteConfirmTitleProp, deleteConfirmBody: deleteConfirmBodyProp, deleteConfirmActionLabel: deleteConfirmActionLabelProp, cancelLabel: cancelLabelProp, composerMentionToolLabel: composerMentionToolLabelProp, variant, className, ...rest }) {
|
|
320
325
|
const closeLabel = (0, core_1.useCrispMessage)(closeLabelProp, "Close");
|
|
321
326
|
const backLabel = (0, core_1.useCrispMessage)(backLabelProp, "Back");
|
|
322
327
|
const title = (0, core_1.useCrispMessage)(titleProp, "All comments");
|
|
@@ -369,7 +374,7 @@ function CommentsPanel({ threads, currentUserId, subject, subjectIcon, showResol
|
|
|
369
374
|
const activeThread = activeThreadId
|
|
370
375
|
? threads.find((t) => t.id === activeThreadId)
|
|
371
376
|
: null;
|
|
372
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, comments_recipe_1.commentsRecipe)({ className }), role: "dialog", "aria-label": title, ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-comments-head", children: [activeThread ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": backLabel, onClick: () => setActiveThreadId(null), children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { "data-rtl-flip": "", size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "crisp-comments-title-wrap", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-comments-title", children: activeThread ? threadTitle : title }), activeThread && ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-comments-breadcrumb", children: [breadcrumbPrefix, " ", subjectIcon, " ", subject] }))] }), !activeThread && ((0, jsx_runtime_1.jsxs)(menu_1.Menu, { align: "end", trigger: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": filterLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }), children: [(0, jsx_runtime_1.jsx)(menu_1.MenuCheckboxItem, { checked: showResolved, onCheckedChange: onShowResolvedChange, children: showResolvedLabel }), (0, jsx_runtime_1.jsx)(menu_1.MenuCheckboxItem, { checked: onlyMine, onCheckedChange: onOnlyMineChange, children: onlyMineLabel })] })), onClose && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": closeLabel, onClick: onClose, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-comments-body crisp-comments-body--pad-top", children: activeThread ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(CommentRow, { comment: activeThread.root, currentUserId: currentUserId, replyLabel: replyActionLabel, reactLabel: reactActionLabel, resolveLabel: resolveActionLabel, moreLabel: moreActionsLabel, copyLinkLabel: copyLinkLabel, deleteLabel: deleteLabel, addReactionLabel: addReactionLabel, reactionSearchLabel: reactionSearchLabel, emojiOptions: emojiOptions, resolvable: !!onResolve, resolved: activeThread.resolved, resolvedLabel: activeThread.resolved
|
|
377
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, comments_recipe_1.commentsRecipe)({ variant, className }), role: "dialog", "aria-label": title, ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-comments-head", children: [activeThread ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": backLabel, onClick: () => setActiveThreadId(null), children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { "data-rtl-flip": "", size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "crisp-comments-title-wrap", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-comments-title", children: activeThread ? threadTitle : title }), activeThread && ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-comments-breadcrumb", children: [breadcrumbPrefix, " ", subjectIcon, " ", subject] }))] }), !activeThread && ((0, jsx_runtime_1.jsxs)(menu_1.Menu, { align: "end", trigger: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": filterLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }), children: [(0, jsx_runtime_1.jsx)(menu_1.MenuCheckboxItem, { checked: showResolved, onCheckedChange: onShowResolvedChange, children: showResolvedLabel }), (0, jsx_runtime_1.jsx)(menu_1.MenuCheckboxItem, { checked: onlyMine, onCheckedChange: onOnlyMineChange, children: onlyMineLabel })] })), onClose && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-comments-headbtn", "aria-label": closeLabel, onClick: onClose, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" }) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-comments-body crisp-comments-body--pad-top", children: activeThread ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(CommentRow, { comment: activeThread.root, currentUserId: currentUserId, replyLabel: replyActionLabel, reactLabel: reactActionLabel, resolveLabel: resolveActionLabel, moreLabel: moreActionsLabel, copyLinkLabel: copyLinkLabel, deleteLabel: deleteLabel, addReactionLabel: addReactionLabel, reactionSearchLabel: reactionSearchLabel, emojiOptions: emojiOptions, resolvable: !!onResolve, resolved: activeThread.resolved, resolvedLabel: activeThread.resolved
|
|
373
378
|
? activeThread.resolvedBy?.id === currentUserId ||
|
|
374
379
|
!activeThread.resolvedBy
|
|
375
380
|
? resolvedByYouLabel
|
|
@@ -18,8 +18,8 @@ const tokens_1 = require("../../tokens");
|
|
|
18
18
|
// width and still gets an odd number).
|
|
19
19
|
const config = (0, core_1.defineRecipe)({
|
|
20
20
|
name: "comments",
|
|
21
|
-
base: `display: flex; flex-direction: column; box-sizing: border-box;
|
|
22
|
-
background: ${tokens_1.contract.bgSurface};
|
|
21
|
+
base: `display: flex; flex-direction: column; box-sizing: border-box; height: 100%;
|
|
22
|
+
background: ${tokens_1.contract.bgSurface};
|
|
23
23
|
font-family: ${tokens_1.contract.font.sans};
|
|
24
24
|
-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
25
25
|
& * { box-sizing: border-box; }
|
|
@@ -99,9 +99,13 @@ const config = (0, core_1.defineRecipe)({
|
|
|
99
99
|
box-shadow, so this reuses that literal rather than re-deriving it.
|
|
100
100
|
32px/radius.lg/6px-10px padding has no matching Button \`size\` yet
|
|
101
101
|
(24/28/40 are the three that exist), so this stays hand-rolled instead
|
|
102
|
-
of stretching one of those.
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
of stretching one of those. your-moon/crisp#953:
|
|
103
|
+
bgBrandContrast, not bgBrandSolid -- the accent (#0298d9) only clears
|
|
104
|
+
3.23:1 with white; same fix already applied to Button/Badge/Avatar
|
|
105
|
+
(#897). Hover is a brightness filter on the new fill, matching that
|
|
106
|
+
PR's own Button primary treatment, not bgBrandSolidPressed. */
|
|
107
|
+
& .crisp-comments-post { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 6px ${tokens_1.contract.space["2.5"]}; border: none; border-radius: ${tokens_1.contract.radius.lg}; background: ${tokens_1.contract.bgBrandContrast}; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08); font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.semibold}; color: ${tokens_1.contract.fgOnBrand}; cursor: pointer; opacity: 1; transition: opacity .12s, filter .12s; }
|
|
108
|
+
& .crisp-comments-post:hover:not(:disabled) { filter: brightness(0.96); }
|
|
105
109
|
& .crisp-comments-post:disabled { opacity: .4; cursor: default; }
|
|
106
110
|
|
|
107
111
|
/* Filter menu -- measured: 220px, radius 12 (radius.xl), 4px padding,
|
|
@@ -113,8 +117,22 @@ const config = (0, core_1.defineRecipe)({
|
|
|
113
117
|
rather than re-derived since it's the same atomic-chip affordance. */
|
|
114
118
|
& .crisp-comments-mention { display: inline; padding: 0 2px; border-radius: 4px; background: color-mix(in srgb, ${tokens_1.contract.bgBrandSolid} 12%, transparent); color: ${tokens_1.contract.bgBrandSolid}; font-weight: ${tokens_1.contract.weight.medium}; user-select: none; }
|
|
115
119
|
${core_1.rtlFlipCss}`,
|
|
116
|
-
variants: {
|
|
117
|
-
|
|
120
|
+
variants: {
|
|
121
|
+
// your-moon/crisp#960: the 320px width + left-border hairline is a
|
|
122
|
+
// drawer-consumer look (RecordPage's own comments drawer, #864), not
|
|
123
|
+
// an intrinsic property of the panel itself. A consumer embedding this
|
|
124
|
+
// in a full-width tab pane (internal/grc's own record-page Comments
|
|
125
|
+
// tab, sibling to Related/Activity/Notes/Tasks/Lists, all of which
|
|
126
|
+
// fill the pane) needs `width: 100%` and no border -- a tab pane
|
|
127
|
+
// doesn't need a seam separating it from itself. `drawer` (default)
|
|
128
|
+
// is today's exact, already-measured look; nothing changes for an
|
|
129
|
+
// existing consumer that doesn't pass `variant`.
|
|
130
|
+
variant: {
|
|
131
|
+
drawer: `width: 320px; border-inline-start: 1px solid ${tokens_1.contract.borderSubtle};`,
|
|
132
|
+
pane: `width: 100%;`,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
defaultVariants: { variant: "drawer" },
|
|
118
136
|
compoundVariants: [],
|
|
119
137
|
// Two pieces below intentionally live OUTSIDE the nested \`base\` above,
|
|
120
138
|
// the same reason Menu's own \`.crisp-menu-content\` does (menu.recipe.ts's
|
|
@@ -54,10 +54,18 @@ function Inbox({ notifications = [], title: titleProp, tabs, activeTab, onTabCha
|
|
|
54
54
|
// own `empty`.
|
|
55
55
|
const crispMessages = (0, core_1.useCrispMessages)();
|
|
56
56
|
const title = titleProp ?? crispMessages.Notifications ?? "Notifications";
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// A tab's own empty copy wins over the instance-level prop, which wins
|
|
58
|
+
// over the built-in default — same precedence as `title`/`emptyAction`.
|
|
59
|
+
const activeTabDef = tabs?.find((t) => t.id === activeTab);
|
|
60
|
+
const emptyTitle = activeTabDef?.emptyTitle ??
|
|
61
|
+
emptyTitleProp ??
|
|
62
|
+
crispMessages["No notifications"] ??
|
|
63
|
+
"No notifications";
|
|
64
|
+
const emptySubtitle = activeTabDef?.emptySubtitle ??
|
|
65
|
+
emptySubtitleProp ??
|
|
59
66
|
crispMessages["Notifications such as mentions and important updates will be displayed here."] ??
|
|
60
67
|
"Notifications such as mentions and important updates will be displayed here.";
|
|
68
|
+
const resolvedEmptyAction = activeTabDef?.emptyAction ?? emptyAction;
|
|
61
69
|
const tabsLabel = (0, core_1.useCrispMessage)(tabsLabelProp, "Notification views");
|
|
62
70
|
// crisp's shared tablist model, the one `Tabs` runs (#195). Hand-rolling a
|
|
63
71
|
// second one is how Inbox ended up with no arrow keys, no roving tabindex
|
|
@@ -68,6 +76,6 @@ function Inbox({ notifications = [], title: titleProp, tabs, activeTab, onTabCha
|
|
|
68
76
|
select: (id) => onTabChange?.(id),
|
|
69
77
|
listRef,
|
|
70
78
|
});
|
|
71
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, inbox_recipe_1.inboxRecipe)({ className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-inbox-head", children: [(0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-title", children: title }), tabs && tabs.length > 0 && ((0, jsx_runtime_1.jsx)("div", { ref: listRef, className: "crisp-inbox-tabs", role: "tablist", "aria-label": tabsLabel, onKeyDown: onKeyDown, children: tabs.map((t) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", "aria-selected": t.id === activeTab, tabIndex: tabIndexFor(t.id), "data-value": t.id, disabled: t.disabled, className: "crisp-inbox-tab", "data-active": t.id === activeTab ? "" : undefined, onClick: () => onTabChange?.(t.id), children: [t.label, t.count != null && ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-inbox-tab-count", children: ["(", t.count, ")"] }))] }, t.id))) }))] }), notifications.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-inbox-empty", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-empty-icon", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Bell, { size: 40, strokeWidth: 1.25 }) }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-empty-title", children: emptyTitle }), emptySubtitle != null && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-empty-sub", children: emptySubtitle })),
|
|
79
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, inbox_recipe_1.inboxRecipe)({ className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-inbox-head", children: [(0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-title", children: title }), tabs && tabs.length > 0 && ((0, jsx_runtime_1.jsx)("div", { ref: listRef, className: "crisp-inbox-tabs", role: "tablist", "aria-label": tabsLabel, onKeyDown: onKeyDown, children: tabs.map((t) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", "aria-selected": t.id === activeTab, tabIndex: tabIndexFor(t.id), "data-value": t.id, disabled: t.disabled, className: "crisp-inbox-tab", "data-active": t.id === activeTab ? "" : undefined, onClick: () => onTabChange?.(t.id), children: [t.label, t.count != null && ((0, jsx_runtime_1.jsxs)("span", { className: "crisp-inbox-tab-count", children: ["(", t.count, ")"] }))] }, t.id))) }))] }), notifications.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-inbox-empty", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-empty-icon", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Bell, { size: 40, strokeWidth: 1.25 }) }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-empty-title", children: emptyTitle }), emptySubtitle != null && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-empty-sub", children: emptySubtitle })), resolvedEmptyAction != null && ((0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-empty-action", children: resolvedEmptyAction }))] })) : ((0, jsx_runtime_1.jsx)("div", { className: "crisp-inbox-list", children: notifications.map((n) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-inbox-row", onClick: n.onClick, children: [n.avatar != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-row-avatar", children: n.avatar })), (0, jsx_runtime_1.jsxs)("span", { className: "crisp-inbox-row-body", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-row-msg", children: n.message }), n.time != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-row-time", children: n.time }))] }), n.unread && (0, jsx_runtime_1.jsx)("span", { className: "crisp-inbox-row-unread" })] }, n.id))) }))] }));
|
|
72
80
|
}
|
|
73
81
|
Inbox.displayName = "Inbox";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MembersSettings = exports.InviteMembersDialog = void 0;
|
|
4
|
+
var memberssettings_1 = require("./memberssettings");
|
|
5
|
+
Object.defineProperty(exports, "InviteMembersDialog", { enumerable: true, get: function () { return memberssettings_1.InviteMembersDialog; } });
|
|
6
|
+
Object.defineProperty(exports, "MembersSettings", { enumerable: true, get: function () { return memberssettings_1.MembersSettings; } });
|