@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
|
@@ -92,7 +92,11 @@ const spec = (0, core_1.defineSpec)({
|
|
|
92
92
|
paddingInline: tokens_1.contract.space["1"],
|
|
93
93
|
fontSize: tokens_1.contract.text.sm,
|
|
94
94
|
lineHeight: "16px",
|
|
95
|
-
|
|
95
|
+
// your-moon/crisp#919: seed-design's own Badge (`badge.yaml`)
|
|
96
|
+
// is a small rounded-rect at every size, never a pill -- its
|
|
97
|
+
// small/medium step is `$radius.r1` = 4px (`radius.xs`), not the 6px
|
|
98
|
+
// `radius.sm` this used to share with Chip's old rounded-rect shape.
|
|
99
|
+
borderRadius: tokens_1.contract.radius.xs,
|
|
96
100
|
},
|
|
97
101
|
// crisp#696: Attio's tag pill (Standard/System/Enriched) measures
|
|
98
102
|
// 20px h / 4px padding / 12px text / 16px line-height / 3px gap -- was
|
|
@@ -104,14 +108,24 @@ const spec = (0, core_1.defineSpec)({
|
|
|
104
108
|
fontSize: tokens_1.contract.text.sm,
|
|
105
109
|
lineHeight: "16px",
|
|
106
110
|
gap: "3px",
|
|
107
|
-
|
|
111
|
+
// your-moon/crisp#919: same seed radius step as `small`
|
|
112
|
+
// above -- seed's Badge treats small/medium as one radius step
|
|
113
|
+
// (`$radius.r1` = 4px), unlike Button/Input's per-size table.
|
|
114
|
+
borderRadius: tokens_1.contract.radius.xs,
|
|
108
115
|
},
|
|
109
116
|
// crisp#805: measured live against Attio's real status/stage chip
|
|
110
|
-
// (Deals "Deal stage" column, All Deals table view) --
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
117
|
+
// (Deals "Deal stage" column, All Deals table view) -- asymmetric
|
|
118
|
+
// padding (room for a leading dot/icon: 1px top/bottom, 6px trailing,
|
|
119
|
+
// 4px leading), not a symmetric 9px. Height/font/tracking are
|
|
120
|
+
// unchanged (still not independently re-measured this round, per
|
|
121
|
+
// #696's own note).
|
|
122
|
+
// your-moon/crisp#919: radius was Attio's own measured 9px
|
|
123
|
+
// (`radius.lg`, deliberately not `radius.chip`'s then-7px) -- now
|
|
124
|
+
// `radius.sm` (6px), seed-design's own Badge large step
|
|
125
|
+
// (`$radius.r1_5`). Radius specifically is one of the values this
|
|
126
|
+
// migration takes from seed over an Attio measurement (colours/radii/
|
|
127
|
+
// control-styling/elevation all do); the padding/height facts above
|
|
128
|
+
// are unaffected and still Attio's.
|
|
115
129
|
large: {
|
|
116
130
|
height: tokens_1.contract.size.chip,
|
|
117
131
|
paddingBlock: tokens_1.contract.space.px,
|
|
@@ -119,7 +133,7 @@ const spec = (0, core_1.defineSpec)({
|
|
|
119
133
|
paddingInlineEnd: tokens_1.contract.space["1.5"],
|
|
120
134
|
fontSize: tokens_1.contract.text.lg,
|
|
121
135
|
letterSpacing: "-0.1px",
|
|
122
|
-
borderRadius: tokens_1.contract.radius.
|
|
136
|
+
borderRadius: tokens_1.contract.radius.sm,
|
|
123
137
|
},
|
|
124
138
|
},
|
|
125
139
|
variant: { soft: {}, solid: {} },
|
|
@@ -0,0 +1,90 @@
|
|
|
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.BottomSheet = BottomSheet;
|
|
37
|
+
exports.BottomSheetBody = BottomSheetBody;
|
|
38
|
+
exports.BottomSheetFooter = BottomSheetFooter;
|
|
39
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
40
|
+
const dialog = __importStar(require("@zag-js/dialog"));
|
|
41
|
+
const react_1 = require("@zag-js/react");
|
|
42
|
+
const lucide_react_1 = require("lucide-react");
|
|
43
|
+
const React = __importStar(require("react"));
|
|
44
|
+
const core_1 = require("../../core");
|
|
45
|
+
const bottomsheet_recipe_1 = require("./bottomsheet.recipe");
|
|
46
|
+
let instanceCounter = 0;
|
|
47
|
+
function useBottomSheetInstanceId() {
|
|
48
|
+
const idRef = React.useRef(null);
|
|
49
|
+
if (idRef.current == null) {
|
|
50
|
+
instanceCounter += 1;
|
|
51
|
+
idRef.current = `crisp-bottomsheet-${instanceCounter}`;
|
|
52
|
+
}
|
|
53
|
+
return idRef.current;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A mobile bottom sheet — composes Zag's dialog machine (focus trap, scroll
|
|
57
|
+
* lock, Escape / outside-click dismissal) with a panel that slides up from
|
|
58
|
+
* the bottom edge. Compose the body with `BottomSheetBody` and actions with
|
|
59
|
+
* `BottomSheetFooter`.
|
|
60
|
+
*/
|
|
61
|
+
function BottomSheet({ open, onOpenChange, title, description, headerAlign = "left", showCloseButton, "aria-label": ariaLabel, closeLabel: closeLabelProp, children, className, "aria-describedby": describedBy, ...rest }) {
|
|
62
|
+
const closeLabel = (0, core_1.useCrispMessage)(closeLabelProp, "Close");
|
|
63
|
+
const id = useBottomSheetInstanceId();
|
|
64
|
+
const service = (0, react_1.useMachine)(dialog.machine, {
|
|
65
|
+
id,
|
|
66
|
+
open,
|
|
67
|
+
onOpenChange(details) {
|
|
68
|
+
onOpenChange(details.open);
|
|
69
|
+
},
|
|
70
|
+
"aria-label": typeof title === "string" ? title : ariaLabel,
|
|
71
|
+
// Defer to a nested Menu/Select/Popover/ContextMenu's own Escape
|
|
72
|
+
// handling (#361) -- same reasoning as Dialog/Drawer, same machine.
|
|
73
|
+
onEscapeKeyDown(event) {
|
|
74
|
+
if ((0, core_1.hasOpenFloatingLayer)())
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
const api = dialog.connect(service, react_1.normalizeProps);
|
|
79
|
+
if (!api.open)
|
|
80
|
+
return null;
|
|
81
|
+
const hasClose = showCloseButton ?? title != null;
|
|
82
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Portal, { children: (0, jsx_runtime_1.jsxs)("div", { className: (0, bottomsheet_recipe_1.bottomsheetRecipe)(), children: [(0, jsx_runtime_1.jsx)("div", { ...api.getBackdropProps(), className: "crisp-bottomsheet-backdrop" }), (0, jsx_runtime_1.jsx)("div", { ...api.getPositionerProps(), className: "crisp-bottomsheet-positioner", children: (0, jsx_runtime_1.jsxs)("div", { ...rest, ...(0, core_1.withDescribedBy)(api.getContentProps(), describedBy), className: (0, core_1.cx)("crisp-bottomsheet-content", className), "data-header-align": headerAlign, "data-has-close": hasClose ? "" : undefined, children: [(title != null || description != null) && ((0, jsx_runtime_1.jsxs)("div", { className: "crisp-bottomsheet-header", children: [title != null && ((0, jsx_runtime_1.jsx)("span", { ...api.getTitleProps(), className: "crisp-bottomsheet-title", children: title })), description != null && ((0, jsx_runtime_1.jsx)("span", { className: "crisp-bottomsheet-description", children: description })), hasClose && ((0, jsx_runtime_1.jsx)("button", { type: "button", ...api.getCloseTriggerProps(), className: "crisp-bottomsheet-close", "aria-label": closeLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16, strokeWidth: 2, "aria-hidden": "true" }) }))] })), children] }) })] }) }));
|
|
83
|
+
}
|
|
84
|
+
BottomSheet.displayName = "BottomSheet";
|
|
85
|
+
function BottomSheetBody({ children }) {
|
|
86
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "crisp-bottomsheet-body", children: children });
|
|
87
|
+
}
|
|
88
|
+
function BottomSheetFooter({ children, }) {
|
|
89
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "crisp-bottomsheet-footer", children: children });
|
|
90
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bottomsheetRecipe = void 0;
|
|
4
|
+
const core_1 = require("../../core");
|
|
5
|
+
const tokens_1 = require("../../tokens");
|
|
6
|
+
// A mobile bottom sheet — daangn/seed-design's
|
|
7
|
+
// packages/rootage/components/bottom-sheet.yaml (dev@e1c486b904297f7b6a8f17b8523f732c37015d60),
|
|
8
|
+
// not Attio (no such component there; crisp#911). Composes @zag-js/dialog, the
|
|
9
|
+
// same headless machine Dialog/Drawer already use, with a panel that slides
|
|
10
|
+
// up from the bottom edge over a scrim -- only the TOP corners round; the
|
|
11
|
+
// panel sits flush with the viewport's bottom edge, unlike Drawer's own
|
|
12
|
+
// 8px-gutter floating panel. Every numeric value below cites its yaml line.
|
|
13
|
+
const config = (0, core_1.defineRecipe)({
|
|
14
|
+
name: "bottomsheet",
|
|
15
|
+
base: `display: contents; font-family: ${tokens_1.contract.font.sans};
|
|
16
|
+
& .crisp-bottomsheet-backdrop {
|
|
17
|
+
position: fixed; inset: 0; z-index: 60;
|
|
18
|
+
background: ${tokens_1.contract.bgOverlayStrong}; /* bottom-sheet.yaml:99 backdrop.color = $color.bg.overlay -- a different, darker, theme-constant scrim than the Dialog bgScrim token, see its own comment */
|
|
19
|
+
opacity: 1; transition: opacity 300ms cubic-bezier(0,0,.15,1); /* bottom-sheet.yaml:100-102 enterDuration/enterTimingFunction */
|
|
20
|
+
@starting-style { opacity: 0; }
|
|
21
|
+
}
|
|
22
|
+
& .crisp-bottomsheet-positioner {
|
|
23
|
+
position: fixed; inset: 0; z-index: 61;
|
|
24
|
+
display: flex; align-items: flex-end; justify-content: center;
|
|
25
|
+
}
|
|
26
|
+
& .crisp-bottomsheet-content {
|
|
27
|
+
-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
28
|
+
position: relative; box-sizing: border-box; display: flex; flex-direction: column;
|
|
29
|
+
overflow: hidden; width: 100%; max-width: 480px; /* bottom-sheet.yaml:110 content.maxWidth */
|
|
30
|
+
max-height: 85vh;
|
|
31
|
+
background: ${tokens_1.contract.bgSurface}; /* bottom-sheet.yaml:109 content.color = $color.bg.layer-floating */
|
|
32
|
+
border-radius: ${tokens_1.contract.radius["4xl"]} ${tokens_1.contract.radius["4xl"]} 0 0; /* bottom-sheet.yaml:111 content.topCornerRadius = $radius.r6 (24px), bottom flush with the viewport */
|
|
33
|
+
transform: translateY(0);
|
|
34
|
+
transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* bottom-sheet.yaml:112-113 content.enterDuration/enterTimingFunction (enter-expressive) */
|
|
35
|
+
@starting-style { transform: translateY(100%); }
|
|
36
|
+
}
|
|
37
|
+
& .crisp-bottomsheet-header {
|
|
38
|
+
position: relative; display: flex; flex-direction: column;
|
|
39
|
+
gap: ${tokens_1.contract.space["2"]}; /* bottom-sheet.yaml:120 header.gap = $dimension.x2 (8px) */
|
|
40
|
+
padding-top: ${tokens_1.contract.space["6"]}; padding-bottom: ${tokens_1.contract.space["4"]}; /* bottom-sheet.yaml:121-122 header.paddingTop/paddingBottom = $dimension.x6/x4 (24px/16px) */
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
}
|
|
43
|
+
& .crisp-bottomsheet-title {
|
|
44
|
+
color: ${tokens_1.contract.fgPrimary}; /* bottom-sheet.yaml:130 title.color = $color.fg.neutral */
|
|
45
|
+
font-size: 22px; line-height: 30px; font-weight: ${tokens_1.contract.weight.bold}; /* bottom-sheet.yaml:131-133 title.fontSize/lineHeight/fontWeight = $font-size.t8/$line-height.t8/bold */
|
|
46
|
+
padding-inline: ${tokens_1.contract.space["4"]}; /* default (headerAlignment=left, no close button): bottom-sheet.yaml:150-152 */
|
|
47
|
+
}
|
|
48
|
+
&[data-header-align="left"][data-has-close] .crisp-bottomsheet-title { padding-inline-start: ${tokens_1.contract.space["4"]}; padding-inline-end: 56px; } /* bottom-sheet.yaml:141-144 */
|
|
49
|
+
&[data-header-align="center"] .crisp-bottomsheet-title { text-align: center; }
|
|
50
|
+
&[data-header-align="center"][data-has-close] .crisp-bottomsheet-title { padding-inline: 56px; } /* bottom-sheet.yaml:154-157 */
|
|
51
|
+
& .crisp-bottomsheet-description {
|
|
52
|
+
color: ${tokens_1.contract.fgMuted}; /* bottom-sheet.yaml:138 description.color = $color.fg.neutral-muted */
|
|
53
|
+
font-size: ${tokens_1.contract.text.xl}; line-height: 22px; font-weight: ${tokens_1.contract.weight.regular}; /* bottom-sheet.yaml:139-141 description.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */
|
|
54
|
+
padding-inline: ${tokens_1.contract.space["4"]}; /* bottom-sheet.yaml:142 description.paddingX = global-gutter (16px) */
|
|
55
|
+
}
|
|
56
|
+
& .crisp-bottomsheet-close {
|
|
57
|
+
position: absolute; top: ${tokens_1.contract.space["6"]}; inset-inline-end: ${tokens_1.contract.space["4"]}; /* bottom-sheet.yaml:145-146 closeButton.fromTop/fromRight = $dimension.x6/x4 (24px/16px) */
|
|
58
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
59
|
+
width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: ${tokens_1.contract.radius.md};
|
|
60
|
+
background: none; color: ${tokens_1.contract.fgMuted}; font-family: inherit; cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
& .crisp-bottomsheet-close:hover { background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 6%, transparent); color: ${tokens_1.contract.fgPrimary}; }
|
|
63
|
+
& .crisp-bottomsheet-body {
|
|
64
|
+
flex: 1; min-height: 0; overflow-y: auto;
|
|
65
|
+
padding-inline: ${tokens_1.contract.space["4"]}; /* bottom-sheet.yaml:126 body.paddingX = global-gutter (16px) -- no vertical padding in the spec */
|
|
66
|
+
}
|
|
67
|
+
& .crisp-bottomsheet-footer {
|
|
68
|
+
display: flex; align-items: center; justify-content: flex-end; gap: ${tokens_1.contract.space["3"]};
|
|
69
|
+
flex-shrink: 0;
|
|
70
|
+
padding-inline: ${tokens_1.contract.space["4"]}; padding-top: ${tokens_1.contract.space["3"]}; padding-bottom: ${tokens_1.contract.space["4"]}; /* bottom-sheet.yaml:127-129 footer.paddingX/paddingTop/paddingBottom = global-gutter/x3/x4 (16px/12px/16px) */
|
|
71
|
+
}`,
|
|
72
|
+
variants: {},
|
|
73
|
+
defaultVariants: {},
|
|
74
|
+
compoundVariants: [],
|
|
75
|
+
});
|
|
76
|
+
exports.bottomsheetRecipe = (0, core_1.resolveRecipe)(config);
|
|
77
|
+
exports.default = config;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bottomsheetRecipe = exports.BottomSheetFooter = exports.BottomSheetBody = exports.BottomSheet = void 0;
|
|
4
|
+
var bottomsheet_1 = require("./bottomsheet");
|
|
5
|
+
Object.defineProperty(exports, "BottomSheet", { enumerable: true, get: function () { return bottomsheet_1.BottomSheet; } });
|
|
6
|
+
Object.defineProperty(exports, "BottomSheetBody", { enumerable: true, get: function () { return bottomsheet_1.BottomSheetBody; } });
|
|
7
|
+
Object.defineProperty(exports, "BottomSheetFooter", { enumerable: true, get: function () { return bottomsheet_1.BottomSheetFooter; } });
|
|
8
|
+
var bottomsheet_recipe_1 = require("./bottomsheet.recipe");
|
|
9
|
+
Object.defineProperty(exports, "bottomsheetRecipe", { enumerable: true, get: function () { return bottomsheet_recipe_1.bottomsheetRecipe; } });
|
|
@@ -55,7 +55,7 @@ function Breadcrumb({ items, separator, "aria-label": ariaLabelProp, className,
|
|
|
55
55
|
return ((0, jsx_runtime_1.jsx)("nav", { "aria-label": ariaLabel, className: (0, breadcrumb_recipe_1.breadcrumbRecipe)({ className }), ...rest, children: items.map((item, i) => {
|
|
56
56
|
const last = i === items.length - 1;
|
|
57
57
|
const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [item.icon, item.label] }));
|
|
58
|
-
return ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [last ? ((0, jsx_runtime_1.jsx)("span", { className: "crisp-breadcrumb-item", "aria-current": "page", children: content })) : item.href ? ((0, jsx_runtime_1.jsx)("a", { className: "crisp-breadcrumb-item", href: item.href, children: content })) : ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-breadcrumb-item", onClick: item.onClick, children: content })), !last && (0, jsx_runtime_1.jsx)("span", { className: "crisp-breadcrumb-sep", children: sep })] }, i));
|
|
58
|
+
return ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [last ? ((0, jsx_runtime_1.jsx)("span", { className: "crisp-breadcrumb-item", "aria-current": "page", children: content })) : item.href ? ((0, jsx_runtime_1.jsx)("a", { className: "crisp-breadcrumb-item", href: item.href, onClick: item.onClick, children: content })) : ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "crisp-breadcrumb-item", onClick: item.onClick, children: content })), !last && (0, jsx_runtime_1.jsx)("span", { className: "crisp-breadcrumb-sep", children: sep })] }, i));
|
|
59
59
|
}) }));
|
|
60
60
|
}
|
|
61
61
|
Breadcrumb.displayName = "Breadcrumb";
|
|
@@ -25,6 +25,12 @@ const spec = (0, core_1.defineSpec)({
|
|
|
25
25
|
},
|
|
26
26
|
parts: [
|
|
27
27
|
{ selector: "&:disabled", decls: { opacity: 0.5, cursor: "not-allowed" } },
|
|
28
|
+
// your-moon/crisp#910: seed-design's every Button variant
|
|
29
|
+
// gives press feedback as a `scaleScope: self` micro-interaction, not a
|
|
30
|
+
// shadow/fill change alone (`action-button.yaml`, read in the seed raw
|
|
31
|
+
// dump) -- on top of, not instead of, each intent's own colour-on-press
|
|
32
|
+
// below. Root-level so it applies uniformly across all four intents.
|
|
33
|
+
{ selector: "&:active", decls: { transform: "scale(0.98)" } },
|
|
28
34
|
],
|
|
29
35
|
variants: {
|
|
30
36
|
intent: {
|
|
@@ -38,12 +44,13 @@ const spec = (0, core_1.defineSpec)({
|
|
|
38
44
|
// buttons use white).
|
|
39
45
|
background: tokens_1.contract.bgBrandContrast,
|
|
40
46
|
color: tokens_1.contract.fgOnBrand,
|
|
41
|
-
// crisp#
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
+
// your-moon/crisp#910: seed's brandSolid carries no
|
|
48
|
+
// shadow/ring at all (`action-button.yaml`: `border: none`, no
|
|
49
|
+
// shadow key) -- dropped the coloured ambient drop-shadow and the
|
|
50
|
+
// black-tint inset ring (crisp#494) that were tuned for Attio's
|
|
51
|
+
// own look, per the owner's directive that elevation/control
|
|
52
|
+
// styling now follows seed, not Attio.
|
|
53
|
+
boxShadow: "none",
|
|
47
54
|
},
|
|
48
55
|
// your-moon/crisp#897: a brightness filter, not a second background
|
|
49
56
|
// swap — matches `danger`'s own pattern below. `bgBrandSolidPressed`
|
|
@@ -59,20 +66,29 @@ const spec = (0, core_1.defineSpec)({
|
|
|
59
66
|
},
|
|
60
67
|
neutral: {
|
|
61
68
|
decls: {
|
|
62
|
-
|
|
69
|
+
// your-moon/crisp#910: seed's `neutralWeak` fill is
|
|
70
|
+
// `bg.neutral-weak` (#f3f4f5) at rest, not an opaque white --
|
|
71
|
+
// `bgNeutralWeak` is already this exact hex (no new measurement).
|
|
72
|
+
// No border/shadow in seed's spec either; dropped `e.field`'s
|
|
73
|
+
// 3-layer button-chrome glow for the same reason primary/danger
|
|
74
|
+
// lost theirs.
|
|
75
|
+
background: tokens_1.contract.bgNeutralWeak,
|
|
63
76
|
color: tokens_1.contract.fgPrimary,
|
|
64
|
-
boxShadow:
|
|
77
|
+
boxShadow: "none",
|
|
65
78
|
},
|
|
66
|
-
parts: [
|
|
79
|
+
parts: [
|
|
80
|
+
// seed's neutralWeak "pressed" bg (#eeeff1) is `borderSubtle`'s
|
|
81
|
+
// own already-exact value -- reused, not a fresh literal.
|
|
82
|
+
{ selector: "&:hover", decls: { background: tokens_1.contract.borderSubtle } },
|
|
83
|
+
],
|
|
67
84
|
},
|
|
68
85
|
danger: {
|
|
69
86
|
decls: {
|
|
70
87
|
background: tokens_1.contract.bgDangerSolid,
|
|
71
88
|
color: tokens_1.contract.fgOnBrand,
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(186,37,37,0.20), 0 3px 6px -2px rgba(186,37,37,0.12)",
|
|
89
|
+
// your-moon/crisp#910: same "no shadow at all" call as
|
|
90
|
+
// primary above -- seed's criticalSolid carries no ring either.
|
|
91
|
+
boxShadow: "none",
|
|
76
92
|
},
|
|
77
93
|
parts: [
|
|
78
94
|
{ selector: "&:hover", decls: { filter: "brightness(0.96)" } },
|
|
@@ -82,7 +98,12 @@ const spec = (0, core_1.defineSpec)({
|
|
|
82
98
|
ghost: {
|
|
83
99
|
decls: {
|
|
84
100
|
background: "transparent",
|
|
85
|
-
|
|
101
|
+
// your-moon/crisp#910: seed's `ghost` enabled label/icon
|
|
102
|
+
// colour is `fg.neutral` (full ink), not a de-emphasised muted
|
|
103
|
+
// grey that only darkens on hover -- `action-button.yaml`'s own
|
|
104
|
+
// enabled-state colour table has no separate "muted" step for
|
|
105
|
+
// ghost. Real behaviour change, flagged in HANDOFF/CHANGELOG.
|
|
106
|
+
color: tokens_1.contract.fgPrimary,
|
|
86
107
|
boxShadow: "none",
|
|
87
108
|
},
|
|
88
109
|
parts: [
|
|
@@ -103,6 +124,34 @@ const spec = (0, core_1.defineSpec)({
|
|
|
103
124
|
fontSize: tokens_1.contract.text.md,
|
|
104
125
|
borderRadius: tokens_1.contract.radius.md,
|
|
105
126
|
},
|
|
127
|
+
// crisp#688: Attio's own 20px small button, split out of #682 rather
|
|
128
|
+
// than redefining `sm` -- 72 existing `size="sm"` call sites (sidebar,
|
|
129
|
+
// comments, recordpage, workspacegeneralsettings, personchip,
|
|
130
|
+
// datatable) already rely on sm's 24px, unverified against `xs`'s own
|
|
131
|
+
// context. Box measured live on app.attio.com Home/Tasks ("View all",
|
|
132
|
+
// "Today, <date>", the date-stepper's Previous/Next-day icon
|
|
133
|
+
// buttons): 20px height, 6px radius, 6px inline padding on text
|
|
134
|
+
// buttons (a 20x20 icon-only button centers a 16px icon the same way
|
|
135
|
+
// shape="icon" already does for every other size, so it needs no
|
|
136
|
+
// extra rule), 4px gap between multiple children.
|
|
137
|
+
//
|
|
138
|
+
// The label itself is NOT 14px/#682's tracking -- getComputedStyle on
|
|
139
|
+
// the live button (fonts loaded, DPR 2, zero zoom/transform anywhere
|
|
140
|
+
// in the ancestor chain) reads 10px/regular/15px line-height/normal
|
|
141
|
+
// tracking, independently matching `recordpanel.recipe.ts`'s own
|
|
142
|
+
// "View all" measurement (10px/400) elsewhere in this codebase. 10px
|
|
143
|
+
// sits below the text scale's 11px floor, so it's a literal here, the
|
|
144
|
+
// same as recordpanel's.
|
|
145
|
+
xs: {
|
|
146
|
+
height: "20px",
|
|
147
|
+
paddingInline: tokens_1.contract.space["1.5"],
|
|
148
|
+
fontSize: "10px",
|
|
149
|
+
fontWeight: tokens_1.contract.weight.regular,
|
|
150
|
+
lineHeight: "15px",
|
|
151
|
+
letterSpacing: "normal",
|
|
152
|
+
borderRadius: tokens_1.contract.radius.sm,
|
|
153
|
+
gap: tokens_1.contract.space["1"],
|
|
154
|
+
},
|
|
106
155
|
md: {
|
|
107
156
|
decls: {
|
|
108
157
|
height: "28px",
|
|
@@ -132,7 +181,10 @@ const spec = (0, core_1.defineSpec)({
|
|
|
132
181
|
height: "40px",
|
|
133
182
|
paddingInline: "14px",
|
|
134
183
|
fontSize: tokens_1.contract.text.lg,
|
|
135
|
-
|
|
184
|
+
// your-moon/crisp#910: was a stray literal `10px`, matching neither
|
|
185
|
+
// the token scale nor seed's own large-size radius (`$radius.r3` =
|
|
186
|
+
// 12px, `action-button.yaml`) -- now the actual `xl` token.
|
|
187
|
+
borderRadius: tokens_1.contract.radius.xl,
|
|
136
188
|
},
|
|
137
189
|
},
|
|
138
190
|
shape: {
|
|
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.spec = exports.checkboxRecipe = void 0;
|
|
4
4
|
const core_1 = require("../../core");
|
|
5
5
|
const tokens_1 = require("../../tokens");
|
|
6
|
-
// A 16px square checkbox measured from a record grid:
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// A 16px square checkbox measured from a record grid: brand fill + white
|
|
7
|
+
// check when on. The check is a data-URI SVG background so it renders
|
|
8
|
+
// reliably (input pseudo-content doesn't). Radius (r4) and the real 1px
|
|
9
|
+
// border when empty are seed-design's own (your-moon/crisp#926),
|
|
10
|
+
// not the original 6px/box-shadow-ring measurement.
|
|
9
11
|
const CHECK = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E\")";
|
|
10
12
|
const spec = (0, core_1.defineSpec)({
|
|
11
13
|
name: "checkbox",
|
|
@@ -17,25 +19,32 @@ const spec = (0, core_1.defineSpec)({
|
|
|
17
19
|
margin: 0,
|
|
18
20
|
width: "16px",
|
|
19
21
|
height: "16px",
|
|
20
|
-
border:
|
|
21
|
-
|
|
22
|
+
// your-moon/crisp#926: was `border: none` + a box-shadow
|
|
23
|
+
// inset ring -- seed-design's own checkmark (`checkmark.yaml`) is a real
|
|
24
|
+
// 1px border (`stroke.neutral-weak`, `borderDefault`'s exact value),
|
|
25
|
+
// removed entirely (not hidden via boxShadow:none) when selected, same
|
|
26
|
+
// technique change already made for Input (your-moon/crisp#910).
|
|
27
|
+
border: `1px solid ${tokens_1.contract.borderDefault}`,
|
|
28
|
+
// your-moon/crisp#926: seed's checkmark box corner is
|
|
29
|
+
// `$radius.r1` (4px, `radius.xs`), not the 6px `radius.sm` this shared
|
|
30
|
+
// with Chip's old rounded-rect shape.
|
|
31
|
+
borderRadius: tokens_1.contract.radius.xs,
|
|
22
32
|
background: tokens_1.contract.bgSurface,
|
|
23
|
-
boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${tokens_1.contract.fgPrimary} 9%, transparent)`,
|
|
24
33
|
cursor: "pointer",
|
|
25
|
-
transition: "background-color .12s,
|
|
34
|
+
transition: "background-color .12s, border-color .12s",
|
|
26
35
|
},
|
|
27
36
|
parts: [
|
|
28
37
|
{
|
|
29
38
|
selector: "&:hover",
|
|
30
39
|
decls: {
|
|
31
|
-
|
|
40
|
+
borderColor: `color-mix(in srgb, ${tokens_1.contract.fgPrimary} 30%, transparent)`,
|
|
32
41
|
},
|
|
33
42
|
},
|
|
34
43
|
{
|
|
35
44
|
selector: "&:checked, &:indeterminate",
|
|
36
45
|
decls: {
|
|
37
46
|
background: `${tokens_1.contract.bgBrandSolid} center / 10px no-repeat`,
|
|
38
|
-
|
|
47
|
+
borderColor: "transparent",
|
|
39
48
|
},
|
|
40
49
|
},
|
|
41
50
|
{ selector: "&:checked", decls: { backgroundImage: CHECK } },
|
|
@@ -53,6 +62,49 @@ const spec = (0, core_1.defineSpec)({
|
|
|
53
62
|
outlineOffset: "1px",
|
|
54
63
|
},
|
|
55
64
|
},
|
|
65
|
+
// your-moon/crisp#963: was no `:disabled` styling at all
|
|
66
|
+
// -- seed-design's own checkmark spec (`checkmark.yaml`) treats disabled
|
|
67
|
+
// as its own recolor, not a blanket opacity dim: fill `bg.disabled`
|
|
68
|
+
// (crisp's already-exact `bgNeutralWeak`, #f3f4f5), border
|
|
69
|
+
// `stroke.neutral-muted` (crisp's already-exact `borderSubtle`, applied
|
|
70
|
+
// here as the disabled border colour rather than its usual ring role).
|
|
71
|
+
// "disabled (any state)" per seed -- checked/indeterminate get the same
|
|
72
|
+
// muted fill/border, not the brand fill, hence the compound selectors
|
|
73
|
+
// below outranking the plain `:checked`/`:indeterminate` rule above.
|
|
74
|
+
{
|
|
75
|
+
selector: "&:disabled",
|
|
76
|
+
decls: {
|
|
77
|
+
background: tokens_1.contract.bgNeutralWeak,
|
|
78
|
+
borderColor: tokens_1.contract.borderSubtle,
|
|
79
|
+
cursor: "not-allowed",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
// Higher specificity than the plain `&:checked, &:indeterminate` rule
|
|
84
|
+
// above (two pseudo-classes vs one), so this wins regardless of
|
|
85
|
+
// declaration order. Deliberately keeps the existing white check icon
|
|
86
|
+
// rather than recolouring it to seed's `fg.disabled` -- that glyph is
|
|
87
|
+
// baked into a static SVG data-URI with no theme-aware way to retint
|
|
88
|
+
// it without switching techniques entirely (mask + a separate colour
|
|
89
|
+
// layer), and white still reads clearly against the muted grey fill.
|
|
90
|
+
selector: "&:checked:disabled, &:indeterminate:disabled",
|
|
91
|
+
decls: {
|
|
92
|
+
background: `${tokens_1.contract.bgNeutralWeak} center / 10px no-repeat`,
|
|
93
|
+
borderColor: tokens_1.contract.borderSubtle,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{ selector: "&:checked:disabled", decls: { backgroundImage: CHECK } },
|
|
97
|
+
{
|
|
98
|
+
// The `background` shorthand just above resets `background-image` to
|
|
99
|
+
// `none` on every property it doesn't restate -- without this, a
|
|
100
|
+
// disabled indeterminate checkbox would show the muted fill but lose
|
|
101
|
+
// its dash entirely.
|
|
102
|
+
selector: "&:indeterminate:disabled",
|
|
103
|
+
decls: {
|
|
104
|
+
backgroundImage: `linear-gradient(${tokens_1.contract.fgOnBrand}, ${tokens_1.contract.fgOnBrand})`,
|
|
105
|
+
backgroundSize: "8px 2px",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
56
108
|
],
|
|
57
109
|
});
|
|
58
110
|
exports.spec = spec;
|
|
@@ -51,9 +51,21 @@ const chip_recipe_1 = require("./chip.recipe");
|
|
|
51
51
|
* an inline ×) — so `Chip` has no `onRemove`/remove button yet. Add one once
|
|
52
52
|
* that surface can be measured; don't guess the icon, its hit target, or its
|
|
53
53
|
* spacing from the label.
|
|
54
|
+
*
|
|
55
|
+
* `appearance` (`"filled"` default | `"outline"`) and `selected` separate
|
|
56
|
+
* three visual roles crisp/#907's study found conflated: a filled chip reads
|
|
57
|
+
* as a status/value (not clickable), an outline chip reads as actionable (a
|
|
58
|
+
* tag or filter you can tap), and `selected` overrides either to a dark fill
|
|
59
|
+
* once tapped — see `chip.recipe.ts` for the structural reference.
|
|
54
60
|
*/
|
|
55
|
-
exports.Chip = React.forwardRef(({ tone, truncate, className, asChild, children, ...props }, ref) => {
|
|
61
|
+
exports.Chip = React.forwardRef(({ tone, truncate, appearance, selected, className, asChild, children, ...props }, ref) => {
|
|
56
62
|
const content = truncate && !asChild && typeof children === "string" ? ((0, jsx_runtime_1.jsx)("span", { className: "crisp-chip-label", children: children })) : (children);
|
|
57
|
-
return ((0, jsx_runtime_1.jsx)(core_1.Primitive.span, { ref: ref, asChild: asChild, className: (0, chip_recipe_1.chipRecipe)({
|
|
63
|
+
return ((0, jsx_runtime_1.jsx)(core_1.Primitive.span, { ref: ref, asChild: asChild, className: (0, chip_recipe_1.chipRecipe)({
|
|
64
|
+
tone,
|
|
65
|
+
truncate,
|
|
66
|
+
appearance,
|
|
67
|
+
selected,
|
|
68
|
+
className,
|
|
69
|
+
}), ...props, children: content }));
|
|
58
70
|
});
|
|
59
71
|
exports.Chip.displayName = "Chip";
|
|
@@ -12,6 +12,15 @@ const tokens_1 = require("../../tokens");
|
|
|
12
12
|
// can't be reused verbatim here — Chip's root IS the styled element, not a
|
|
13
13
|
// wrapper around one. The values below are transcribed from recordTagCss,
|
|
14
14
|
// not re-measured; keep the two in sync by hand if either changes.
|
|
15
|
+
//
|
|
16
|
+
// your-moon/crisp#919: `radius.chip` itself (tokens/scale.ts) moved
|
|
17
|
+
// from Attio's measured 7px to a pill (999px), matching seed-design's own
|
|
18
|
+
// `chip.yaml` (always a pill, no size-based radius step at all). Every
|
|
19
|
+
// consumer sharing this one token — DataTable/RecordPage/RecordsTable/
|
|
20
|
+
// MultiSelect's tag & mention chips, TableToolbar/DatePickerField's date
|
|
21
|
+
// presets — goes pill-shaped together from this single token change, not a
|
|
22
|
+
// per-file edit; that's the whole reason those rules keep re-declaring
|
|
23
|
+
// `border-radius: ${c.radius.chip}` instead of a literal.
|
|
15
24
|
const ring = (v, pct) => `inset 0 0 0 1px color-mix(in srgb, ${v} ${pct}%, transparent)`;
|
|
16
25
|
const soft = (v, pct) => `color-mix(in srgb, ${v} ${pct}%, transparent)`;
|
|
17
26
|
const onFg = (v, pct) => `color-mix(in srgb, ${v} ${pct}%, ${tokens_1.contract.fgPrimary})`;
|
|
@@ -67,7 +76,9 @@ const spec = (0, core_1.defineSpec)({
|
|
|
67
76
|
selector: "& .crisp-chip-label",
|
|
68
77
|
decls: {
|
|
69
78
|
minWidth: 0,
|
|
70
|
-
|
|
79
|
+
// #719: `clip`, not `hidden` -- immune to a programmatic
|
|
80
|
+
// `scrollLeft` assignment; renders the ellipsis identically.
|
|
81
|
+
overflow: "clip",
|
|
71
82
|
textOverflow: "ellipsis",
|
|
72
83
|
whiteSpace: "nowrap",
|
|
73
84
|
display: "block",
|
|
@@ -119,8 +130,67 @@ const spec = (0, core_1.defineSpec)({
|
|
|
119
130
|
boxShadow: ring(tokens_1.contract.bgOrange, 30),
|
|
120
131
|
},
|
|
121
132
|
},
|
|
133
|
+
// your-moon/crisp#907: a three-state read (actionable / informational /
|
|
134
|
+
// selected), the same shape as seed-design's own `chip.yaml` (`variant:
|
|
135
|
+
// solid|outlineStrong|outlineWeak`, each with a `selected` state) --
|
|
136
|
+
// structural reference only, not Naver/Kakao's colours (the study only
|
|
137
|
+
// supplied the pattern: outline reads as tappable, filled reads as
|
|
138
|
+
// status, dark fill reads as selected). `outline` only clears
|
|
139
|
+
// `background`, keeping the `tone`'s own `color`/`boxShadow` ring --
|
|
140
|
+
// SEED's own spec keeps `label.color` identical between `solid` and
|
|
141
|
+
// `outlineWeak`/`outlineStrong`, so the ring is the only thing that
|
|
142
|
+
// changes. Declared after `tone` so its rule wins the cascade at equal
|
|
143
|
+
// specificity (`core/resolve.ts` emits variant blocks in declaration
|
|
144
|
+
// order; see `build/generate-recipes.mjs`).
|
|
145
|
+
appearance: {
|
|
146
|
+
filled: {},
|
|
147
|
+
outline: { background: "transparent" },
|
|
148
|
+
},
|
|
149
|
+
// Overrides `tone`+`appearance` entirely to crisp's own dark-inverted
|
|
150
|
+
// pair (`bgNeutralInverted`/`fgOnNeutralInverted`, already shipped for
|
|
151
|
+
// `Snackbar` #911) -- SEED's `solid`/`outlineStrong` selected state, not
|
|
152
|
+
// Daum's `rgb(44,46,51)` (crisp's own token is `#2a3038`, close but
|
|
153
|
+
// deliberately not copied). Declared last so it always wins regardless
|
|
154
|
+
// of `tone`/`appearance`. Simplified from SEED, which gives
|
|
155
|
+
// `outlineWeak` a DIFFERENT, lighter selected treatment (a stronger
|
|
156
|
+
// stroke + weak fill, not a full inversion) -- one consistent dark-fill
|
|
157
|
+
// "selected" reads clearer across every tone than three different
|
|
158
|
+
// selected looks, and matches what #907 actually asked for.
|
|
159
|
+
selected: {
|
|
160
|
+
true: {
|
|
161
|
+
background: tokens_1.contract.bgNeutralInverted,
|
|
162
|
+
color: tokens_1.contract.fgOnNeutralInverted,
|
|
163
|
+
boxShadow: "none",
|
|
164
|
+
},
|
|
165
|
+
false: {},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
// Team-lead review of #955's screenshot: the neutral tone's outline ring
|
|
169
|
+
// reuses `borderSubtle` (`#eeeff1`, meant for hairline dividers under a
|
|
170
|
+
// fill, not a standalone edge) -- on outline's transparent background
|
|
171
|
+
// it's nearly invisible, defeating the "outline reads as tappable" point
|
|
172
|
+
// of the appearance itself. Every other tone's ring is already a 30%
|
|
173
|
+
// tint of a saturated colour, visible enough on white; only neutral needs
|
|
174
|
+
// the fix. Matches `Input`'s own border token, per the reviewer's note.
|
|
175
|
+
// `selected: false` keeps this from re-drawing a border under `selected`'s
|
|
176
|
+
// dark fill -- compound rules emit after every plain variant rule
|
|
177
|
+
// (including `selected`'s own), so without this an outline+selected+
|
|
178
|
+
// neutral chip would get its border back on top of `selected`'s
|
|
179
|
+
// `boxShadow: "none"`.
|
|
180
|
+
compoundVariants: [
|
|
181
|
+
{
|
|
182
|
+
tone: "neutral",
|
|
183
|
+
appearance: "outline",
|
|
184
|
+
selected: false,
|
|
185
|
+
decls: { boxShadow: `inset 0 0 0 1px ${tokens_1.contract.borderDefault}` },
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
defaultVariants: {
|
|
189
|
+
tone: "neutral",
|
|
190
|
+
truncate: false,
|
|
191
|
+
appearance: "filled",
|
|
192
|
+
selected: false,
|
|
122
193
|
},
|
|
123
|
-
defaultVariants: { tone: "neutral", truncate: false },
|
|
124
194
|
});
|
|
125
195
|
exports.spec = spec;
|
|
126
196
|
const config = (0, core_1.specToRecipe)(spec);
|