@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineSpec, resolveRecipe, specToRecipe } from "../../core/index.js";
|
|
2
|
-
import { contract as c
|
|
2
|
+
import { contract as c } from "../../tokens/index.js";
|
|
3
3
|
const spec = defineSpec({
|
|
4
4
|
name: "button",
|
|
5
5
|
base: {
|
|
@@ -22,6 +22,12 @@ const spec = defineSpec({
|
|
|
22
22
|
},
|
|
23
23
|
parts: [
|
|
24
24
|
{ selector: "&:disabled", decls: { opacity: 0.5, cursor: "not-allowed" } },
|
|
25
|
+
// your-moon/crisp#910: seed-design's every Button variant
|
|
26
|
+
// gives press feedback as a `scaleScope: self` micro-interaction, not a
|
|
27
|
+
// shadow/fill change alone (`action-button.yaml`, read in the seed raw
|
|
28
|
+
// dump) -- on top of, not instead of, each intent's own colour-on-press
|
|
29
|
+
// below. Root-level so it applies uniformly across all four intents.
|
|
30
|
+
{ selector: "&:active", decls: { transform: "scale(0.98)" } },
|
|
25
31
|
],
|
|
26
32
|
variants: {
|
|
27
33
|
intent: {
|
|
@@ -35,12 +41,13 @@ const spec = defineSpec({
|
|
|
35
41
|
// buttons use white).
|
|
36
42
|
background: c.bgBrandContrast,
|
|
37
43
|
color: c.fgOnBrand,
|
|
38
|
-
// crisp#
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
+
// your-moon/crisp#910: seed's brandSolid carries no
|
|
45
|
+
// shadow/ring at all (`action-button.yaml`: `border: none`, no
|
|
46
|
+
// shadow key) -- dropped the coloured ambient drop-shadow and the
|
|
47
|
+
// black-tint inset ring (crisp#494) that were tuned for Attio's
|
|
48
|
+
// own look, per the owner's directive that elevation/control
|
|
49
|
+
// styling now follows seed, not Attio.
|
|
50
|
+
boxShadow: "none",
|
|
44
51
|
},
|
|
45
52
|
// your-moon/crisp#897: a brightness filter, not a second background
|
|
46
53
|
// swap — matches `danger`'s own pattern below. `bgBrandSolidPressed`
|
|
@@ -56,20 +63,29 @@ const spec = defineSpec({
|
|
|
56
63
|
},
|
|
57
64
|
neutral: {
|
|
58
65
|
decls: {
|
|
59
|
-
|
|
66
|
+
// your-moon/crisp#910: seed's `neutralWeak` fill is
|
|
67
|
+
// `bg.neutral-weak` (#f3f4f5) at rest, not an opaque white --
|
|
68
|
+
// `bgNeutralWeak` is already this exact hex (no new measurement).
|
|
69
|
+
// No border/shadow in seed's spec either; dropped `e.field`'s
|
|
70
|
+
// 3-layer button-chrome glow for the same reason primary/danger
|
|
71
|
+
// lost theirs.
|
|
72
|
+
background: c.bgNeutralWeak,
|
|
60
73
|
color: c.fgPrimary,
|
|
61
|
-
boxShadow:
|
|
74
|
+
boxShadow: "none",
|
|
62
75
|
},
|
|
63
|
-
parts: [
|
|
76
|
+
parts: [
|
|
77
|
+
// seed's neutralWeak "pressed" bg (#eeeff1) is `borderSubtle`'s
|
|
78
|
+
// own already-exact value -- reused, not a fresh literal.
|
|
79
|
+
{ selector: "&:hover", decls: { background: c.borderSubtle } },
|
|
80
|
+
],
|
|
64
81
|
},
|
|
65
82
|
danger: {
|
|
66
83
|
decls: {
|
|
67
84
|
background: c.bgDangerSolid,
|
|
68
85
|
color: c.fgOnBrand,
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
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)",
|
|
86
|
+
// your-moon/crisp#910: same "no shadow at all" call as
|
|
87
|
+
// primary above -- seed's criticalSolid carries no ring either.
|
|
88
|
+
boxShadow: "none",
|
|
73
89
|
},
|
|
74
90
|
parts: [
|
|
75
91
|
{ selector: "&:hover", decls: { filter: "brightness(0.96)" } },
|
|
@@ -79,7 +95,12 @@ const spec = defineSpec({
|
|
|
79
95
|
ghost: {
|
|
80
96
|
decls: {
|
|
81
97
|
background: "transparent",
|
|
82
|
-
|
|
98
|
+
// your-moon/crisp#910: seed's `ghost` enabled label/icon
|
|
99
|
+
// colour is `fg.neutral` (full ink), not a de-emphasised muted
|
|
100
|
+
// grey that only darkens on hover -- `action-button.yaml`'s own
|
|
101
|
+
// enabled-state colour table has no separate "muted" step for
|
|
102
|
+
// ghost. Real behaviour change, flagged in HANDOFF/CHANGELOG.
|
|
103
|
+
color: c.fgPrimary,
|
|
83
104
|
boxShadow: "none",
|
|
84
105
|
},
|
|
85
106
|
parts: [
|
|
@@ -100,6 +121,34 @@ const spec = defineSpec({
|
|
|
100
121
|
fontSize: c.text.md,
|
|
101
122
|
borderRadius: c.radius.md,
|
|
102
123
|
},
|
|
124
|
+
// crisp#688: Attio's own 20px small button, split out of #682 rather
|
|
125
|
+
// than redefining `sm` -- 72 existing `size="sm"` call sites (sidebar,
|
|
126
|
+
// comments, recordpage, workspacegeneralsettings, personchip,
|
|
127
|
+
// datatable) already rely on sm's 24px, unverified against `xs`'s own
|
|
128
|
+
// context. Box measured live on app.attio.com Home/Tasks ("View all",
|
|
129
|
+
// "Today, <date>", the date-stepper's Previous/Next-day icon
|
|
130
|
+
// buttons): 20px height, 6px radius, 6px inline padding on text
|
|
131
|
+
// buttons (a 20x20 icon-only button centers a 16px icon the same way
|
|
132
|
+
// shape="icon" already does for every other size, so it needs no
|
|
133
|
+
// extra rule), 4px gap between multiple children.
|
|
134
|
+
//
|
|
135
|
+
// The label itself is NOT 14px/#682's tracking -- getComputedStyle on
|
|
136
|
+
// the live button (fonts loaded, DPR 2, zero zoom/transform anywhere
|
|
137
|
+
// in the ancestor chain) reads 10px/regular/15px line-height/normal
|
|
138
|
+
// tracking, independently matching `recordpanel.recipe.ts`'s own
|
|
139
|
+
// "View all" measurement (10px/400) elsewhere in this codebase. 10px
|
|
140
|
+
// sits below the text scale's 11px floor, so it's a literal here, the
|
|
141
|
+
// same as recordpanel's.
|
|
142
|
+
xs: {
|
|
143
|
+
height: "20px",
|
|
144
|
+
paddingInline: c.space["1.5"],
|
|
145
|
+
fontSize: "10px",
|
|
146
|
+
fontWeight: c.weight.regular,
|
|
147
|
+
lineHeight: "15px",
|
|
148
|
+
letterSpacing: "normal",
|
|
149
|
+
borderRadius: c.radius.sm,
|
|
150
|
+
gap: c.space["1"],
|
|
151
|
+
},
|
|
103
152
|
md: {
|
|
104
153
|
decls: {
|
|
105
154
|
height: "28px",
|
|
@@ -129,7 +178,10 @@ const spec = defineSpec({
|
|
|
129
178
|
height: "40px",
|
|
130
179
|
paddingInline: "14px",
|
|
131
180
|
fontSize: c.text.lg,
|
|
132
|
-
|
|
181
|
+
// your-moon/crisp#910: was a stray literal `10px`, matching neither
|
|
182
|
+
// the token scale nor seed's own large-size radius (`$radius.r3` =
|
|
183
|
+
// 12px, `action-button.yaml`) -- now the actual `xl` token.
|
|
184
|
+
borderRadius: c.radius.xl,
|
|
133
185
|
},
|
|
134
186
|
},
|
|
135
187
|
shape: {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { defineSpec, resolveRecipe, specToRecipe } from "../../core/index.js";
|
|
2
2
|
import { contract as c } from "../../tokens/index.js";
|
|
3
|
-
// A 16px square checkbox measured from a record grid:
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// A 16px square checkbox measured from a record grid: brand fill + white
|
|
4
|
+
// check when on. The check is a data-URI SVG background so it renders
|
|
5
|
+
// reliably (input pseudo-content doesn't). Radius (r4) and the real 1px
|
|
6
|
+
// border when empty are seed-design's own (your-moon/crisp#926),
|
|
7
|
+
// not the original 6px/box-shadow-ring measurement.
|
|
6
8
|
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\")";
|
|
7
9
|
const spec = defineSpec({
|
|
8
10
|
name: "checkbox",
|
|
@@ -14,25 +16,32 @@ const spec = defineSpec({
|
|
|
14
16
|
margin: 0,
|
|
15
17
|
width: "16px",
|
|
16
18
|
height: "16px",
|
|
17
|
-
border:
|
|
18
|
-
|
|
19
|
+
// your-moon/crisp#926: was `border: none` + a box-shadow
|
|
20
|
+
// inset ring -- seed-design's own checkmark (`checkmark.yaml`) is a real
|
|
21
|
+
// 1px border (`stroke.neutral-weak`, `borderDefault`'s exact value),
|
|
22
|
+
// removed entirely (not hidden via boxShadow:none) when selected, same
|
|
23
|
+
// technique change already made for Input (your-moon/crisp#910).
|
|
24
|
+
border: `1px solid ${c.borderDefault}`,
|
|
25
|
+
// your-moon/crisp#926: seed's checkmark box corner is
|
|
26
|
+
// `$radius.r1` (4px, `radius.xs`), not the 6px `radius.sm` this shared
|
|
27
|
+
// with Chip's old rounded-rect shape.
|
|
28
|
+
borderRadius: c.radius.xs,
|
|
19
29
|
background: c.bgSurface,
|
|
20
|
-
boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${c.fgPrimary} 9%, transparent)`,
|
|
21
30
|
cursor: "pointer",
|
|
22
|
-
transition: "background-color .12s,
|
|
31
|
+
transition: "background-color .12s, border-color .12s",
|
|
23
32
|
},
|
|
24
33
|
parts: [
|
|
25
34
|
{
|
|
26
35
|
selector: "&:hover",
|
|
27
36
|
decls: {
|
|
28
|
-
|
|
37
|
+
borderColor: `color-mix(in srgb, ${c.fgPrimary} 30%, transparent)`,
|
|
29
38
|
},
|
|
30
39
|
},
|
|
31
40
|
{
|
|
32
41
|
selector: "&:checked, &:indeterminate",
|
|
33
42
|
decls: {
|
|
34
43
|
background: `${c.bgBrandSolid} center / 10px no-repeat`,
|
|
35
|
-
|
|
44
|
+
borderColor: "transparent",
|
|
36
45
|
},
|
|
37
46
|
},
|
|
38
47
|
{ selector: "&:checked", decls: { backgroundImage: CHECK } },
|
|
@@ -50,6 +59,49 @@ const spec = defineSpec({
|
|
|
50
59
|
outlineOffset: "1px",
|
|
51
60
|
},
|
|
52
61
|
},
|
|
62
|
+
// your-moon/crisp#963: was no `:disabled` styling at all
|
|
63
|
+
// -- seed-design's own checkmark spec (`checkmark.yaml`) treats disabled
|
|
64
|
+
// as its own recolor, not a blanket opacity dim: fill `bg.disabled`
|
|
65
|
+
// (crisp's already-exact `bgNeutralWeak`, #f3f4f5), border
|
|
66
|
+
// `stroke.neutral-muted` (crisp's already-exact `borderSubtle`, applied
|
|
67
|
+
// here as the disabled border colour rather than its usual ring role).
|
|
68
|
+
// "disabled (any state)" per seed -- checked/indeterminate get the same
|
|
69
|
+
// muted fill/border, not the brand fill, hence the compound selectors
|
|
70
|
+
// below outranking the plain `:checked`/`:indeterminate` rule above.
|
|
71
|
+
{
|
|
72
|
+
selector: "&:disabled",
|
|
73
|
+
decls: {
|
|
74
|
+
background: c.bgNeutralWeak,
|
|
75
|
+
borderColor: c.borderSubtle,
|
|
76
|
+
cursor: "not-allowed",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
// Higher specificity than the plain `&:checked, &:indeterminate` rule
|
|
81
|
+
// above (two pseudo-classes vs one), so this wins regardless of
|
|
82
|
+
// declaration order. Deliberately keeps the existing white check icon
|
|
83
|
+
// rather than recolouring it to seed's `fg.disabled` -- that glyph is
|
|
84
|
+
// baked into a static SVG data-URI with no theme-aware way to retint
|
|
85
|
+
// it without switching techniques entirely (mask + a separate colour
|
|
86
|
+
// layer), and white still reads clearly against the muted grey fill.
|
|
87
|
+
selector: "&:checked:disabled, &:indeterminate:disabled",
|
|
88
|
+
decls: {
|
|
89
|
+
background: `${c.bgNeutralWeak} center / 10px no-repeat`,
|
|
90
|
+
borderColor: c.borderSubtle,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{ selector: "&:checked:disabled", decls: { backgroundImage: CHECK } },
|
|
94
|
+
{
|
|
95
|
+
// The `background` shorthand just above resets `background-image` to
|
|
96
|
+
// `none` on every property it doesn't restate -- without this, a
|
|
97
|
+
// disabled indeterminate checkbox would show the muted fill but lose
|
|
98
|
+
// its dash entirely.
|
|
99
|
+
selector: "&:indeterminate:disabled",
|
|
100
|
+
decls: {
|
|
101
|
+
backgroundImage: `linear-gradient(${c.fgOnBrand}, ${c.fgOnBrand})`,
|
|
102
|
+
backgroundSize: "8px 2px",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
53
105
|
],
|
|
54
106
|
});
|
|
55
107
|
const config = specToRecipe(spec);
|
|
@@ -15,9 +15,21 @@ import { chipRecipe } from "./chip.recipe.js";
|
|
|
15
15
|
* an inline ×) — so `Chip` has no `onRemove`/remove button yet. Add one once
|
|
16
16
|
* that surface can be measured; don't guess the icon, its hit target, or its
|
|
17
17
|
* spacing from the label.
|
|
18
|
+
*
|
|
19
|
+
* `appearance` (`"filled"` default | `"outline"`) and `selected` separate
|
|
20
|
+
* three visual roles crisp/#907's study found conflated: a filled chip reads
|
|
21
|
+
* as a status/value (not clickable), an outline chip reads as actionable (a
|
|
22
|
+
* tag or filter you can tap), and `selected` overrides either to a dark fill
|
|
23
|
+
* once tapped — see `chip.recipe.ts` for the structural reference.
|
|
18
24
|
*/
|
|
19
|
-
export const Chip = React.forwardRef(({ tone, truncate, className, asChild, children, ...props }, ref) => {
|
|
25
|
+
export const Chip = React.forwardRef(({ tone, truncate, appearance, selected, className, asChild, children, ...props }, ref) => {
|
|
20
26
|
const content = truncate && !asChild && typeof children === "string" ? (_jsx("span", { className: "crisp-chip-label", children: children })) : (children);
|
|
21
|
-
return (_jsx(Primitive.span, { ref: ref, asChild: asChild, className: chipRecipe({
|
|
27
|
+
return (_jsx(Primitive.span, { ref: ref, asChild: asChild, className: chipRecipe({
|
|
28
|
+
tone,
|
|
29
|
+
truncate,
|
|
30
|
+
appearance,
|
|
31
|
+
selected,
|
|
32
|
+
className,
|
|
33
|
+
}), ...props, children: content }));
|
|
22
34
|
});
|
|
23
35
|
Chip.displayName = "Chip";
|
|
@@ -9,6 +9,15 @@ import { contract as c } from "../../tokens/index.js";
|
|
|
9
9
|
// can't be reused verbatim here — Chip's root IS the styled element, not a
|
|
10
10
|
// wrapper around one. The values below are transcribed from recordTagCss,
|
|
11
11
|
// not re-measured; keep the two in sync by hand if either changes.
|
|
12
|
+
//
|
|
13
|
+
// your-moon/crisp#919: `radius.chip` itself (tokens/scale.ts) moved
|
|
14
|
+
// from Attio's measured 7px to a pill (999px), matching seed-design's own
|
|
15
|
+
// `chip.yaml` (always a pill, no size-based radius step at all). Every
|
|
16
|
+
// consumer sharing this one token — DataTable/RecordPage/RecordsTable/
|
|
17
|
+
// MultiSelect's tag & mention chips, TableToolbar/DatePickerField's date
|
|
18
|
+
// presets — goes pill-shaped together from this single token change, not a
|
|
19
|
+
// per-file edit; that's the whole reason those rules keep re-declaring
|
|
20
|
+
// `border-radius: ${c.radius.chip}` instead of a literal.
|
|
12
21
|
const ring = (v, pct) => `inset 0 0 0 1px color-mix(in srgb, ${v} ${pct}%, transparent)`;
|
|
13
22
|
const soft = (v, pct) => `color-mix(in srgb, ${v} ${pct}%, transparent)`;
|
|
14
23
|
const onFg = (v, pct) => `color-mix(in srgb, ${v} ${pct}%, ${c.fgPrimary})`;
|
|
@@ -64,7 +73,9 @@ const spec = defineSpec({
|
|
|
64
73
|
selector: "& .crisp-chip-label",
|
|
65
74
|
decls: {
|
|
66
75
|
minWidth: 0,
|
|
67
|
-
|
|
76
|
+
// #719: `clip`, not `hidden` -- immune to a programmatic
|
|
77
|
+
// `scrollLeft` assignment; renders the ellipsis identically.
|
|
78
|
+
overflow: "clip",
|
|
68
79
|
textOverflow: "ellipsis",
|
|
69
80
|
whiteSpace: "nowrap",
|
|
70
81
|
display: "block",
|
|
@@ -116,8 +127,67 @@ const spec = defineSpec({
|
|
|
116
127
|
boxShadow: ring(c.bgOrange, 30),
|
|
117
128
|
},
|
|
118
129
|
},
|
|
130
|
+
// your-moon/crisp#907: a three-state read (actionable / informational /
|
|
131
|
+
// selected), the same shape as seed-design's own `chip.yaml` (`variant:
|
|
132
|
+
// solid|outlineStrong|outlineWeak`, each with a `selected` state) --
|
|
133
|
+
// structural reference only, not Naver/Kakao's colours (the study only
|
|
134
|
+
// supplied the pattern: outline reads as tappable, filled reads as
|
|
135
|
+
// status, dark fill reads as selected). `outline` only clears
|
|
136
|
+
// `background`, keeping the `tone`'s own `color`/`boxShadow` ring --
|
|
137
|
+
// SEED's own spec keeps `label.color` identical between `solid` and
|
|
138
|
+
// `outlineWeak`/`outlineStrong`, so the ring is the only thing that
|
|
139
|
+
// changes. Declared after `tone` so its rule wins the cascade at equal
|
|
140
|
+
// specificity (`core/resolve.ts` emits variant blocks in declaration
|
|
141
|
+
// order; see `build/generate-recipes.mjs`).
|
|
142
|
+
appearance: {
|
|
143
|
+
filled: {},
|
|
144
|
+
outline: { background: "transparent" },
|
|
145
|
+
},
|
|
146
|
+
// Overrides `tone`+`appearance` entirely to crisp's own dark-inverted
|
|
147
|
+
// pair (`bgNeutralInverted`/`fgOnNeutralInverted`, already shipped for
|
|
148
|
+
// `Snackbar` #911) -- SEED's `solid`/`outlineStrong` selected state, not
|
|
149
|
+
// Daum's `rgb(44,46,51)` (crisp's own token is `#2a3038`, close but
|
|
150
|
+
// deliberately not copied). Declared last so it always wins regardless
|
|
151
|
+
// of `tone`/`appearance`. Simplified from SEED, which gives
|
|
152
|
+
// `outlineWeak` a DIFFERENT, lighter selected treatment (a stronger
|
|
153
|
+
// stroke + weak fill, not a full inversion) -- one consistent dark-fill
|
|
154
|
+
// "selected" reads clearer across every tone than three different
|
|
155
|
+
// selected looks, and matches what #907 actually asked for.
|
|
156
|
+
selected: {
|
|
157
|
+
true: {
|
|
158
|
+
background: c.bgNeutralInverted,
|
|
159
|
+
color: c.fgOnNeutralInverted,
|
|
160
|
+
boxShadow: "none",
|
|
161
|
+
},
|
|
162
|
+
false: {},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
// Team-lead review of #955's screenshot: the neutral tone's outline ring
|
|
166
|
+
// reuses `borderSubtle` (`#eeeff1`, meant for hairline dividers under a
|
|
167
|
+
// fill, not a standalone edge) -- on outline's transparent background
|
|
168
|
+
// it's nearly invisible, defeating the "outline reads as tappable" point
|
|
169
|
+
// of the appearance itself. Every other tone's ring is already a 30%
|
|
170
|
+
// tint of a saturated colour, visible enough on white; only neutral needs
|
|
171
|
+
// the fix. Matches `Input`'s own border token, per the reviewer's note.
|
|
172
|
+
// `selected: false` keeps this from re-drawing a border under `selected`'s
|
|
173
|
+
// dark fill -- compound rules emit after every plain variant rule
|
|
174
|
+
// (including `selected`'s own), so without this an outline+selected+
|
|
175
|
+
// neutral chip would get its border back on top of `selected`'s
|
|
176
|
+
// `boxShadow: "none"`.
|
|
177
|
+
compoundVariants: [
|
|
178
|
+
{
|
|
179
|
+
tone: "neutral",
|
|
180
|
+
appearance: "outline",
|
|
181
|
+
selected: false,
|
|
182
|
+
decls: { boxShadow: `inset 0 0 0 1px ${c.borderDefault}` },
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
defaultVariants: {
|
|
186
|
+
tone: "neutral",
|
|
187
|
+
truncate: false,
|
|
188
|
+
appearance: "filled",
|
|
189
|
+
selected: false,
|
|
119
190
|
},
|
|
120
|
-
defaultVariants: { tone: "neutral", truncate: false },
|
|
121
191
|
});
|
|
122
192
|
const config = specToRecipe(spec);
|
|
123
193
|
export const chipRecipe = Object.assign(resolveRecipe(config), { config });
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Primitive } from "../../core/index.js";
|
|
4
|
+
import { chipgroupRecipe } from "./chipgroup.recipe.js";
|
|
5
|
+
/**
|
|
6
|
+
* A single-line, horizontally-scrolling row of `Chip`s (or anything else),
|
|
7
|
+
* with scroll-snap — for a filter/status row that would otherwise wrap onto
|
|
8
|
+
* a second line once it runs out of width (crisp#908). Every child snaps to
|
|
9
|
+
* the row's start edge and never shrinks, so scrolling always lands a chip
|
|
10
|
+
* flush against the left edge rather than mid-chip.
|
|
11
|
+
*/
|
|
12
|
+
export const ChipGroup = React.forwardRef(({ className, asChild, ...props }, ref) => {
|
|
13
|
+
return (_jsx(Primitive.div, { ref: ref, asChild: asChild, role: "group", className: chipgroupRecipe({ className }), ...props }));
|
|
14
|
+
});
|
|
15
|
+
ChipGroup.displayName = "ChipGroup";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
2
|
+
import { contract as c } from "../../tokens/index.js";
|
|
3
|
+
// your-moon/crisp#908: a horizontally-scrolling, single-line row for a set of
|
|
4
|
+
// `Chip`s -- Naver/Kakao both solve "many filter/status chips" this way
|
|
5
|
+
// (docs/study/korean/: Naver home `comp_snap_list`, `scroll-snap-type: x
|
|
6
|
+
// mandatory`; Daum `UL.grid_xscroll`, native overflow with no snap). crisp
|
|
7
|
+
// had no equivalent: a consumer's own flex row wraps chips onto a second
|
|
8
|
+
// line once they run out of horizontal space, which breaks the one-line
|
|
9
|
+
// table-header density Attio parity is built on (GRC's own toolbar filter
|
|
10
|
+
// row and record tabs, per the issue). No new visual values -- the gap
|
|
11
|
+
// between chips reuses `Chip`'s own measured 3px inter-child gap
|
|
12
|
+
// (chip.recipe.ts's `gap: "3px"` comment), and the scrollbar is hidden the
|
|
13
|
+
// same way `WheelPicker`'s already-shipped scroll column does
|
|
14
|
+
// (`scrollbar-width: none` + the `-webkit-scrollbar` pseudo), not a new
|
|
15
|
+
// pattern invented for this component.
|
|
16
|
+
const config = defineRecipe({
|
|
17
|
+
name: "chipgroup",
|
|
18
|
+
base: `
|
|
19
|
+
display: flex; flex-wrap: nowrap; align-items: center; gap: ${c.space["1.5"]};
|
|
20
|
+
overflow-x: auto; overscroll-behavior-x: contain;
|
|
21
|
+
scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
|
|
22
|
+
scrollbar-width: none; -ms-overflow-style: none;
|
|
23
|
+
&::-webkit-scrollbar { display: none; }
|
|
24
|
+
& > * { flex-shrink: 0; scroll-snap-align: start; }
|
|
25
|
+
`,
|
|
26
|
+
variants: {},
|
|
27
|
+
defaultVariants: {},
|
|
28
|
+
compoundVariants: [],
|
|
29
|
+
});
|
|
30
|
+
export const chipgroupRecipe = Object.assign(resolveRecipe(config), {
|
|
31
|
+
config,
|
|
32
|
+
});
|
|
33
|
+
export default config;
|
|
@@ -369,7 +369,11 @@ function renderTyped(col, value, avatarTone, row, display, locale = "en-US", ope
|
|
|
369
369
|
const e = display ? { ...raw, name: display } : raw;
|
|
370
370
|
if (!e.name)
|
|
371
371
|
return empty;
|
|
372
|
-
return (_jsxs("span", { className: "crisp-datatable-entity", children: [_jsx("span", { className: "crisp-datatable-avatar", "data-tone": avatarTone === "hashed" ? toneFor(raw.name) : undefined, children: e.avatar ? (_jsx("img", { src: e.avatar, alt: "" })) : (initials(e.name).slice(0, 2)) }), col.
|
|
372
|
+
return (_jsxs("span", { className: "crisp-datatable-entity", children: [_jsx("span", { className: "crisp-datatable-avatar", "data-tone": avatarTone === "hashed" ? toneFor(raw.name) : undefined, "data-shape": col.avatarShape === "circle" ? "circle" : undefined, children: e.avatar ? (_jsx("img", { src: e.avatar, alt: "" })) : (initials(e.name).slice(0, 2)) }), col.href ? (_jsx("a", { href: col.href(row), className: "crisp-datatable-entity-name crisp-datatable-entity-name--link", onClick: (ev) => {
|
|
373
|
+
// same reasoning as onEntityClick's stopPropagation below --
|
|
374
|
+
// this must not also trigger the row's own onRowClick.
|
|
375
|
+
ev.stopPropagation();
|
|
376
|
+
}, children: e.name })) : col.onEntityClick ? (_jsx("button", { type: "button", className: "crisp-datatable-entity-name crisp-datatable-entity-name--link", onClick: (ev) => {
|
|
373
377
|
// the cell's own click already just selects (see the
|
|
374
378
|
// TableCell onClick above) -- this must additionally stop
|
|
375
379
|
// the row's onRowClick from firing, since this name points
|
|
@@ -113,7 +113,13 @@ const config = defineRecipe({
|
|
|
113
113
|
& .crisp-datatable-group-count { margin-inline-start: ${c.space["1.5"]}; color: ${c.fgMuted}; font-variant-numeric: tabular-nums; }
|
|
114
114
|
& .crisp-datatable-th-rename { width: 100%; min-width: 0; height: ${c.size.row}; margin: 0; padding: 0 ${c.space["1"]}; border: none; border-radius: ${c.radius.md}; background: ${c.bgSurface}; box-shadow: inset 0 0 0 1px ${c.bgBrandSolid}; font-family: inherit; font-size: ${c.text.lg}; font-weight: ${c.weight.medium}; color: ${c.fgPrimary}; outline: none; }
|
|
115
115
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px ${c.bgBrandSolid}; }
|
|
116
|
-
|
|
116
|
+
/* #719: overflow: clip, not hidden, on every truncation rule below --
|
|
117
|
+
hidden still honours a programmatic scrollLeft assignment (found via
|
|
118
|
+
a screenshot tool that pans anything with scrollWidth > clientWidth),
|
|
119
|
+
blanking or fragmenting the visible text even though real user
|
|
120
|
+
scrolling was already blocked. clip renders the ellipsis identically
|
|
121
|
+
and leaves no scroll position to move. */
|
|
122
|
+
& .crisp-datatable-th-label { overflow: clip; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
117
123
|
/* #465: 12px per the comment above (and Attio's measured header cell
|
|
118
124
|
padding: 0 12px) -- was still c.space["2"] (8px), drifted from its
|
|
119
125
|
own documented value. */
|
|
@@ -200,7 +206,7 @@ const config = defineRecipe({
|
|
|
200
206
|
/* reference picker: a leading 16px avatar per option, plus a trailing
|
|
201
207
|
"Create X" row when the consumer supplies one (#449) -- same measured
|
|
202
208
|
values as RecordsTable's own .crisp-recordstable-refoption*. */
|
|
203
|
-
& .crisp-datatable-refoption { display: flex; align-items: center; gap: ${c.space["2"]}; min-width: 0; overflow:
|
|
209
|
+
& .crisp-datatable-refoption { display: flex; align-items: center; gap: ${c.space["2"]}; min-width: 0; overflow: clip; text-overflow: ellipsis; }
|
|
204
210
|
& .crisp-datatable-refoption-avatar { flex-shrink: 0; }
|
|
205
211
|
& .crisp-datatable-refoption--create { color: ${c.fgMuted}; }
|
|
206
212
|
& .crisp-datatable-empty { padding: ${c.space["8"]} ${c.space["3"]}; text-align: center; color: ${c.fgMuted}; font-size: ${c.text.lg}; }
|
|
@@ -286,8 +292,11 @@ const config = defineRecipe({
|
|
|
286
292
|
(#833/#835/#848) that happened to apply the same 500 to every
|
|
287
293
|
primary-column body cell regardless of type. Made explicit here so
|
|
288
294
|
fixing that leak doesn't also (wrongly) drop entity names to 400. */
|
|
289
|
-
& .crisp-datatable-entity-name { overflow:
|
|
290
|
-
|
|
295
|
+
& .crisp-datatable-entity-name { overflow: clip; text-overflow: ellipsis; white-space: nowrap; font-weight: ${c.weight.medium}; text-decoration: underline; text-decoration-color: color-mix(in srgb, ${c.fgPrimary} 9%, transparent); }
|
|
296
|
+
/* #893: shared by the button (onEntityClick, a different record) and
|
|
297
|
+
the anchor (href, the row's own record) -- was button-only, which
|
|
298
|
+
silently left a real <a> unstyled the day #893 added one. */
|
|
299
|
+
& .crisp-datatable-entity-name--link { margin: 0; padding: 0; border: none; background: none; font: inherit; color: inherit; letter-spacing: inherit; text-align: start; cursor: pointer; max-width: 100%; }
|
|
291
300
|
/* crisp/#601, G-048: two 20px ghost icons, right-aligned in the primary
|
|
292
301
|
column, revealed on ROW hover (the issue's own title says "row
|
|
293
302
|
hover", and a live check confirmed hovering well past the name --
|
|
@@ -301,7 +310,13 @@ const config = defineRecipe({
|
|
|
301
310
|
& tr:hover .crisp-datatable-entity-actions, & .crisp-datatable-entity-actions:focus-within { opacity: 1; }
|
|
302
311
|
& .crisp-datatable-entity-action { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0; padding: 0; border: none; border-radius: ${c.radius.sm}; background: none; font-family: inherit; color: color-mix(in srgb, ${c.fgPrimary} 55%, transparent); cursor: pointer; flex-shrink: 0; }
|
|
303
312
|
& .crisp-datatable-entity-action:hover { background: color-mix(in srgb, ${c.fgPrimary} 4%, transparent); color: ${c.fgPrimary}; }
|
|
304
|
-
|
|
313
|
+
/* #892: the default shape's radius was a stray literal (radius.sm, 6px)
|
|
314
|
+
-- Attio's own real company/object avatar measures 30%, which is
|
|
315
|
+
Avatar's own already-shipped shape="rounded" value, not a new number.
|
|
316
|
+
shape="circle" reuses Avatar's own shape="circle" value (radius.full)
|
|
317
|
+
the same way, measured live on a real Attio person avatar. */
|
|
318
|
+
& .crisp-datatable-avatar { width: ${c.size.icon}; height: ${c.size.icon}; border-radius: 30%; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; font-weight: ${c.weight.semibold}; text-transform: uppercase; color: ${c.fgOnBrand}; background: ${c.bgBrandSolid}; }
|
|
319
|
+
& .crisp-datatable-avatar[data-shape="circle"] { border-radius: ${c.radius.full}; }
|
|
305
320
|
& .crisp-datatable-avatar[data-tone="success"] { background: ${c.bgSuccess}; } & .crisp-datatable-avatar[data-tone="warning"] { background: ${c.bgWarning}; } & .crisp-datatable-avatar[data-tone="danger"] { background: ${c.bgDanger}; } & .crisp-datatable-avatar[data-tone="purple"] { background: ${c.bgPurple}; } & .crisp-datatable-avatar[data-tone="cyan"] { background: ${c.bgCyan}; } & .crisp-datatable-avatar[data-tone="orange"] { background: ${c.bgOrange}; }
|
|
306
321
|
& .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
|
|
307
322
|
& .crisp-datatable-tags { display: flex; align-items: center; gap: ${c.space["1"]}; overflow: hidden; }
|
|
@@ -323,7 +338,7 @@ const config = defineRecipe({
|
|
|
323
338
|
own .crisp-recordstable-link, which this mirrors: no underline at
|
|
324
339
|
rest, underline on hover, own-colour text rather than a browser-blue
|
|
325
340
|
link. */
|
|
326
|
-
& .crisp-datatable-link { color: ${c.fgPrimary}; text-decoration: none; overflow:
|
|
341
|
+
& .crisp-datatable-link { color: ${c.fgPrimary}; text-decoration: none; overflow: clip; text-overflow: ellipsis; }
|
|
327
342
|
& .crisp-datatable-link:hover { text-decoration: underline; }
|
|
328
343
|
/* phone cell type/editor (#765) -- measured live: the dial-code prefix
|
|
329
344
|
is a muted rgba(0,0,0,0.63) at 14px, matching every other muted-text
|
|
@@ -22,7 +22,7 @@ const fromDate = (d) => ({
|
|
|
22
22
|
* popover. This is what `DatePicker` used to be; `DatePicker` is now
|
|
23
23
|
* seed-design's bare calendar, and this composes it.
|
|
24
24
|
*/
|
|
25
|
-
export function DatePickerField({ value, defaultValue, onValueChange, onChange, placeholder: placeholderProp, variant = "default", format = defaultFormat, clearable = true, clearLabel: clearLabelProp, presets, calendarProps, "aria-label": ariaLabel, className, ...rest }) {
|
|
25
|
+
export function DatePickerField({ value, defaultValue, onValueChange, onChange, placeholder: placeholderProp, variant = "default", width = "full", format = defaultFormat, clearable = true, clearLabel: clearLabelProp, presets, calendarProps, "aria-label": ariaLabel, className, ...rest }) {
|
|
26
26
|
// crisp/#471: same resolution order as Select's own.
|
|
27
27
|
const placeholder = useCrispMessage(placeholderProp, "Set date…");
|
|
28
28
|
const clearLabel = useCrispMessage(clearLabelProp, "Clear date");
|
|
@@ -43,7 +43,7 @@ export function DatePickerField({ value, defaultValue, onValueChange, onChange,
|
|
|
43
43
|
onValueChange?.(null);
|
|
44
44
|
onChange?.(null);
|
|
45
45
|
};
|
|
46
|
-
return (_jsx("div", { className: datepickerfieldRecipe({ className }), ...rest, children: _jsxs("div", { className: "crisp-datepickerfield-box", "data-ghost": variant === "ghost" ? "" : undefined, "data-placeholder": selected ? undefined : "", children: [_jsx(Popover, { open: open, onOpenChange: setOpen, "aria-label": ariaLabel, trigger: _jsxs("button", { type: "button", className: "crisp-datepickerfield-trigger", "aria-label": ariaLabel, children: [_jsx(CalendarDays, { size: 15, strokeWidth: 1.75, "aria-hidden": "true" }), selected ? format(selected) : placeholder] }), children: _jsxs("div", { className: "crisp-datepickerfield-panel", children: [_jsx(DatePicker
|
|
46
|
+
return (_jsx("div", { className: datepickerfieldRecipe({ width, className }), ...rest, children: _jsxs("div", { className: "crisp-datepickerfield-box", "data-ghost": variant === "ghost" ? "" : undefined, "data-placeholder": selected ? undefined : "", children: [_jsx(Popover, { open: open, onOpenChange: setOpen, "aria-label": ariaLabel, trigger: _jsxs("button", { type: "button", className: "crisp-datepickerfield-trigger", "aria-label": ariaLabel, children: [_jsx(CalendarDays, { size: 15, strokeWidth: 1.75, "aria-hidden": "true" }), selected ? format(selected) : placeholder] }), children: _jsxs("div", { className: "crisp-datepickerfield-panel", children: [_jsx(DatePicker
|
|
47
47
|
// DatePickerProps is a union over selectionMode, and TypeScript
|
|
48
48
|
// cannot narrow it through a spread: it tries every branch and
|
|
49
49
|
// reports the range one as missing props. The field is always
|
|
@@ -10,7 +10,7 @@ const config = defineRecipe({
|
|
|
10
10
|
display: inline-flex; font-family: ${c.font.sans};
|
|
11
11
|
|
|
12
12
|
& .crisp-datepickerfield-box {
|
|
13
|
-
display: inline-flex; align-items: center;
|
|
13
|
+
display: inline-flex; align-items: center; width: 100%;
|
|
14
14
|
box-sizing: border-box; height: 32px; margin: 0;
|
|
15
15
|
border-radius: ${c.radius.md}; background: transparent;
|
|
16
16
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, ${c.fgPrimary} 7%, transparent);
|
|
@@ -19,6 +19,7 @@ const config = defineRecipe({
|
|
|
19
19
|
& .crisp-datepickerfield-box[data-ghost] { background: transparent; box-shadow: none; }
|
|
20
20
|
& .crisp-datepickerfield-box[data-ghost]:hover { background: color-mix(in srgb, ${c.fgPrimary} 4%, transparent); }
|
|
21
21
|
& .crisp-datepickerfield-trigger {
|
|
22
|
+
flex: 1; min-width: 0;
|
|
22
23
|
display: inline-flex; align-items: center; gap: ${c.space["2"]};
|
|
23
24
|
height: 100%; padding: 0 ${c.space["2.5"]}; margin: 0;
|
|
24
25
|
border: none; background: none; color: inherit; font-family: inherit;
|
|
@@ -48,8 +49,20 @@ const config = defineRecipe({
|
|
|
48
49
|
}
|
|
49
50
|
& .crisp-datepickerfield-preset:hover { background: color-mix(in srgb, ${c.fgPrimary} 8%, transparent); }
|
|
50
51
|
`,
|
|
51
|
-
variants: {
|
|
52
|
-
|
|
52
|
+
variants: {
|
|
53
|
+
// crisp#980: full (default) fills its container, matching Select's own
|
|
54
|
+
// width variant/default -- so a form composing DatePickerField alongside
|
|
55
|
+
// Input/Select via FormField gets one consistent column width across
|
|
56
|
+
// every field type, not just some of them. auto sizes to content, the
|
|
57
|
+
// behaviour every consumer got unconditionally before this.
|
|
58
|
+
width: {
|
|
59
|
+
full: `width: 100%;`,
|
|
60
|
+
auto: `width: auto;`,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
width: "full",
|
|
65
|
+
},
|
|
53
66
|
compoundVariants: [],
|
|
54
67
|
});
|
|
55
68
|
export const datepickerfieldRecipe = Object.assign(resolveRecipe(config), {
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
2
|
-
import { contract as c
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
2
|
+
import { contract as c } from "../../tokens/index.js";
|
|
3
|
+
// your-moon/crisp#934: was a radius-16 frosted-glass card (a
|
|
4
|
+
// 60%-tinted, 15px-backdrop-blurred outer shell wrapping a solid radius-12
|
|
5
|
+
// inner card) -- owner-directed: Dialog's identity now follows seed-design
|
|
6
|
+
// (daangn), whose own Dialog spec has no shadow/blur/tint property at all;
|
|
7
|
+
// elevation there is conveyed purely by a darker backdrop scrim plus the
|
|
8
|
+
// existing scale+fade entrance animation (which crisp already had). Flat
|
|
9
|
+
// single surface now: `.crisp-dialog-content` is a bare, invisible sizing
|
|
10
|
+
// wrapper (no background/radius/shadow of its own); `.crisp-dialog-card` is
|
|
11
|
+
// the one real surface, radius bumped from `xl` (12px) to `3xl` (20px,
|
|
12
|
+
// seed's own shared floating-surface radius, `$radius.r5`), no shadow.
|
|
13
|
+
// `bgScrim` itself also moved toward seed's own darker backdrop value
|
|
14
|
+
// (`tokens/palette.ts`). The alert variant no longer needs its own override
|
|
15
|
+
// of either rule -- both variants now render the identical flat surface.
|
|
8
16
|
//
|
|
9
17
|
// #414: the footer's submit-key caps (⌘/Enter) used to be one span drawing a
|
|
10
18
|
// visible pill (18px, 22%-white background). Attio's own are two separate
|
|
@@ -18,10 +26,8 @@ const config = defineRecipe({
|
|
|
18
26
|
& .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: ${c.bgScrim}; }
|
|
19
27
|
& .crisp-dialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-start; justify-content: center; padding: 15vh ${c.space["4"]} ${c.space["4"]}; }
|
|
20
28
|
& .crisp-dialog-positioner[data-variant="alert"] { align-items: center; padding: ${c.space["4"]}; }
|
|
21
|
-
& .crisp-dialog-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 90vw; max-height: 74vh;
|
|
22
|
-
& .crisp-dialog-
|
|
23
|
-
& .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: ${c.radius.xl}; background: ${c.bgSurface}; box-shadow: 0 0 0 1px color-mix(in srgb, ${c.fgPrimary} 8%, transparent); overflow: hidden; }
|
|
24
|
-
& .crisp-dialog-content[data-variant="alert"] .crisp-dialog-card { border-radius: ${c.radius.xl}; background: ${c.bgPopover}; box-shadow: ${e.floating}; }
|
|
29
|
+
& .crisp-dialog-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 90vw; max-height: 74vh; opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
|
|
30
|
+
& .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: ${c.radius["3xl"]}; background: ${c.bgSurface}; overflow: hidden; }
|
|
25
31
|
& .crisp-dialog-header { display: flex; align-items: center; gap: ${c.space["2"]}; flex-shrink: 0; height: 52px; padding: 0 ${c.space["2"]} 0 ${c.space["4"]}; border-bottom: 1px solid ${c.borderSubtle}; }
|
|
26
32
|
& .crisp-dialog-header svg { flex-shrink: 0; color: ${c.fgMuted}; }
|
|
27
33
|
& .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: ${c.text.lg}; font-weight: ${c.weight.medium}; color: ${c.fgPrimary}; margin: 0; }
|
|
@@ -43,7 +49,12 @@ const config = defineRecipe({
|
|
|
43
49
|
& .crisp-dialog-field { display: flex; flex-direction: column; gap: ${c.space["1.5"]}; }
|
|
44
50
|
& .crisp-dialog-field-label { font-size: ${c.text.sm}; font-weight: ${c.weight.medium}; color: color-mix(in srgb, ${c.fgPrimary} 50%, transparent); }
|
|
45
51
|
& .crisp-dialog-more { display: inline-flex; align-items: center; gap: ${c.space["2"]}; margin-inline-end: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: ${c.text.md}; color: ${c.fgMuted}; cursor: pointer; }
|
|
46
|
-
|
|
52
|
+
/* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
|
|
53
|
+
the accent (#0298d9) only clears 3.23:1 with white; the darker
|
|
54
|
+
sibling clears 4.5:1+, same fix already applied to Button/Badge/
|
|
55
|
+
Avatar (#897). Scoped to this one fill only -- Dialog's own frosted-
|
|
56
|
+
surface identity (#934) is untouched here. */
|
|
57
|
+
& .crisp-dialog-submit { display: inline-flex; align-items: center; gap: ${c.space["2"]}; height: 28px; padding: 0 ${c.space["1"]} 0 ${c.space["2.5"]}; border: none; border-radius: ${c.radius.md}; background: ${c.bgBrandContrast}; color: ${c.fgOnBrand}; font-family: inherit; font-size: ${c.text.md}; font-weight: ${c.weight.medium}; cursor: pointer; }
|
|
47
58
|
& .crisp-dialog-submit-key { display: inline-flex; align-items: center; gap: ${c.space["1"]}; }
|
|
48
59
|
& .crisp-dialog-submit-key kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: ${c.fgOnBrand}; font-family: inherit; font-style: normal; font-size: 10px; }`,
|
|
49
60
|
variants: {},
|