@crisp-ui-kit/crisp 0.9.1 → 0.10.1

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.
@@ -0,0 +1,17 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./middletruncate"), exports);
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.MiddleTruncate = MiddleTruncate;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_middle_truncate_1 = require("@seed-design/react-middle-truncate");
7
+ /**
8
+ * Truncates in the MIDDLE rather than the end, so the part that identifies a
9
+ * string survives: `annual-report-fi…-v7-final.pdf` keeps its extension, and a
10
+ * record title keeps its suffix. An end-truncating `text-overflow: ellipsis`
11
+ * throws exactly that away.
12
+ *
13
+ * Measurement is seed-design's — it re-measures on resize with a
14
+ * `ResizeObserver` and only touches the DOM inside an effect, so it renders the
15
+ * full string on the server and narrows it on hydration.
16
+ *
17
+ * It owns no pixels, in crisp or in seed: there is no recipe here because
18
+ * seed-design ships no stylesheet for it either. It inherits the type around it
19
+ * by design, which is what makes it usable inside a table cell.
20
+ */
21
+ function MiddleTruncate({ children, title, ...props }) {
22
+ return ((0, jsx_runtime_1.jsx)(react_middle_truncate_1.MiddleTruncate, { ...props, title: title ?? children, children: children }));
23
+ }
@@ -0,0 +1,18 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./slider"), exports);
18
+ __exportStar(require("./slider.recipe"), exports);
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Slider = Slider;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_slider_1 = require("@seed-design/react-slider");
7
+ const slider_recipe_1 = require("./slider.recipe");
8
+ /** Reads the thumb count from the engine rather than re-deriving it from props. */
9
+ function Thumbs() {
10
+ const { values } = (0, react_slider_1.useSliderContext)();
11
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: values.map((_, i) => ((0, jsx_runtime_1.jsx)(react_slider_1.SliderThumb
12
+ // biome-ignore lint/suspicious/noArrayIndexKey: thumbs are positional — the index IS the identity the engine addresses them by
13
+ , { thumbIndex: i, className: "slider-thumb" }, i))) }));
14
+ }
15
+ /**
16
+ * A range input, driven by seed-design's headless engine so the keyboard model,
17
+ * the pointer maths and multi-thumb constraints are theirs by construction.
18
+ * Pass one value for a simple slider, two for a range.
19
+ */
20
+ function Slider({ className, ...props }) {
21
+ return ((0, jsx_runtime_1.jsx)(react_slider_1.SliderRoot, { ...props, className: (0, slider_recipe_1.sliderRecipe)({ className }), children: (0, jsx_runtime_1.jsxs)("span", { className: "slider-control", children: [(0, jsx_runtime_1.jsx)("span", { className: "slider-track", children: (0, jsx_runtime_1.jsx)(react_slider_1.SliderRange, { className: "slider-range" }) }), (0, jsx_runtime_1.jsx)(Thumbs, {})] }) }));
22
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sliderRecipe = void 0;
4
+ const core_1 = require("../../core");
5
+ const tokens_1 = require("../../tokens");
6
+ // seed-design's slider, shape for shape, in crisp's colours.
7
+ //
8
+ // Attio ships no slider anywhere — Records, Reports, Settings and the record
9
+ // pages contain no `input[type=range]` or `[role=slider]` — so there is nothing
10
+ // of Attio's to measure. The GEOMETRY is therefore seed's own, read from
11
+ // `@seed-design/css/recipes/slider.css`: a 26px control row, a 4px track on
12
+ // `radius.full`, a 20px thumb whose visible disc is an `::after` that scales to
13
+ // 1.2 while dragging, and a 2px focus ring offset 2px.
14
+ //
15
+ // Only the COLOUR roles are re-pointed at crisp's tokens:
16
+ // seed gray-400 track -> bgNeutralWeak (crisp's weak neutral fill)
17
+ // seed fg-neutral range -> bgBrandSolid (crisp fills with brand, as Progress does)
18
+ // seed bg-neutral-inverted -> #fff + elevation.field (crisp's control disc, as Switch does)
19
+ //
20
+ // Position comes from the engine's own `--range-start`/`--range-end` and
21
+ // `--thumb-position`/`--thumb-offset`, switched on the `data-dir` it stamps —
22
+ // the same mechanism seed uses, rather than CSS direction inheritance.
23
+ const config = (0, core_1.defineRecipe)({
24
+ name: "slider",
25
+ base: `
26
+ display: flex; flex-direction: column; align-items: stretch;
27
+ width: 100%; min-width: 0; gap: ${tokens_1.contract.space["0.5"]};
28
+ font-family: ${tokens_1.contract.font.sans}; user-select: none; touch-action: none;
29
+
30
+ & .slider-control { position: relative; height: 26px; display: flex; align-items: center; }
31
+
32
+ & .slider-track {
33
+ position: relative; flex-grow: 1; height: ${tokens_1.contract.space["1"]};
34
+ border-radius: ${tokens_1.contract.radius.full}; background: ${tokens_1.contract.bgNeutralWeak};
35
+ overflow: hidden;
36
+ }
37
+
38
+ & .slider-range { position: absolute; height: 100%; background: ${tokens_1.contract.bgBrandSolid}; }
39
+ & .slider-range[data-dir="ltr"] { left: var(--range-start); right: var(--range-end); }
40
+ & .slider-range[data-dir="rtl"] { right: var(--range-start); left: var(--range-end); }
41
+
42
+ & .slider-thumb {
43
+ position: absolute; top: 50%;
44
+ width: ${tokens_1.contract.space["5"]}; height: ${tokens_1.contract.space["5"]};
45
+ transform: translate(-50%, -50%);
46
+ border: none; background: none; padding: 0;
47
+ }
48
+ & .slider-thumb[data-dir="ltr"] { left: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
49
+ & .slider-thumb[data-dir="rtl"] { right: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
50
+ & .slider-thumb::after {
51
+ content: ""; position: absolute; inset: 0;
52
+ border-radius: ${tokens_1.contract.radius.full}; background: #fff; box-shadow: ${tokens_1.elevation.field};
53
+ outline: 2px solid transparent; outline-offset: 2px;
54
+ transition: transform .2s ease, outline-color .2s ease;
55
+ cursor: grab;
56
+ }
57
+ & .slider-thumb[data-thumb-dragging]::after { transform: scale(1.2); cursor: grabbing; }
58
+ & .slider-thumb:focus { outline: none; }
59
+ & .slider-thumb:focus-visible::after { outline-color: ${tokens_1.contract.strokeFocusRing}; }
60
+
61
+ &[data-disabled] { cursor: not-allowed; }
62
+ &[data-disabled] .slider-range { background: ${tokens_1.contract.fgDisabled}; }
63
+ &[data-disabled] .slider-thumb::after { cursor: not-allowed; }
64
+ `,
65
+ variants: {},
66
+ defaultVariants: {},
67
+ compoundVariants: [],
68
+ });
69
+ exports.sliderRecipe = Object.assign((0, core_1.resolveRecipe)(config), { config });
70
+ exports.default = config;
package/dist/cjs/index.js CHANGED
@@ -45,6 +45,7 @@ __exportStar(require("./components/input"), exports);
45
45
  __exportStar(require("./components/kbd"), exports);
46
46
  __exportStar(require("./components/linechart"), exports);
47
47
  __exportStar(require("./components/menu"), exports);
48
+ __exportStar(require("./components/middletruncate"), exports);
48
49
  __exportStar(require("./components/multiselect"), exports);
49
50
  __exportStar(require("./components/popover"), exports);
50
51
  __exportStar(require("./components/progress"), exports);
@@ -53,6 +54,7 @@ __exportStar(require("./components/resizablepanel"), exports);
53
54
  __exportStar(require("./components/segmented"), exports);
54
55
  __exportStar(require("./components/select"), exports);
55
56
  __exportStar(require("./components/skeleton"), exports);
57
+ __exportStar(require("./components/slider"), exports);
56
58
  __exportStar(require("./components/spinner"), exports);
57
59
  __exportStar(require("./components/stagebar"), exports);
58
60
  __exportStar(require("./components/statcard"), exports);
@@ -0,0 +1 @@
1
+ export * from "./middletruncate.js";
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { MiddleTruncate as SeedMiddleTruncate, } from "@seed-design/react-middle-truncate";
4
+ /**
5
+ * Truncates in the MIDDLE rather than the end, so the part that identifies a
6
+ * string survives: `annual-report-fi…-v7-final.pdf` keeps its extension, and a
7
+ * record title keeps its suffix. An end-truncating `text-overflow: ellipsis`
8
+ * throws exactly that away.
9
+ *
10
+ * Measurement is seed-design's — it re-measures on resize with a
11
+ * `ResizeObserver` and only touches the DOM inside an effect, so it renders the
12
+ * full string on the server and narrows it on hydration.
13
+ *
14
+ * It owns no pixels, in crisp or in seed: there is no recipe here because
15
+ * seed-design ships no stylesheet for it either. It inherits the type around it
16
+ * by design, which is what makes it usable inside a table cell.
17
+ */
18
+ export function MiddleTruncate({ children, title, ...props }) {
19
+ return (_jsx(SeedMiddleTruncate, { ...props, title: title ?? children, children: children }));
20
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./slider.js";
2
+ export * from "./slider.recipe.js";
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { SliderRange, SliderRoot, SliderThumb, useSliderContext, } from "@seed-design/react-slider";
4
+ import { sliderRecipe } from "./slider.recipe.js";
5
+ /** Reads the thumb count from the engine rather than re-deriving it from props. */
6
+ function Thumbs() {
7
+ const { values } = useSliderContext();
8
+ return (_jsx(_Fragment, { children: values.map((_, i) => (_jsx(SliderThumb
9
+ // biome-ignore lint/suspicious/noArrayIndexKey: thumbs are positional — the index IS the identity the engine addresses them by
10
+ , { thumbIndex: i, className: "slider-thumb" }, i))) }));
11
+ }
12
+ /**
13
+ * A range input, driven by seed-design's headless engine so the keyboard model,
14
+ * the pointer maths and multi-thumb constraints are theirs by construction.
15
+ * Pass one value for a simple slider, two for a range.
16
+ */
17
+ export function Slider({ className, ...props }) {
18
+ return (_jsx(SliderRoot, { ...props, className: sliderRecipe({ className }), children: _jsxs("span", { className: "slider-control", children: [_jsx("span", { className: "slider-track", children: _jsx(SliderRange, { className: "slider-range" }) }), _jsx(Thumbs, {})] }) }));
19
+ }
@@ -0,0 +1,67 @@
1
+ import { defineRecipe, resolveRecipe } from "../../core/index.js";
2
+ import { contract as c, elevation as e } from "../../tokens/index.js";
3
+ // seed-design's slider, shape for shape, in crisp's colours.
4
+ //
5
+ // Attio ships no slider anywhere — Records, Reports, Settings and the record
6
+ // pages contain no `input[type=range]` or `[role=slider]` — so there is nothing
7
+ // of Attio's to measure. The GEOMETRY is therefore seed's own, read from
8
+ // `@seed-design/css/recipes/slider.css`: a 26px control row, a 4px track on
9
+ // `radius.full`, a 20px thumb whose visible disc is an `::after` that scales to
10
+ // 1.2 while dragging, and a 2px focus ring offset 2px.
11
+ //
12
+ // Only the COLOUR roles are re-pointed at crisp's tokens:
13
+ // seed gray-400 track -> bgNeutralWeak (crisp's weak neutral fill)
14
+ // seed fg-neutral range -> bgBrandSolid (crisp fills with brand, as Progress does)
15
+ // seed bg-neutral-inverted -> #fff + elevation.field (crisp's control disc, as Switch does)
16
+ //
17
+ // Position comes from the engine's own `--range-start`/`--range-end` and
18
+ // `--thumb-position`/`--thumb-offset`, switched on the `data-dir` it stamps —
19
+ // the same mechanism seed uses, rather than CSS direction inheritance.
20
+ const config = defineRecipe({
21
+ name: "slider",
22
+ base: `
23
+ display: flex; flex-direction: column; align-items: stretch;
24
+ width: 100%; min-width: 0; gap: ${c.space["0.5"]};
25
+ font-family: ${c.font.sans}; user-select: none; touch-action: none;
26
+
27
+ & .slider-control { position: relative; height: 26px; display: flex; align-items: center; }
28
+
29
+ & .slider-track {
30
+ position: relative; flex-grow: 1; height: ${c.space["1"]};
31
+ border-radius: ${c.radius.full}; background: ${c.bgNeutralWeak};
32
+ overflow: hidden;
33
+ }
34
+
35
+ & .slider-range { position: absolute; height: 100%; background: ${c.bgBrandSolid}; }
36
+ & .slider-range[data-dir="ltr"] { left: var(--range-start); right: var(--range-end); }
37
+ & .slider-range[data-dir="rtl"] { right: var(--range-start); left: var(--range-end); }
38
+
39
+ & .slider-thumb {
40
+ position: absolute; top: 50%;
41
+ width: ${c.space["5"]}; height: ${c.space["5"]};
42
+ transform: translate(-50%, -50%);
43
+ border: none; background: none; padding: 0;
44
+ }
45
+ & .slider-thumb[data-dir="ltr"] { left: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
46
+ & .slider-thumb[data-dir="rtl"] { right: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
47
+ & .slider-thumb::after {
48
+ content: ""; position: absolute; inset: 0;
49
+ border-radius: ${c.radius.full}; background: #fff; box-shadow: ${e.field};
50
+ outline: 2px solid transparent; outline-offset: 2px;
51
+ transition: transform .2s ease, outline-color .2s ease;
52
+ cursor: grab;
53
+ }
54
+ & .slider-thumb[data-thumb-dragging]::after { transform: scale(1.2); cursor: grabbing; }
55
+ & .slider-thumb:focus { outline: none; }
56
+ & .slider-thumb:focus-visible::after { outline-color: ${c.strokeFocusRing}; }
57
+
58
+ &[data-disabled] { cursor: not-allowed; }
59
+ &[data-disabled] .slider-range { background: ${c.fgDisabled}; }
60
+ &[data-disabled] .slider-thumb::after { cursor: not-allowed; }
61
+ `,
62
+ variants: {},
63
+ defaultVariants: {},
64
+ compoundVariants: [],
65
+ });
66
+ export const sliderRecipe = Object.assign(resolveRecipe(config), { config });
67
+ export default config;
package/dist/esm/index.js CHANGED
@@ -29,6 +29,7 @@ export * from "./components/input/index.js";
29
29
  export * from "./components/kbd/index.js";
30
30
  export * from "./components/linechart/index.js";
31
31
  export * from "./components/menu/index.js";
32
+ export * from "./components/middletruncate/index.js";
32
33
  export * from "./components/multiselect/index.js";
33
34
  export * from "./components/popover/index.js";
34
35
  export * from "./components/progress/index.js";
@@ -37,6 +38,7 @@ export * from "./components/resizablepanel/index.js";
37
38
  export * from "./components/segmented/index.js";
38
39
  export * from "./components/select/index.js";
39
40
  export * from "./components/skeleton/index.js";
41
+ export * from "./components/slider/index.js";
40
42
  export * from "./components/spinner/index.js";
41
43
  export * from "./components/stagebar/index.js";
42
44
  export * from "./components/statcard/index.js";
@@ -0,0 +1,50 @@
1
+ .slider {
2
+
3
+ display: flex; flex-direction: column; align-items: stretch;
4
+ width: 100%; min-width: 0; gap: var(--space-0-5);
5
+ font-family: var(--font-sans); user-select: none; touch-action: none;
6
+
7
+ & .slider-control { position: relative; height: 26px; display: flex; align-items: center; }
8
+
9
+ & .slider-track {
10
+ position: relative; flex-grow: 1; height: var(--space-1);
11
+ border-radius: var(--radius-full); background: var(--bg-neutral-weak);
12
+ overflow: hidden;
13
+ }
14
+
15
+ & .slider-range { position: absolute; height: 100%; background: var(--bg-brand-solid); }
16
+ & .slider-range[data-dir="ltr"] { left: var(--range-start); right: var(--range-end); }
17
+ & .slider-range[data-dir="rtl"] { right: var(--range-start); left: var(--range-end); }
18
+
19
+ & .slider-thumb {
20
+ position: absolute; top: 50%;
21
+ width: var(--space-5); height: var(--space-5);
22
+ transform: translate(-50%, -50%);
23
+ border: none; background: none; padding: 0;
24
+ }
25
+ & .slider-thumb[data-dir="ltr"] { left: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
26
+ & .slider-thumb[data-dir="rtl"] { right: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
27
+ & .slider-thumb::after {
28
+ content: ""; position: absolute; inset: 0;
29
+ border-radius: var(--radius-full); background: #fff; box-shadow: inset 0 0 0 1px var(--ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04);
30
+ outline: 2px solid transparent; outline-offset: 2px;
31
+ transition: transform .2s ease, outline-color .2s ease;
32
+ cursor: grab;
33
+ }
34
+ & .slider-thumb[data-thumb-dragging]::after { transform: scale(1.2); cursor: grabbing; }
35
+ & .slider-thumb:focus { outline: none; }
36
+ & .slider-thumb:focus-visible::after { outline-color: var(--stroke-focus-ring); }
37
+
38
+ &[data-disabled] { cursor: not-allowed; }
39
+ &[data-disabled] .slider-range { background: var(--fg-disabled); }
40
+ &[data-disabled] .slider-thumb::after { cursor: not-allowed; }
41
+
42
+ }
43
+
44
+ @media (prefers-reduced-motion: reduce) {
45
+ .slider, .slider * {
46
+ animation-duration: 0.01ms !important;
47
+ animation-iteration-count: 1 !important;
48
+ transition-duration: 0.01ms !important;
49
+ }
50
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface SliderVariants {
4
+
5
+ }
6
+
7
+ export declare const sliderRecipe: RecipeFn<{ }>;
package/dist/styles.css CHANGED
@@ -1365,6 +1365,57 @@
1365
1365
  }
1366
1366
  }
1367
1367
 
1368
+ .slider {
1369
+
1370
+ display: flex; flex-direction: column; align-items: stretch;
1371
+ width: 100%; min-width: 0; gap: var(--space-0-5);
1372
+ font-family: var(--font-sans); user-select: none; touch-action: none;
1373
+
1374
+ & .slider-control { position: relative; height: 26px; display: flex; align-items: center; }
1375
+
1376
+ & .slider-track {
1377
+ position: relative; flex-grow: 1; height: var(--space-1);
1378
+ border-radius: var(--radius-full); background: var(--bg-neutral-weak);
1379
+ overflow: hidden;
1380
+ }
1381
+
1382
+ & .slider-range { position: absolute; height: 100%; background: var(--bg-brand-solid); }
1383
+ & .slider-range[data-dir="ltr"] { left: var(--range-start); right: var(--range-end); }
1384
+ & .slider-range[data-dir="rtl"] { right: var(--range-start); left: var(--range-end); }
1385
+
1386
+ & .slider-thumb {
1387
+ position: absolute; top: 50%;
1388
+ width: var(--space-5); height: var(--space-5);
1389
+ transform: translate(-50%, -50%);
1390
+ border: none; background: none; padding: 0;
1391
+ }
1392
+ & .slider-thumb[data-dir="ltr"] { left: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
1393
+ & .slider-thumb[data-dir="rtl"] { right: calc(var(--thumb-position) * 1% + var(--thumb-offset)); }
1394
+ & .slider-thumb::after {
1395
+ content: ""; position: absolute; inset: 0;
1396
+ border-radius: var(--radius-full); background: #fff; box-shadow: inset 0 0 0 1px var(--ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04);
1397
+ outline: 2px solid transparent; outline-offset: 2px;
1398
+ transition: transform .2s ease, outline-color .2s ease;
1399
+ cursor: grab;
1400
+ }
1401
+ & .slider-thumb[data-thumb-dragging]::after { transform: scale(1.2); cursor: grabbing; }
1402
+ & .slider-thumb:focus { outline: none; }
1403
+ & .slider-thumb:focus-visible::after { outline-color: var(--stroke-focus-ring); }
1404
+
1405
+ &[data-disabled] { cursor: not-allowed; }
1406
+ &[data-disabled] .slider-range { background: var(--fg-disabled); }
1407
+ &[data-disabled] .slider-thumb::after { cursor: not-allowed; }
1408
+
1409
+ }
1410
+
1411
+ @media (prefers-reduced-motion: reduce) {
1412
+ .slider, .slider * {
1413
+ animation-duration: 0.01ms !important;
1414
+ animation-iteration-count: 1 !important;
1415
+ transition-duration: 0.01ms !important;
1416
+ }
1417
+ }
1418
+
1368
1419
  @keyframes crisp-spin { to { transform: rotate(360deg); } }
1369
1420
  .spinner {
1370
1421
  display: inline-block; box-sizing: border-box; width: 16px; height: 16px; border-radius: var(--radius-full); border: 2px solid color-mix(in srgb, var(--fg-primary) 15%, transparent); border-top-color: var(--fg-muted); animation: crisp-spin 0.6s linear infinite;
@@ -0,0 +1 @@
1
+ export * from "./middletruncate";
@@ -0,0 +1,20 @@
1
+ import { type MiddleTruncateProps as SeedProps } from "@seed-design/react-middle-truncate";
2
+ export type MiddleTruncateProps = Omit<SeedProps, "asChild"> & {
3
+ /** The full string. Kept whole in the DOM's accessible name via `title`. */
4
+ children: string;
5
+ };
6
+ /**
7
+ * Truncates in the MIDDLE rather than the end, so the part that identifies a
8
+ * string survives: `annual-report-fi…-v7-final.pdf` keeps its extension, and a
9
+ * record title keeps its suffix. An end-truncating `text-overflow: ellipsis`
10
+ * throws exactly that away.
11
+ *
12
+ * Measurement is seed-design's — it re-measures on resize with a
13
+ * `ResizeObserver` and only touches the DOM inside an effect, so it renders the
14
+ * full string on the server and narrows it on hydration.
15
+ *
16
+ * It owns no pixels, in crisp or in seed: there is no recipe here because
17
+ * seed-design ships no stylesheet for it either. It inherits the type around it
18
+ * by design, which is what makes it usable inside a table cell.
19
+ */
20
+ export declare function MiddleTruncate({ children, title, ...props }: MiddleTruncateProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export * from "./slider";
2
+ export * from "./slider.recipe";
@@ -0,0 +1,8 @@
1
+ import { type SliderRootProps } from "@seed-design/react-slider";
2
+ export type SliderProps = SliderRootProps;
3
+ /**
4
+ * A range input, driven by seed-design's headless engine so the keyboard model,
5
+ * the pointer maths and multi-thumb constraints are theirs by construction.
6
+ * Pass one value for a simple slider, two for a range.
7
+ */
8
+ export declare function Slider({ className, ...props }: SliderProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ declare const config: import("../..").RecipeConfig<{}>;
2
+ export declare const sliderRecipe: import("../..").RecipeFn<{}> & {
3
+ config: import("../..").RecipeConfig<{}>;
4
+ };
5
+ export default config;
@@ -25,6 +25,7 @@ export * from "./components/input";
25
25
  export * from "./components/kbd";
26
26
  export * from "./components/linechart";
27
27
  export * from "./components/menu";
28
+ export * from "./components/middletruncate";
28
29
  export * from "./components/multiselect";
29
30
  export * from "./components/popover";
30
31
  export * from "./components/progress";
@@ -33,6 +34,7 @@ export * from "./components/resizablepanel";
33
34
  export * from "./components/segmented";
34
35
  export * from "./components/select";
35
36
  export * from "./components/skeleton";
37
+ export * from "./components/slider";
36
38
  export * from "./components/spinner";
37
39
  export * from "./components/stagebar";
38
40
  export * from "./components/statcard";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crisp-ui-kit/crisp",
3
- "version": "0.9.1",
3
+ "version": "0.10.1",
4
4
  "description": "A lean React design system, measured pixel-for-pixel from Attio.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -167,6 +167,11 @@
167
167
  "import": "./dist/esm/components/menu/index.js",
168
168
  "require": "./dist/cjs/components/menu/index.js"
169
169
  },
170
+ "./middletruncate": {
171
+ "types": "./dist/types/components/middletruncate/index.d.ts",
172
+ "import": "./dist/esm/components/middletruncate/index.js",
173
+ "require": "./dist/cjs/components/middletruncate/index.js"
174
+ },
170
175
  "./multiselect": {
171
176
  "types": "./dist/types/components/multiselect/index.d.ts",
172
177
  "import": "./dist/esm/components/multiselect/index.js",
@@ -207,6 +212,11 @@
207
212
  "import": "./dist/esm/components/skeleton/index.js",
208
213
  "require": "./dist/cjs/components/skeleton/index.js"
209
214
  },
215
+ "./slider": {
216
+ "types": "./dist/types/components/slider/index.d.ts",
217
+ "import": "./dist/esm/components/slider/index.js",
218
+ "require": "./dist/cjs/components/slider/index.js"
219
+ },
210
220
  "./spinner": {
211
221
  "types": "./dist/types/components/spinner/index.d.ts",
212
222
  "import": "./dist/esm/components/spinner/index.js",
@@ -418,6 +428,8 @@
418
428
  "@seed-design/dom-utils": "^2.1.0",
419
429
  "@seed-design/react-date-picker": "1.2.0",
420
430
  "@seed-design/react-file-upload": "1.0.1",
431
+ "@seed-design/react-middle-truncate": "1.0.1",
432
+ "@seed-design/react-slider": "2.0.1",
421
433
  "@seed-design/react-time-picker": "1.0.0",
422
434
  "@zag-js/combobox": "^1.43.3",
423
435
  "@zag-js/dialog": "^1.43.3",