@crisp-ui-kit/crisp 0.57.1 → 0.57.2
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 +7 -6
- package/dist/button.layered.css +7 -6
- package/dist/checkbox.css +7 -3
- package/dist/checkbox.layered.css +7 -3
- package/dist/chip.css +15 -0
- package/dist/chip.d.ts +3 -1
- package/dist/chip.layered.css +15 -0
- 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/button/button.recipe.js +39 -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 +69 -1
- 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 +11 -2
- 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.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/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/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/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/recordpage.js +57 -6
- package/dist/cjs/product/recordpage/recordpage.recipe.js +43 -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 +161 -67
- package/dist/datatable.layered.css +161 -67
- package/dist/datepicker.css +13 -41
- package/dist/datepicker.layered.css +13 -41
- package/dist/datepickerfield.css +4 -1
- package/dist/datepickerfield.layered.css +4 -1
- 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/button/button.recipe.js +40 -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 +69 -1
- 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 +11 -2
- 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.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/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/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/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/recordpage.js +58 -7
- package/dist/esm/product/recordpage/recordpage.recipe.js +43 -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 +67 -23
- package/dist/recordpage.layered.css +67 -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 +859 -345
- package/dist/styles.layered.css +859 -345
- package/dist/table.css +28 -10
- package/dist/table.layered.css +28 -10
- 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/button/button.recipe.d.ts +11 -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 +48 -0
- 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/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/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/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/recordpage.d.ts +53 -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
|
@@ -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}; }
|
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
|
|
@@ -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; } });
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MembersSettings = MembersSettings;
|
|
37
|
+
exports.InviteMembersDialog = InviteMembersDialog;
|
|
38
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
39
|
+
const lucide_react_1 = require("lucide-react");
|
|
40
|
+
const React = __importStar(require("react"));
|
|
41
|
+
const avatar_1 = require("../../components/avatar");
|
|
42
|
+
const badge_1 = require("../../components/badge");
|
|
43
|
+
const button_1 = require("../../components/button");
|
|
44
|
+
const dialog_1 = require("../../components/dialog");
|
|
45
|
+
const formfield_1 = require("../../components/formfield");
|
|
46
|
+
const select_1 = require("../../components/select");
|
|
47
|
+
const tabs_keyboard_1 = require("../../components/tabs/tabs-keyboard");
|
|
48
|
+
const textarea_1 = require("../../components/textarea");
|
|
49
|
+
const textlink_1 = require("../../components/textlink");
|
|
50
|
+
const memberssettings_recipe_1 = require("./memberssettings.recipe");
|
|
51
|
+
/**
|
|
52
|
+
* Attio's "Members and teams" settings page (crisp#636, P-119/P-120):
|
|
53
|
+
* title + description, a Members/Teams segmented switcher, a
|
|
54
|
+
* search+Filter+Invite toolbar, and the members table (User/Role/Teams).
|
|
55
|
+
* Compose `InviteMembersDialog` alongside for the "Invite members" flow.
|
|
56
|
+
*/
|
|
57
|
+
function MembersSettings({ members, searchValue, onSearchChange, onFilterClick, onInviteClick, onRowMenuClick, tab: tabProp, onTabChange, teamsContent, className, title = "Members and teams", description = "Manage workspace members and teams, set access levels, and invite new users.", learnMoreLabel = "Learn more", learnMoreHref = "#", membersTabLabel = "Members", teamsTabLabel = "Teams", tablistLabel = "Members and teams", searchPlaceholder = "Search name or email", filterLabel = "Filter", inviteLabel = "Invite members", userColumnLabel = "User", roleColumnLabel = "Role", teamsColumnLabel = "Teams", memberActionsLabel = "Member actions", noTeamsLabel = "No teams yet", ...rest }) {
|
|
58
|
+
const [internalTab, setInternalTab] = React.useState("members");
|
|
59
|
+
const tab = tabProp ?? internalTab;
|
|
60
|
+
const setTab = (next) => {
|
|
61
|
+
if (tabProp === undefined)
|
|
62
|
+
setInternalTab(next);
|
|
63
|
+
onTabChange?.(next);
|
|
64
|
+
};
|
|
65
|
+
const listRef = React.useRef(null);
|
|
66
|
+
const tabEntries = [
|
|
67
|
+
{
|
|
68
|
+
value: "members",
|
|
69
|
+
label: membersTabLabel,
|
|
70
|
+
icon: (0, jsx_runtime_1.jsx)(lucide_react_1.User, { size: 16 }),
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
value: "teams",
|
|
74
|
+
label: teamsTabLabel,
|
|
75
|
+
icon: (0, jsx_runtime_1.jsx)(lucide_react_1.UsersRound, { size: 16 }),
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
const { onKeyDown, tabIndexFor } = (0, tabs_keyboard_1.useTablistKeyboard)({
|
|
79
|
+
tabs: tabEntries,
|
|
80
|
+
active: tab,
|
|
81
|
+
select: (value) => setTab(value),
|
|
82
|
+
listRef,
|
|
83
|
+
});
|
|
84
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, memberssettings_recipe_1.memberssettingsRecipe)({ className }), ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-page", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-heading", children: [(0, jsx_runtime_1.jsx)("h1", { className: "crisp-memberssettings-title", children: title }), (0, jsx_runtime_1.jsxs)("p", { className: "crisp-memberssettings-desc", children: [description, " ", (0, jsx_runtime_1.jsx)(textlink_1.TextLink, { href: learnMoreHref, children: learnMoreLabel })] })] }), (0, jsx_runtime_1.jsx)("div", { ref: listRef, className: "crisp-memberssettings-tabpair", role: "tablist", "aria-label": tablistLabel, onKeyDown: onKeyDown, children: tabEntries.map((t) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", role: "tab", "data-value": t.value, "aria-selected": tab === t.value, "data-selected": tab === t.value ? "" : undefined, tabIndex: tabIndexFor(t.value), className: "crisp-memberssettings-tab", onClick: () => setTab(t.value), children: [t.icon, t.label] }, t.value))) }), tab === "members" ? ((0, jsx_runtime_1.jsxs)("div", { role: "tabpanel", "aria-label": membersTabLabel, children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-toolbar", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-search", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 16 }), (0, jsx_runtime_1.jsx)("input", { value: searchValue, onChange: (e) => onSearchChange?.(e.target.value), placeholder: searchPlaceholder })] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "crisp-memberssettings-filterbtn", onClick: onFilterClick, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Filter, { size: 14 }), filterLabel] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-memberssettings-invitebtn", onClick: onInviteClick, children: inviteLabel })] }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-memberssettings-table-wrap", children: (0, jsx_runtime_1.jsxs)("table", { className: "crisp-memberssettings-table", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("th", { children: userColumnLabel }), (0, jsx_runtime_1.jsx)("th", { children: roleColumnLabel }), (0, jsx_runtime_1.jsx)("th", { children: teamsColumnLabel })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: members.map((m) => ((0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-user", children: [m.avatarSrc ? ((0, jsx_runtime_1.jsx)("img", { className: "crisp-memberssettings-avatarimg", src: m.avatarSrc, alt: "" })) : ((0, jsx_runtime_1.jsx)(avatar_1.Avatar, { size: "lg", shape: "circle", tone: "brand", children: String(m.name).charAt(0) })), (0, jsx_runtime_1.jsxs)("div", { className: "crisp-memberssettings-usermeta", children: [(0, jsx_runtime_1.jsxs)("span", { children: [m.name, m.isYou ? " (You)" : ""] }), (0, jsx_runtime_1.jsx)("span", { className: "crisp-memberssettings-useremail", children: m.email })] })] }) }), (0, jsx_runtime_1.jsx)("td", { children: m.role === "Admin" ? ((0, jsx_runtime_1.jsx)(badge_1.Badge, { tone: "purple", children: m.role })) : (m.role) }), (0, jsx_runtime_1.jsxs)("td", { children: [m.teams ?? "—", (0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-memberssettings-kebab", "aria-label": memberActionsLabel, onClick: () => onRowMenuClick?.(m), children: (0, jsx_runtime_1.jsx)(lucide_react_1.MoreHorizontal, { size: 16 }) })] })] }, m.id))) })] }) })] })) : ((0, jsx_runtime_1.jsx)("div", { role: "tabpanel", "aria-label": teamsTabLabel, children: teamsContent ?? ((0, jsx_runtime_1.jsx)("div", { className: "crisp-memberssettings-teamspanel", children: noTeamsLabel })) }))] }) }));
|
|
85
|
+
}
|
|
86
|
+
MembersSettings.displayName = "MembersSettings";
|
|
87
|
+
/**
|
|
88
|
+
* Attio's "Invite members" modal (crisp#636, P-120), measured live: 708px
|
|
89
|
+
* wide, a multi-email composer, an "Invite as" select (default Member) and
|
|
90
|
+
* an optional "Add to team" search-or-create select, footer "Send Invites".
|
|
91
|
+
*/
|
|
92
|
+
function InviteMembersDialog({ open, onOpenChange, emails, onEmailsChange, inviteAs, onInviteAsChange, team, onTeamChange, teamOptions = [], onSend, title = "Invite members", emailsPlaceholder = "Send Invite to ...", inviteAsFieldLabel = "Invite as", memberOptionLabel = "Member — can edit", adminOptionLabel = "Admin — full access", addToTeamFieldLabel = "Add to team", addToTeamPlaceholder = "Search or create a team", sendLabel = "Send Invites ⌘⏎", ...rest }) {
|
|
93
|
+
const inviteAsOptions = [
|
|
94
|
+
{ value: "member", label: memberOptionLabel },
|
|
95
|
+
{ value: "admin", label: adminOptionLabel },
|
|
96
|
+
];
|
|
97
|
+
return ((0, jsx_runtime_1.jsxs)(dialog_1.Dialog, { open: open, onOpenChange: onOpenChange, title: title, width: 708, ...rest, children: [(0, jsx_runtime_1.jsxs)(dialog_1.DialogBody, { children: [(0, jsx_runtime_1.jsx)("div", { className: "crisp-memberssettings-invitefield", children: (0, jsx_runtime_1.jsx)(textarea_1.Textarea, { value: emails, onChange: (e) => onEmailsChange(e.target.value), placeholder: emailsPlaceholder, rows: 3 }) }), (0, jsx_runtime_1.jsx)(formfield_1.FormField, { label: inviteAsFieldLabel, children: (0, jsx_runtime_1.jsx)(select_1.Select, { options: inviteAsOptions, value: inviteAs, onValueChange: (v) => onInviteAsChange(v) }) }), (0, jsx_runtime_1.jsx)(formfield_1.FormField, { label: addToTeamFieldLabel, optional: true, children: (0, jsx_runtime_1.jsx)(select_1.Select, { options: teamOptions, value: team, onValueChange: onTeamChange, placeholder: addToTeamPlaceholder, searchable: true }) })] }), (0, jsx_runtime_1.jsx)(dialog_1.DialogFooter, { children: (0, jsx_runtime_1.jsx)(button_1.Button, { intent: "primary", onClick: onSend, children: sendLabel }) })] }));
|
|
98
|
+
}
|
|
99
|
+
InviteMembersDialog.displayName = "InviteMembersDialog";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memberssettingsRecipe = void 0;
|
|
4
|
+
const core_1 = require("../../core");
|
|
5
|
+
const tokens_1 = require("../../tokens");
|
|
6
|
+
// Measured live against app.attio.com/<workspace>/settings/members-and-teams
|
|
7
|
+
// (crisp#636, P-119/P-120). The Members/Teams switcher is a plain segmented
|
|
8
|
+
// pill toggle -- NOT the shared `Tabs` primitive, which always reserves an
|
|
9
|
+
// 8px baseline strip and draws an ink underline (crisp#749's own tabs
|
|
10
|
+
// recipe comment): this page's tab container measured a clean 28px, no
|
|
11
|
+
// baseline, no underline, bg transparent. Reusing `Tabs` here would paint a
|
|
12
|
+
// baseline Attio's own switcher doesn't have.
|
|
13
|
+
const config = (0, core_1.defineRecipe)({
|
|
14
|
+
name: "memberssettings",
|
|
15
|
+
base: `& .crisp-memberssettings-page { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["6"]}; font-family: ${tokens_1.contract.font.sans}; }
|
|
16
|
+
& .crisp-memberssettings-heading { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["0.5"]}; }
|
|
17
|
+
& .crisp-memberssettings-title { font-size: 24px; line-height: 28px; font-weight: ${tokens_1.contract.weight.semibold}; letter-spacing: -0.48px; color: ${tokens_1.contract.fgPrimary}; margin: 0; }
|
|
18
|
+
& .crisp-memberssettings-desc { font-size: ${tokens_1.contract.text.lg}; line-height: 20px; color: ${tokens_1.contract.fgMuted}; margin: 0; }
|
|
19
|
+
|
|
20
|
+
/* Segmented Members/Teams switcher -- measured: 28px pills, radius 8,
|
|
21
|
+
4px gap, 6px icon-label gap, 14/500 label, selected bg bgSubtle +
|
|
22
|
+
inset borderSubtle ring, unselected transparent + a flat 63%-opacity
|
|
23
|
+
fgPrimary mix (measured rgba(0,0,0,.63) on the live page, not the
|
|
24
|
+
solid fgMuted token — same alpha technique this file's table header
|
|
25
|
+
already uses). */
|
|
26
|
+
& .crisp-memberssettings-tabpair { display: inline-flex; align-items: center; gap: 4px; }
|
|
27
|
+
& .crisp-memberssettings-tab { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: 28px; padding: 0 ${tokens_1.contract.space["2"]}; border: none; border-radius: ${tokens_1.contract.radius.md}; background: none; box-shadow: inset 0 0 0 1px transparent; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); cursor: pointer; white-space: nowrap; transition: color .12s ease, background-color .12s ease, box-shadow .12s ease; }
|
|
28
|
+
& .crisp-memberssettings-tab svg { flex-shrink: 0; }
|
|
29
|
+
& .crisp-memberssettings-tab:hover:not([data-selected]) { color: ${tokens_1.contract.fgPrimary}; }
|
|
30
|
+
& .crisp-memberssettings-tab[data-selected] { color: ${tokens_1.contract.fgPrimary}; background: ${tokens_1.contract.bgSubtle}; box-shadow: inset 0 0 0 1px ${tokens_1.contract.borderSubtle}; }
|
|
31
|
+
& .crisp-memberssettings-tab:focus-visible { outline: 2px solid ${tokens_1.contract.bgBrandSolid}; outline-offset: 1px; }
|
|
32
|
+
|
|
33
|
+
/* Toolbar row: search grows, Filter + Invite sit trailing -- measured
|
|
34
|
+
32px height on all three, search radius 9 with a 6% ink ring,
|
|
35
|
+
Filter/Invite radius 9 with the button drop-shadow pairing. */
|
|
36
|
+
& .crisp-memberssettings-toolbar { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; }
|
|
37
|
+
& .crisp-memberssettings-search { display: flex; align-items: center; flex: 1; min-width: 0; gap: ${tokens_1.contract.space["1.5"]}; height: 32px; padding: 0 ${tokens_1.contract.space["2.5"]} 0 ${tokens_1.contract.space["2"]}; border-radius: 9px; background: ${tokens_1.contract.bgSurface}; box-shadow: inset 0 0 0 1px color-mix(in srgb, ${tokens_1.contract.fgPrimary} 6%, transparent); color: ${tokens_1.contract.fgMuted}; }
|
|
38
|
+
& .crisp-memberssettings-search:focus-within { box-shadow: inset 0 0 0 1px ${tokens_1.contract.bgBrandSolid}; }
|
|
39
|
+
& .crisp-memberssettings-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; }
|
|
40
|
+
& .crisp-memberssettings-search input::placeholder { color: ${tokens_1.contract.fgMuted}; }
|
|
41
|
+
& .crisp-memberssettings-filterbtn { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: ${tokens_1.contract.bgSurface}; box-shadow: inset 0 0 0 1px transparent, 0 0 2px 0 rgba(28,40,64,.18), 0 1px 3px 0 rgba(0,0,0,.04); color: ${tokens_1.contract.fgPrimary}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; cursor: pointer; white-space: nowrap; }
|
|
42
|
+
& .crisp-memberssettings-filterbtn:hover { background: ${tokens_1.contract.bgRaised}; }
|
|
43
|
+
/* your-moon/crisp#979: bgBrandContrast, not bgBrandSolid -- the accent
|
|
44
|
+
(#0298d9) only clears 3.23:1 with white; the darker sibling clears
|
|
45
|
+
4.5:1+, same fix already applied to Button/Badge/Avatar (#897) and
|
|
46
|
+
TableToolbar/Dialog/Command/Comments/AuthShell (#953/#961), which
|
|
47
|
+
explicitly flagged this button as found-not-fixed. */
|
|
48
|
+
& .crisp-memberssettings-invitebtn { display: inline-flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: ${tokens_1.contract.bgBrandContrast}; box-shadow: inset 0 0 0 1px rgba(0,0,0,.06), 0 2px 4px -2px color-mix(in srgb, ${tokens_1.contract.bgBrandContrast} 12%, transparent), 0 3px 6px -2px color-mix(in srgb, ${tokens_1.contract.bgBrandContrast} 8%, transparent); color: ${tokens_1.contract.fgOnBrand}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; cursor: pointer; white-space: nowrap; }
|
|
49
|
+
& .crisp-memberssettings-invitebtn:hover { filter: brightness(0.95); }
|
|
50
|
+
|
|
51
|
+
/* Table wrapper -- measured card: radius 12, 1px borderSubtle, 40px
|
|
52
|
+
rows, header label 12/500/63%-opacity fgPrimary. */
|
|
53
|
+
& .crisp-memberssettings-table-wrap { border-radius: 12px; border: 1px solid ${tokens_1.contract.borderSubtle}; overflow: hidden; }
|
|
54
|
+
& .crisp-memberssettings-table { width: 100%; border-collapse: collapse; font-family: inherit; }
|
|
55
|
+
& .crisp-memberssettings-table th { height: 32px; padding: 0 ${tokens_1.contract.space["4"]}; text-align: start; font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); border-bottom: 1px solid ${tokens_1.contract.borderSubtle}; background: ${tokens_1.contract.bgSurface}; }
|
|
56
|
+
& .crisp-memberssettings-table td { height: 40px; padding: 0 ${tokens_1.contract.space["4"]}; font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; border-bottom: 1px solid ${tokens_1.contract.borderSubtle}; }
|
|
57
|
+
& .crisp-memberssettings-table tr:last-child td { border-bottom: none; }
|
|
58
|
+
& .crisp-memberssettings-user { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; }
|
|
59
|
+
& .crisp-memberssettings-avatarimg { width: 24px; height: 24px; border-radius: ${tokens_1.contract.radius.full}; object-fit: cover; }
|
|
60
|
+
/* Name + email sit on ONE line, not stacked -- confirmed live: both spans
|
|
61
|
+
share the same y and the same 14px size, only the email's colour
|
|
62
|
+
differs (a flat 63%-opacity fgPrimary mix, not a smaller muted font). */
|
|
63
|
+
& .crisp-memberssettings-usermeta { display: flex; align-items: baseline; gap: ${tokens_1.contract.space["2"]}; min-width: 0; }
|
|
64
|
+
& .crisp-memberssettings-usermeta > span:first-child { flex-shrink: 0; }
|
|
65
|
+
& .crisp-memberssettings-useremail { font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.regular}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
66
|
+
& .crisp-memberssettings-kebab { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-inline-start: auto; border: none; border-radius: ${tokens_1.contract.radius.sm}; background: none; font-family: inherit; color: ${tokens_1.contract.fgMuted}; cursor: pointer; }
|
|
67
|
+
& .crisp-memberssettings-kebab:hover { background: ${tokens_1.contract.bgRaised}; color: ${tokens_1.contract.fgPrimary}; }
|
|
68
|
+
|
|
69
|
+
& .crisp-memberssettings-teamspanel { display: flex; align-items: center; justify-content: center; padding: ${tokens_1.contract.space["8"]} 0; color: ${tokens_1.contract.fgMuted}; font-size: ${tokens_1.contract.text.lg}; }
|
|
70
|
+
|
|
71
|
+
/* Invite dialog fields -- measured 708x386 dialog, radius 16; the
|
|
72
|
+
"Invite as"/"Add to team" selects are 32/34px with a flat 1px
|
|
73
|
+
6%-ink border and 9/10px radius respectively (Attio's own two
|
|
74
|
+
selects don't share one radius). */
|
|
75
|
+
& .crisp-memberssettings-invitefield { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["1.5"]}; }
|
|
76
|
+
& .crisp-memberssettings-invitelabel { font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgMuted}; }
|
|
77
|
+
`,
|
|
78
|
+
variants: {},
|
|
79
|
+
defaultVariants: {},
|
|
80
|
+
compoundVariants: [],
|
|
81
|
+
});
|
|
82
|
+
exports.memberssettingsRecipe = (0, core_1.resolveRecipe)(config);
|
|
83
|
+
exports.default = config;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NotificationsSettings = void 0;
|
|
4
|
+
var notificationssettings_1 = require("./notificationssettings");
|
|
5
|
+
Object.defineProperty(exports, "NotificationsSettings", { enumerable: true, get: function () { return notificationssettings_1.NotificationsSettings; } });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NotificationsSettings = NotificationsSettings;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const lucide_react_1 = require("lucide-react");
|
|
6
|
+
const checkbox_1 = require("../../components/checkbox");
|
|
7
|
+
const switch_1 = require("../../components/switch");
|
|
8
|
+
const textlink_1 = require("../../components/textlink");
|
|
9
|
+
const notificationssettings_recipe_1 = require("./notificationssettings.recipe");
|
|
10
|
+
/**
|
|
11
|
+
* Attio's "Notifications" settings page (crisp#630, P-083): title +
|
|
12
|
+
* description, a "Daily digest" card (a single toggle row), and a
|
|
13
|
+
* "Collaboration notifications" matrix — a header row plus one row per
|
|
14
|
+
* event, each with an Email and an App checkbox. Measured live.
|
|
15
|
+
*/
|
|
16
|
+
function NotificationsSettings({ dailyDigestEnabled, onDailyDigestChange, rows, onEmailChange, onAppChange, className, title = "Notifications", description = "Customize your notification settings to stay informed without being overwhelmed.", learnMoreLabel = "Learn more", learnMoreHref = "#", dailyDigestSectionTitle = "Daily digest", dailyDigestRowTitle = "Enable daily digest", dailyDigestRowDescription = "Includes tasks overdue and due today. Sent every morning if any tasks are due or overdue.", collaborationSectionTitle = "Collaboration notifications", notifyMeAboutLabel = "Notify me about", emailColumnLabel = "Email", appColumnLabel = "App", ...rest }) {
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, notificationssettings_recipe_1.notificationssettingsRecipe)({ className }), ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-page", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-heading", children: [(0, jsx_runtime_1.jsx)("h1", { className: "crisp-notificationssettings-title", children: title }), (0, jsx_runtime_1.jsxs)("p", { className: "crisp-notificationssettings-desc", children: [description, " ", (0, jsx_runtime_1.jsx)(textlink_1.TextLink, { href: learnMoreHref, children: learnMoreLabel })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-section", children: [(0, jsx_runtime_1.jsx)("h2", { className: "crisp-notificationssettings-sectiontitle", children: dailyDigestSectionTitle }), (0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-digestcard", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-digesttext", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-notificationssettings-rowtitle", children: dailyDigestRowTitle }), (0, jsx_runtime_1.jsx)("span", { className: "crisp-notificationssettings-rowdesc", children: dailyDigestRowDescription })] }), (0, jsx_runtime_1.jsx)(switch_1.Switch, { checked: dailyDigestEnabled, onCheckedChange: onDailyDigestChange, "aria-label": dailyDigestRowTitle })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-section", children: [(0, jsx_runtime_1.jsx)("h2", { className: "crisp-notificationssettings-sectiontitle", children: collaborationSectionTitle }), (0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-matrix", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-matrixhead", children: [(0, jsx_runtime_1.jsxs)("span", { className: "crisp-notificationssettings-matrixhead-about", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Bell, { size: 14 }), notifyMeAboutLabel] }), (0, jsx_runtime_1.jsxs)("span", { className: "crisp-notificationssettings-matrixhead-col", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { size: 14 }), emailColumnLabel] }), (0, jsx_runtime_1.jsxs)("span", { className: "crisp-notificationssettings-matrixhead-col", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.MonitorSmartphone, { size: 14 }), appColumnLabel] })] }), rows.map((row) => ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-matrixrow", children: [(0, jsx_runtime_1.jsxs)("div", { className: "crisp-notificationssettings-matrixrow-about", children: [(0, jsx_runtime_1.jsx)("span", { className: "crisp-notificationssettings-rowtitle", children: row.title }), (0, jsx_runtime_1.jsx)("span", { className: "crisp-notificationssettings-rowdesc", children: row.description })] }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-notificationssettings-matrixrow-col", children: (0, jsx_runtime_1.jsx)(checkbox_1.Checkbox, { checked: row.email, onChange: (e) => onEmailChange(row.id, e.target.checked), "aria-label": `${emailColumnLabel}: ${typeof row.title === "string" ? row.title : row.id}` }) }), (0, jsx_runtime_1.jsx)("div", { className: "crisp-notificationssettings-matrixrow-col", children: (0, jsx_runtime_1.jsx)(checkbox_1.Checkbox, { checked: row.app, onChange: (e) => onAppChange(row.id, e.target.checked), "aria-label": `${appColumnLabel}: ${typeof row.title === "string" ? row.title : row.id}` }) })] }, row.id)))] })] })] }) }));
|
|
18
|
+
}
|
|
19
|
+
NotificationsSettings.displayName = "NotificationsSettings";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.notificationssettingsRecipe = void 0;
|
|
4
|
+
const core_1 = require("../../core");
|
|
5
|
+
const tokens_1 = require("../../tokens");
|
|
6
|
+
// Measured live against app.attio.com/<workspace>/settings/notifications
|
|
7
|
+
// (crisp#630, P-083). Two sections, each a 16/600 heading over a bordered
|
|
8
|
+
// 12px-radius card: "Daily digest" (a single 56px row, label 14/500 +
|
|
9
|
+
// description 12/500/63%-opacity, a Switch trailing) and "Collaboration
|
|
10
|
+
// notifications" (a header row -- 12/500/63%-opacity labels -- then 7 rows,
|
|
11
|
+
// each 52px, a title/description pair on the left and two Checkboxes,
|
|
12
|
+
// right-aligned under Email/App, per row).
|
|
13
|
+
const config = (0, core_1.defineRecipe)({
|
|
14
|
+
name: "notificationssettings",
|
|
15
|
+
base: `& .crisp-notificationssettings-page { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["6"]}; font-family: ${tokens_1.contract.font.sans}; }
|
|
16
|
+
& .crisp-notificationssettings-heading { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["0.5"]}; }
|
|
17
|
+
& .crisp-notificationssettings-title { font-size: 24px; line-height: 28px; font-weight: ${tokens_1.contract.weight.semibold}; letter-spacing: -0.48px; color: ${tokens_1.contract.fgPrimary}; margin: 0; }
|
|
18
|
+
& .crisp-notificationssettings-desc { font-size: ${tokens_1.contract.text.lg}; line-height: 20px; color: ${tokens_1.contract.fgMuted}; margin: 0; }
|
|
19
|
+
|
|
20
|
+
& .crisp-notificationssettings-section { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["4"]}; }
|
|
21
|
+
& .crisp-notificationssettings-sectiontitle { font-size: 16px; line-height: 20px; font-weight: ${tokens_1.contract.weight.semibold}; color: ${tokens_1.contract.fgPrimary}; margin: 0; }
|
|
22
|
+
|
|
23
|
+
/* Daily digest card: one bordered 12px-radius row. */
|
|
24
|
+
& .crisp-notificationssettings-digestcard { display: flex; align-items: center; justify-content: space-between; gap: ${tokens_1.contract.space["6"]}; padding: ${tokens_1.contract.space["2"]} ${tokens_1.contract.space["3"]}; border: 1px solid ${tokens_1.contract.borderSubtle}; border-radius: 12px; background: ${tokens_1.contract.bgSurface}; }
|
|
25
|
+
& .crisp-notificationssettings-digesttext { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["1"]}; }
|
|
26
|
+
& .crisp-notificationssettings-rowtitle { font-size: ${tokens_1.contract.text.lg}; font-weight: ${tokens_1.contract.weight.medium}; color: ${tokens_1.contract.fgPrimary}; }
|
|
27
|
+
& .crisp-notificationssettings-rowdesc { font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); }
|
|
28
|
+
|
|
29
|
+
/* Collaboration matrix: a bordered card, header row + N body rows. */
|
|
30
|
+
& .crisp-notificationssettings-matrix { border: 1px solid ${tokens_1.contract.borderSubtle}; border-radius: 12px; overflow: hidden; background: ${tokens_1.contract.bgSurface}; }
|
|
31
|
+
& .crisp-notificationssettings-matrixhead { display: flex; align-items: center; gap: ${tokens_1.contract.space["3"]}; padding: 0 ${tokens_1.contract.space["4"]}; height: 40px; border-bottom: 1px solid ${tokens_1.contract.borderSubtle}; }
|
|
32
|
+
& .crisp-notificationssettings-matrixhead-about { display: flex; align-items: center; gap: ${tokens_1.contract.space["1.5"]}; flex: 1; min-width: 0; font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); }
|
|
33
|
+
& .crisp-notificationssettings-matrixhead-col { display: flex; align-items: center; justify-content: center; gap: ${tokens_1.contract.space["1.5"]}; width: 64px; flex-shrink: 0; font-size: ${tokens_1.contract.text.sm}; font-weight: ${tokens_1.contract.weight.medium}; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 63%, transparent); }
|
|
34
|
+
& .crisp-notificationssettings-matrixrow { display: flex; align-items: center; gap: ${tokens_1.contract.space["3"]}; padding: ${tokens_1.contract.space["2"]} ${tokens_1.contract.space["4"]}; min-height: 52px; }
|
|
35
|
+
& .crisp-notificationssettings-matrixrow + .crisp-notificationssettings-matrixrow { border-top: 1px solid ${tokens_1.contract.borderSubtle}; }
|
|
36
|
+
& .crisp-notificationssettings-matrixrow-about { display: flex; flex-direction: column; gap: ${tokens_1.contract.space["1"]}; flex: 1; min-width: 0; }
|
|
37
|
+
& .crisp-notificationssettings-matrixrow-col { display: flex; align-items: center; justify-content: center; width: 64px; flex-shrink: 0; }
|
|
38
|
+
`,
|
|
39
|
+
variants: {},
|
|
40
|
+
defaultVariants: {},
|
|
41
|
+
compoundVariants: [],
|
|
42
|
+
});
|
|
43
|
+
exports.notificationssettingsRecipe = (0, core_1.resolveRecipe)(config);
|
|
44
|
+
exports.default = config;
|