@hanzo/ui 8.0.60 → 8.0.62
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/backends/gui/input.cjs +4 -3
- package/dist/backends/gui/input.d.ts +10 -2
- package/dist/backends/gui/input.d.ts.map +1 -1
- package/dist/backends/gui/input.js +4 -3
- package/dist/backends/gui/input.js.map +1 -1
- package/dist/backends/gui/mask.cjs +20 -0
- package/dist/backends/gui/mask.d.ts +17 -0
- package/dist/backends/gui/mask.d.ts.map +1 -0
- package/dist/backends/gui/mask.js +17 -0
- package/dist/backends/gui/mask.js.map +1 -0
- package/dist/chat/Code.cjs +1 -1
- package/dist/chat/Code.d.ts.map +1 -1
- package/dist/chat/Code.js +1 -1
- package/dist/chat/Code.js.map +1 -1
- package/dist/core/css.cjs +114 -0
- package/dist/core/css.d.ts +46 -0
- package/dist/core/css.d.ts.map +1 -0
- package/dist/core/css.js +112 -0
- package/dist/core/css.js.map +1 -0
- package/dist/product/CopyButton.cjs +16 -2
- package/dist/product/CopyButton.d.ts +30 -3
- package/dist/product/CopyButton.d.ts.map +1 -1
- package/dist/product/CopyButton.js +18 -4
- package/dist/product/CopyButton.js.map +1 -1
- package/dist/product/DataTable.cjs +4 -4
- package/dist/product/DataTable.js +4 -4
- package/dist/product/DataTable.js.map +1 -1
- package/dist/product/FadeIn.cjs +1 -1
- package/dist/product/FadeIn.js +1 -1
- package/dist/product/FadeIn.js.map +1 -1
- package/dist/product/Field.cjs +3 -3
- package/dist/product/Field.d.ts +21 -1
- package/dist/product/Field.d.ts.map +1 -1
- package/dist/product/Field.js +3 -3
- package/dist/product/Field.js.map +1 -1
- package/dist/product/Fieldset.cjs +10 -2
- package/dist/product/Fieldset.d.ts +12 -1
- package/dist/product/Fieldset.d.ts.map +1 -1
- package/dist/product/Fieldset.js +10 -2
- package/dist/product/Fieldset.js.map +1 -1
- package/dist/product/Metric.cjs +7 -4
- package/dist/product/Metric.d.ts +8 -1
- package/dist/product/Metric.d.ts.map +1 -1
- package/dist/product/Metric.js +7 -4
- package/dist/product/Metric.js.map +1 -1
- package/dist/product/Pagination.cjs +9 -49
- package/dist/product/Pagination.d.ts +2 -10
- package/dist/product/Pagination.d.ts.map +1 -1
- package/dist/product/Pagination.js +6 -46
- package/dist/product/Pagination.js.map +1 -1
- package/dist/product/Reorder.cjs +1 -1
- package/dist/product/Reorder.js +1 -1
- package/dist/product/Reorder.js.map +1 -1
- package/dist/product/SecretInput.cjs +3 -13
- package/dist/product/SecretInput.d.ts +2 -11
- package/dist/product/SecretInput.d.ts.map +1 -1
- package/dist/product/SecretInput.js +6 -11
- package/dist/product/SecretInput.js.map +1 -1
- package/dist/product/SlideOver.cjs +2 -2
- package/dist/product/SlideOver.js +2 -2
- package/dist/product/SlideOver.js.map +1 -1
- package/dist/product/StatusTag.cjs +10 -39
- package/dist/product/StatusTag.d.ts +6 -2
- package/dist/product/StatusTag.d.ts.map +1 -1
- package/dist/product/StatusTag.js +10 -39
- package/dist/product/StatusTag.js.map +1 -1
- package/dist/product/UserMenu.cjs +4 -10
- package/dist/product/UserMenu.d.ts +2 -3
- package/dist/product/UserMenu.d.ts.map +1 -1
- package/dist/product/UserMenu.js +5 -8
- package/dist/product/UserMenu.js.map +1 -1
- package/dist/product/animatedLogo.logic.cjs +1 -1
- package/dist/product/animatedLogo.logic.js +1 -1
- package/dist/product/brand.cjs +1 -1
- package/dist/product/brand.js +1 -1
- package/dist/product/combobox/filter.cjs +1 -1
- package/dist/product/combobox/filter.js +1 -1
- package/dist/product/index.cjs +14 -3
- package/dist/product/index.d.ts +1 -1
- package/dist/product/index.d.ts.map +1 -1
- package/dist/product/index.js +13 -1
- package/dist/product/index.js.map +1 -1
- package/dist/product/name.cjs +17 -0
- package/dist/product/name.d.ts +10 -0
- package/dist/product/name.d.ts.map +1 -0
- package/dist/product/name.js +15 -0
- package/dist/product/name.js.map +1 -0
- package/dist/product/pages.cjs +57 -0
- package/dist/product/pages.d.ts +28 -0
- package/dist/product/pages.d.ts.map +1 -0
- package/dist/product/pages.js +54 -0
- package/dist/product/pages.js.map +1 -0
- package/dist/product/pure.cjs +63 -0
- package/dist/product/pure.d.ts +9 -0
- package/dist/product/pure.d.ts.map +1 -0
- package/dist/product/pure.js +38 -0
- package/dist/product/pure.js.map +1 -0
- package/dist/product/scope.cjs +1 -1
- package/dist/product/scope.js +1 -1
- package/dist/product/social/SocialResource.cjs +1 -1
- package/dist/product/social/SocialResource.js +1 -1
- package/dist/product/social/SocialResource.js.map +1 -1
- package/dist/product/social/SocialSummaryBar.cjs +1 -1
- package/dist/product/social/SocialSummaryBar.js +1 -1
- package/dist/product/social/SocialSummaryBar.js.map +1 -1
- package/dist/product/tone.cjs +105 -0
- package/dist/product/tone.d.ts +52 -0
- package/dist/product/tone.d.ts.map +1 -0
- package/dist/product/tone.js +102 -0
- package/dist/product/tone.js.map +1 -0
- package/dist/styles/motion.css +52 -17
- package/dist/styles.css +53 -18
- package/package.json +35 -7
|
@@ -16,6 +16,7 @@ const react_1 = require("react");
|
|
|
16
16
|
const slot_1 = require("./slot.cjs");
|
|
17
17
|
const gesture_1 = require("./gesture.cjs");
|
|
18
18
|
const focus_1 = require("./focus.cjs");
|
|
19
|
+
const mask_1 = require("./mask.cjs");
|
|
19
20
|
const HEIGHT = 36;
|
|
20
21
|
const GUTTER = 12;
|
|
21
22
|
/** Width reserved for an adornment inside the field. */
|
|
@@ -28,11 +29,11 @@ const well = (side) => ({
|
|
|
28
29
|
items: 'center',
|
|
29
30
|
justify: 'center',
|
|
30
31
|
});
|
|
31
|
-
const Input = /* @__PURE__ */ (0, react_1.forwardRef)(function Input({ startAdornment, endAdornment,
|
|
32
|
+
const Input = /* @__PURE__ */ (0, react_1.forwardRef)(function Input({ startAdornment, endAdornment, reveal = true, type, secureTextEntry, ...props }, ref) {
|
|
32
33
|
const [revealed, setRevealed] = (0, react_1.useState)(false);
|
|
33
34
|
const isPassword = type === 'password' || secureTextEntry === true;
|
|
34
|
-
const toggle = isPassword &&
|
|
35
|
-
const field = ((0, jsx_runtime_1.jsx)(gui_1.Input, { ref: ref, ...(0, slot_1.slot)('input'),
|
|
35
|
+
const toggle = isPassword && reveal;
|
|
36
|
+
const field = ((0, jsx_runtime_1.jsx)(gui_1.Input, { ref: ref, ...(0, slot_1.slot)('input'), ...(isPassword ? (0, mask_1.masked)(!revealed) : { type, secureTextEntry }), height: HEIGHT, width: "100%", minW: 0, rounded: "$3", bg: "transparent", borderWidth: 1, borderColor: "$borderColor", ...focus_1.FOCUS, placeholderTextColor: "$color10", fontSize: "$3", pl: startAdornment ? WELL : GUTTER, pr: endAdornment || toggle ? WELL : GUTTER, ...props }));
|
|
36
37
|
if (!startAdornment && !endAdornment && !toggle)
|
|
37
38
|
return field;
|
|
38
39
|
return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { position: "relative", width: "100%", items: "center", children: [startAdornment ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...well('l'), pointerEvents: "none", opacity: 0.6, children: startAdornment })) : null, field, toggle ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...well('r'), cursor: "pointer", ...(0, gesture_1.touch)(20), onPress: () => setRevealed((v) => !v), "aria-label": revealed ? 'Hide password' : 'Show password', children: revealed ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.EyeOff, { size: 16 }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Eye, { size: 16 }) })) : endAdornment ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...well('r'), opacity: 0.6, children: endAdornment })) : null] }));
|
|
@@ -12,8 +12,16 @@ export type InputProps = Omit<ComponentProps<typeof GuiInput>, 'children'> & {
|
|
|
12
12
|
startAdornment?: ReactNode;
|
|
13
13
|
/** Optional trailing affordance rendered inside the field. */
|
|
14
14
|
endAdornment?: ReactNode;
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Whether a masked field draws its own show/hide eye. Default true.
|
|
17
|
+
*
|
|
18
|
+
* `false` when the caller owns the reveal — `SecretInput` does, and so does
|
|
19
|
+
* any field that masks locally — because two controls over one boolean is a
|
|
20
|
+
* field with two states that disagree: press ours and the caller's icon still
|
|
21
|
+
* reads "show", press theirs and ours does. The field is masked by whichever
|
|
22
|
+
* was pressed last and neither control can say which.
|
|
23
|
+
*/
|
|
24
|
+
reveal?: boolean;
|
|
17
25
|
};
|
|
18
26
|
declare const Input: import("react").ForwardRefExoticComponent<Omit<InputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
19
27
|
export { Input };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/input.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAU,MAAM,YAAY,CAAA;AAEtD,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/input.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAU,MAAM,YAAY,CAAA;AAEtD,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAWjF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC,GAAG;IAC3E,yEAAyE;IACzE,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAYD,QAAA,MAAM,KAAK,sHAmET,CAAA;AAEF,OAAO,EAAE,KAAK,EAAE,CAAA"}
|
|
@@ -13,6 +13,7 @@ import { forwardRef, useState } from 'react';
|
|
|
13
13
|
import { slot } from './slot.js';
|
|
14
14
|
import { touch } from './gesture.js';
|
|
15
15
|
import { FOCUS } from './focus.js';
|
|
16
|
+
import { masked } from './mask.js';
|
|
16
17
|
const HEIGHT = 36;
|
|
17
18
|
const GUTTER = 12;
|
|
18
19
|
/** Width reserved for an adornment inside the field. */
|
|
@@ -25,11 +26,11 @@ const well = (side) => ({
|
|
|
25
26
|
items: 'center',
|
|
26
27
|
justify: 'center',
|
|
27
28
|
});
|
|
28
|
-
const Input = /* @__PURE__ */ forwardRef(function Input({ startAdornment, endAdornment,
|
|
29
|
+
const Input = /* @__PURE__ */ forwardRef(function Input({ startAdornment, endAdornment, reveal = true, type, secureTextEntry, ...props }, ref) {
|
|
29
30
|
const [revealed, setRevealed] = useState(false);
|
|
30
31
|
const isPassword = type === 'password' || secureTextEntry === true;
|
|
31
|
-
const toggle = isPassword &&
|
|
32
|
-
const field = (_jsx(GuiInput, { ref: ref, ...slot('input'),
|
|
32
|
+
const toggle = isPassword && reveal;
|
|
33
|
+
const field = (_jsx(GuiInput, { ref: ref, ...slot('input'), ...(isPassword ? masked(!revealed) : { type, secureTextEntry }), height: HEIGHT, width: "100%", minW: 0, rounded: "$3", bg: "transparent", borderWidth: 1, borderColor: "$borderColor", ...FOCUS, placeholderTextColor: "$color10", fontSize: "$3", pl: startAdornment ? WELL : GUTTER, pr: endAdornment || toggle ? WELL : GUTTER, ...props }));
|
|
33
34
|
if (!startAdornment && !endAdornment && !toggle)
|
|
34
35
|
return field;
|
|
35
36
|
return (_jsxs(XStack, { position: "relative", width: "100%", items: "center", children: [startAdornment ? (_jsx(XStack, { ...well('l'), pointerEvents: "none", opacity: 0.6, children: startAdornment })) : null, field, toggle ? (_jsx(XStack, { ...well('r'), cursor: "pointer", ...touch(20), onPress: () => setRevealed((v) => !v), "aria-label": revealed ? 'Hide password' : 'Show password', children: revealed ? _jsx(EyeOff, { size: 16 }) : _jsx(Eye, { size: 16 }) })) : endAdornment ? (_jsx(XStack, { ...well('r'), opacity: 0.6, children: endAdornment })) : null] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/backends/gui/input.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAuC,MAAM,OAAO,CAAA;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,MAAM,MAAM,GAAG,EAAE,CAAA;AACjB,MAAM,MAAM,GAAG,EAAE,CAAA;AACjB,wDAAwD;AACxD,MAAM,IAAI,GAAG,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/backends/gui/input.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Masking, on both platforms.
|
|
4
|
+
*
|
|
5
|
+
* `secureTextEntry` is React Native's spelling and gui DROPS it on web — an
|
|
6
|
+
* input carrying only that prop renders the secret in plain text, which is the
|
|
7
|
+
* exact opposite of what the caller asked for. `type="password"` is the web
|
|
8
|
+
* spelling and gui forwards it, being an unrecognised prop. Native ignores
|
|
9
|
+
* `type` for the same reason. So masking needs BOTH names, and neither alone is
|
|
10
|
+
* safe. `readOnly` is the same story: `editable={false}` is dropped on web.
|
|
11
|
+
*
|
|
12
|
+
* A prop object is a value, so this needs no DOM: `@hanzo/ui/product/pure`
|
|
13
|
+
* exports it, and a consumer can assert that its own field really masks without
|
|
14
|
+
* mounting one.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.masked = void 0;
|
|
18
|
+
/** The props that mask (or unmask) a field on web AND native. */
|
|
19
|
+
const masked = (on) => (on ? { secureTextEntry: true, type: 'password' } : { secureTextEntry: false, type: 'text' });
|
|
20
|
+
exports.masked = masked;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Masking, on both platforms.
|
|
3
|
+
*
|
|
4
|
+
* `secureTextEntry` is React Native's spelling and gui DROPS it on web — an
|
|
5
|
+
* input carrying only that prop renders the secret in plain text, which is the
|
|
6
|
+
* exact opposite of what the caller asked for. `type="password"` is the web
|
|
7
|
+
* spelling and gui forwards it, being an unrecognised prop. Native ignores
|
|
8
|
+
* `type` for the same reason. So masking needs BOTH names, and neither alone is
|
|
9
|
+
* safe. `readOnly` is the same story: `editable={false}` is dropped on web.
|
|
10
|
+
*
|
|
11
|
+
* A prop object is a value, so this needs no DOM: `@hanzo/ui/product/pure`
|
|
12
|
+
* exports it, and a consumer can assert that its own field really masks without
|
|
13
|
+
* mounting one.
|
|
14
|
+
*/
|
|
15
|
+
/** The props that mask (or unmask) a field on web AND native. */
|
|
16
|
+
export declare const masked: (on: boolean) => object;
|
|
17
|
+
//# sourceMappingURL=mask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/mask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iEAAiE;AACjE,eAAO,MAAM,MAAM,GAAI,IAAI,OAAO,KACiE,MAAM,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Masking, on both platforms.
|
|
3
|
+
*
|
|
4
|
+
* `secureTextEntry` is React Native's spelling and gui DROPS it on web — an
|
|
5
|
+
* input carrying only that prop renders the secret in plain text, which is the
|
|
6
|
+
* exact opposite of what the caller asked for. `type="password"` is the web
|
|
7
|
+
* spelling and gui forwards it, being an unrecognised prop. Native ignores
|
|
8
|
+
* `type` for the same reason. So masking needs BOTH names, and neither alone is
|
|
9
|
+
* safe. `readOnly` is the same story: `editable={false}` is dropped on web.
|
|
10
|
+
*
|
|
11
|
+
* A prop object is a value, so this needs no DOM: `@hanzo/ui/product/pure`
|
|
12
|
+
* exports it, and a consumer can assert that its own field really masks without
|
|
13
|
+
* mounting one.
|
|
14
|
+
*/
|
|
15
|
+
/** The props that mask (or unmask) a field on web AND native. */
|
|
16
|
+
export const masked = (on) => (on ? { secureTextEntry: true, type: 'password' } : { secureTextEntry: false, type: 'text' });
|
|
17
|
+
//# sourceMappingURL=mask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.js","sourceRoot":"","sources":["../../../src/backends/gui/mask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAAW,EAAE,EAAE,CACpC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAW,CAAA"}
|
package/dist/chat/Code.cjs
CHANGED
|
@@ -32,5 +32,5 @@ const MONO = {
|
|
|
32
32
|
};
|
|
33
33
|
function Code({ children, language = 'text', value, actions }) {
|
|
34
34
|
const text = value ?? (typeof children === 'string' ? children : '');
|
|
35
|
-
return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('code'), width: "100%", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$color2", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: "$1", px: "$3", py: "$1.5", borderBottomWidth: 1, borderColor: "$borderColor", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", style: MONO, color: "$
|
|
35
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('code'), width: "100%", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$color2", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: "$1", px: "$3", py: "$1.5", borderBottomWidth: 1, borderColor: "$borderColor", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", style: MONO, color: "$color11", children: language }), (0, jsx_runtime_1.jsx)(gui_1.XStack, { flex: 1 }), actions, text ? (0, jsx_runtime_1.jsx)(CopyButton_1.CopyButton, { value: text }) : null] }), (0, jsx_runtime_1.jsx)(gui_1.YStack, { px: "$3", py: "$2.5", children: (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", style: MONO, lineHeight: 20, children: children }) })] }));
|
|
36
36
|
}
|
package/dist/chat/Code.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Code.d.ts","sourceRoot":"","sources":["../../src/chat/Code.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAkBtC,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"Code.d.ts","sourceRoot":"","sources":["../../src/chat/Code.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAkBtC,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAAS,2CA0C9E"}
|
package/dist/chat/Code.js
CHANGED
|
@@ -29,6 +29,6 @@ const MONO = {
|
|
|
29
29
|
};
|
|
30
30
|
export function Code({ children, language = 'text', value, actions }) {
|
|
31
31
|
const text = value ?? (typeof children === 'string' ? children : '');
|
|
32
|
-
return (_jsxs(YStack, { ...slot('code'), width: "100%", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$color2", overflow: "hidden", children: [_jsxs(XStack, { items: "center", gap: "$1", px: "$3", py: "$1.5", borderBottomWidth: 1, borderColor: "$borderColor", children: [_jsx(SizableText, { size: "$1", style: MONO, color: "$
|
|
32
|
+
return (_jsxs(YStack, { ...slot('code'), width: "100%", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$color2", overflow: "hidden", children: [_jsxs(XStack, { items: "center", gap: "$1", px: "$3", py: "$1.5", borderBottomWidth: 1, borderColor: "$borderColor", children: [_jsx(SizableText, { size: "$1", style: MONO, color: "$color11", children: language }), _jsx(XStack, { flex: 1 }), actions, text ? _jsx(CopyButton, { value: text }) : null] }), _jsx(YStack, { px: "$3", py: "$2.5", children: _jsx(SizableText, { size: "$1", style: MONO, lineHeight: 20, children: children }) })] }));
|
|
33
33
|
}
|
|
34
34
|
//# sourceMappingURL=Code.js.map
|
package/dist/chat/Code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/chat/Code.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,IAAI,GAAG;IACX,UAAU,EAAE,wEAAwE;CAC5E,CAAA;AAYV,MAAM,UAAU,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,EAAa;IAC7E,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAEpE,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,MAAM,CAAC,EAChB,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,IAAI,EACZ,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,EAAE,EAAC,SAAS,EACZ,QAAQ,EAAC,QAAQ,aAEjB,MAAC,MAAM,IACL,KAAK,EAAC,QAAQ,EACd,GAAG,EAAC,IAAI,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,MAAM,EACT,iBAAiB,EAAE,CAAC,EACpB,WAAW,EAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/chat/Code.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,IAAI,GAAG;IACX,UAAU,EAAE,wEAAwE;CAC5E,CAAA;AAYV,MAAM,UAAU,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,EAAa;IAC7E,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAEpE,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,MAAM,CAAC,EAChB,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,IAAI,EACZ,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,EAAE,EAAC,SAAS,EACZ,QAAQ,EAAC,QAAQ,aAEjB,MAAC,MAAM,IACL,KAAK,EAAC,QAAQ,EACd,GAAG,EAAC,IAAI,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,MAAM,EACT,iBAAiB,EAAE,CAAC,EACpB,WAAW,EAAC,cAAc,aAQ1B,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC,UAAU,YACjD,QAAQ,GACG,EACd,KAAC,MAAM,IAAC,IAAI,EAAE,CAAC,GAAI,EAClB,OAAO,EACP,IAAI,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,KAAK,EAAE,IAAI,GAAI,CAAC,CAAC,CAAC,IAAI,IACnC,EAET,KAAC,MAAM,IAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,MAAM,YACvB,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,YAC/C,QAAQ,GACG,GACP,IACF,CACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Substitute a CSS value's `var()` references — the step jsdom does not take.
|
|
4
|
+
*
|
|
5
|
+
* The theme rungs read a token and carry the literal behind it:
|
|
6
|
+
*
|
|
7
|
+
* borderColor: 'var(--border, rgb(255 255 255 / .10))'
|
|
8
|
+
*
|
|
9
|
+
* A browser resolves that: `--border` if a stylesheet declares it, the literal
|
|
10
|
+
* otherwise. jsdom resolves nothing — `getComputedStyle(el).borderColor` hands
|
|
11
|
+
* back the `var(...)` text verbatim — so every consumer that tried to assert the
|
|
12
|
+
* contrast of a border in a unit test compared a colour to a function call and
|
|
13
|
+
* either asserted the wrong thing or gave up and asserted nothing.
|
|
14
|
+
*
|
|
15
|
+
* Neither half of that is worth fixing by weakening the rung. The `var()` first
|
|
16
|
+
* is what lets a host that mounts @hanzo/design's sheet follow the live cascade
|
|
17
|
+
* and invert with it; the literal behind it is what keeps a host that mounts
|
|
18
|
+
* neither on the value the WCAG audit measured. So the value stays, and the TEST
|
|
19
|
+
* gets the resolver:
|
|
20
|
+
*
|
|
21
|
+
* import { substitute } from '@hanzo/ui/css'
|
|
22
|
+
*
|
|
23
|
+
* const border = substitute(getComputedStyle(el).borderColor)
|
|
24
|
+
* expect(contrast(border, bg)).toBeGreaterThan(3)
|
|
25
|
+
*
|
|
26
|
+
* With no `vars` map that is exactly right, and not an approximation: jsdom
|
|
27
|
+
* mounts no design stylesheet, so nothing declares `--border`, so the fallback
|
|
28
|
+
* IS the value a browser would compute under the same conditions. Pass a map to
|
|
29
|
+
* model a host that declares its own tokens.
|
|
30
|
+
*
|
|
31
|
+
* Pure, dependency-free and DOM-free, so it loads under any runner — which is
|
|
32
|
+
* why it is `@hanzo/ui/css` and not part of `@hanzo/ui/core`. That subpath is
|
|
33
|
+
* ESM-only on purpose (@hanzo/design, which its tokens come from, publishes no
|
|
34
|
+
* `require` condition), and a jest consumer is exactly the caller that needs
|
|
35
|
+
* this one. Importing nothing is what lets it ship both.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.substitute = substitute;
|
|
39
|
+
/** A value that references a custom property nothing declares is invalid at
|
|
40
|
+
* computed-value time: CSS drops the WHOLE declaration, not just the `var()`.
|
|
41
|
+
* Carried as a sentinel so the outer call can return '' for the whole value. */
|
|
42
|
+
const INVALID = Symbol('invalid');
|
|
43
|
+
/** Index of the `)` closing the `(` at `open`, or -1 if unbalanced. */
|
|
44
|
+
function close(value, open) {
|
|
45
|
+
let depth = 0;
|
|
46
|
+
for (let i = open; i < value.length; i++) {
|
|
47
|
+
if (value[i] === '(')
|
|
48
|
+
depth++;
|
|
49
|
+
else if (value[i] === ')' && --depth === 0)
|
|
50
|
+
return i;
|
|
51
|
+
}
|
|
52
|
+
return -1;
|
|
53
|
+
}
|
|
54
|
+
/** Index of the first comma at depth 0, or -1. `var()` takes at most one
|
|
55
|
+
* fallback and the fallback may itself contain commas — `rgb(255 255 255 / .1)`
|
|
56
|
+
* does not, but `var(--a, var(--b, red))` does — so only the FIRST counts. */
|
|
57
|
+
function comma(inner) {
|
|
58
|
+
let depth = 0;
|
|
59
|
+
for (let i = 0; i < inner.length; i++) {
|
|
60
|
+
if (inner[i] === '(')
|
|
61
|
+
depth++;
|
|
62
|
+
else if (inner[i] === ')')
|
|
63
|
+
depth--;
|
|
64
|
+
else if (inner[i] === ',' && depth === 0)
|
|
65
|
+
return i;
|
|
66
|
+
}
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
function expand(value, vars, seen) {
|
|
70
|
+
const start = value.indexOf('var(');
|
|
71
|
+
if (start === -1)
|
|
72
|
+
return value;
|
|
73
|
+
const end = close(value, start + 3);
|
|
74
|
+
if (end === -1)
|
|
75
|
+
return value; // unbalanced — not a value we can reason about
|
|
76
|
+
const inner = value.slice(start + 4, end);
|
|
77
|
+
const split = comma(inner);
|
|
78
|
+
const name = (split === -1 ? inner : inner.slice(0, split)).trim();
|
|
79
|
+
const fallback = split === -1 ? undefined : inner.slice(split + 1).trim();
|
|
80
|
+
let resolved;
|
|
81
|
+
if (seen.has(name)) {
|
|
82
|
+
// A cycle (`--a: var(--b)`, `--b: var(--a)`) is invalid at computed-value
|
|
83
|
+
// time too, and left unguarded it is an infinite recursion.
|
|
84
|
+
resolved = INVALID;
|
|
85
|
+
}
|
|
86
|
+
else if (name in vars) {
|
|
87
|
+
resolved = expand(vars[name], vars, new Set(seen).add(name));
|
|
88
|
+
}
|
|
89
|
+
else if (fallback !== undefined) {
|
|
90
|
+
resolved = expand(fallback, vars, seen);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
resolved = INVALID;
|
|
94
|
+
}
|
|
95
|
+
if (resolved === INVALID)
|
|
96
|
+
return INVALID;
|
|
97
|
+
const rest = expand(value.slice(end + 1), vars, seen);
|
|
98
|
+
if (rest === INVALID)
|
|
99
|
+
return INVALID;
|
|
100
|
+
return value.slice(0, start) + resolved + rest;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* `value` with every `var()` reference replaced by what it resolves to.
|
|
104
|
+
*
|
|
105
|
+
* `vars` maps custom-property names (with the leading `--`) to their declared
|
|
106
|
+
* values and defaults to none, which is the jsdom case. Returns '' when the
|
|
107
|
+
* value references something undeclared with no fallback, or references itself
|
|
108
|
+
* — both are invalid at computed-value time, and a browser drops the whole
|
|
109
|
+
* declaration rather than part of it.
|
|
110
|
+
*/
|
|
111
|
+
function substitute(value, vars = {}) {
|
|
112
|
+
const out = expand(value, vars, new Set());
|
|
113
|
+
return out === INVALID ? '' : out;
|
|
114
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Substitute a CSS value's `var()` references — the step jsdom does not take.
|
|
3
|
+
*
|
|
4
|
+
* The theme rungs read a token and carry the literal behind it:
|
|
5
|
+
*
|
|
6
|
+
* borderColor: 'var(--border, rgb(255 255 255 / .10))'
|
|
7
|
+
*
|
|
8
|
+
* A browser resolves that: `--border` if a stylesheet declares it, the literal
|
|
9
|
+
* otherwise. jsdom resolves nothing — `getComputedStyle(el).borderColor` hands
|
|
10
|
+
* back the `var(...)` text verbatim — so every consumer that tried to assert the
|
|
11
|
+
* contrast of a border in a unit test compared a colour to a function call and
|
|
12
|
+
* either asserted the wrong thing or gave up and asserted nothing.
|
|
13
|
+
*
|
|
14
|
+
* Neither half of that is worth fixing by weakening the rung. The `var()` first
|
|
15
|
+
* is what lets a host that mounts @hanzo/design's sheet follow the live cascade
|
|
16
|
+
* and invert with it; the literal behind it is what keeps a host that mounts
|
|
17
|
+
* neither on the value the WCAG audit measured. So the value stays, and the TEST
|
|
18
|
+
* gets the resolver:
|
|
19
|
+
*
|
|
20
|
+
* import { substitute } from '@hanzo/ui/css'
|
|
21
|
+
*
|
|
22
|
+
* const border = substitute(getComputedStyle(el).borderColor)
|
|
23
|
+
* expect(contrast(border, bg)).toBeGreaterThan(3)
|
|
24
|
+
*
|
|
25
|
+
* With no `vars` map that is exactly right, and not an approximation: jsdom
|
|
26
|
+
* mounts no design stylesheet, so nothing declares `--border`, so the fallback
|
|
27
|
+
* IS the value a browser would compute under the same conditions. Pass a map to
|
|
28
|
+
* model a host that declares its own tokens.
|
|
29
|
+
*
|
|
30
|
+
* Pure, dependency-free and DOM-free, so it loads under any runner — which is
|
|
31
|
+
* why it is `@hanzo/ui/css` and not part of `@hanzo/ui/core`. That subpath is
|
|
32
|
+
* ESM-only on purpose (@hanzo/design, which its tokens come from, publishes no
|
|
33
|
+
* `require` condition), and a jest consumer is exactly the caller that needs
|
|
34
|
+
* this one. Importing nothing is what lets it ship both.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* `value` with every `var()` reference replaced by what it resolves to.
|
|
38
|
+
*
|
|
39
|
+
* `vars` maps custom-property names (with the leading `--`) to their declared
|
|
40
|
+
* values and defaults to none, which is the jsdom case. Returns '' when the
|
|
41
|
+
* value references something undeclared with no fallback, or references itself
|
|
42
|
+
* — both are invalid at computed-value time, and a browser drops the whole
|
|
43
|
+
* declaration rather than part of it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function substitute(value: string, vars?: Record<string, string>): string;
|
|
46
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/core/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA8DH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAGnF"}
|
package/dist/core/css.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Substitute a CSS value's `var()` references — the step jsdom does not take.
|
|
3
|
+
*
|
|
4
|
+
* The theme rungs read a token and carry the literal behind it:
|
|
5
|
+
*
|
|
6
|
+
* borderColor: 'var(--border, rgb(255 255 255 / .10))'
|
|
7
|
+
*
|
|
8
|
+
* A browser resolves that: `--border` if a stylesheet declares it, the literal
|
|
9
|
+
* otherwise. jsdom resolves nothing — `getComputedStyle(el).borderColor` hands
|
|
10
|
+
* back the `var(...)` text verbatim — so every consumer that tried to assert the
|
|
11
|
+
* contrast of a border in a unit test compared a colour to a function call and
|
|
12
|
+
* either asserted the wrong thing or gave up and asserted nothing.
|
|
13
|
+
*
|
|
14
|
+
* Neither half of that is worth fixing by weakening the rung. The `var()` first
|
|
15
|
+
* is what lets a host that mounts @hanzo/design's sheet follow the live cascade
|
|
16
|
+
* and invert with it; the literal behind it is what keeps a host that mounts
|
|
17
|
+
* neither on the value the WCAG audit measured. So the value stays, and the TEST
|
|
18
|
+
* gets the resolver:
|
|
19
|
+
*
|
|
20
|
+
* import { substitute } from '@hanzo/ui/css'
|
|
21
|
+
*
|
|
22
|
+
* const border = substitute(getComputedStyle(el).borderColor)
|
|
23
|
+
* expect(contrast(border, bg)).toBeGreaterThan(3)
|
|
24
|
+
*
|
|
25
|
+
* With no `vars` map that is exactly right, and not an approximation: jsdom
|
|
26
|
+
* mounts no design stylesheet, so nothing declares `--border`, so the fallback
|
|
27
|
+
* IS the value a browser would compute under the same conditions. Pass a map to
|
|
28
|
+
* model a host that declares its own tokens.
|
|
29
|
+
*
|
|
30
|
+
* Pure, dependency-free and DOM-free, so it loads under any runner — which is
|
|
31
|
+
* why it is `@hanzo/ui/css` and not part of `@hanzo/ui/core`. That subpath is
|
|
32
|
+
* ESM-only on purpose (@hanzo/design, which its tokens come from, publishes no
|
|
33
|
+
* `require` condition), and a jest consumer is exactly the caller that needs
|
|
34
|
+
* this one. Importing nothing is what lets it ship both.
|
|
35
|
+
*/
|
|
36
|
+
/** A value that references a custom property nothing declares is invalid at
|
|
37
|
+
* computed-value time: CSS drops the WHOLE declaration, not just the `var()`.
|
|
38
|
+
* Carried as a sentinel so the outer call can return '' for the whole value. */
|
|
39
|
+
const INVALID = Symbol('invalid');
|
|
40
|
+
/** Index of the `)` closing the `(` at `open`, or -1 if unbalanced. */
|
|
41
|
+
function close(value, open) {
|
|
42
|
+
let depth = 0;
|
|
43
|
+
for (let i = open; i < value.length; i++) {
|
|
44
|
+
if (value[i] === '(')
|
|
45
|
+
depth++;
|
|
46
|
+
else if (value[i] === ')' && --depth === 0)
|
|
47
|
+
return i;
|
|
48
|
+
}
|
|
49
|
+
return -1;
|
|
50
|
+
}
|
|
51
|
+
/** Index of the first comma at depth 0, or -1. `var()` takes at most one
|
|
52
|
+
* fallback and the fallback may itself contain commas — `rgb(255 255 255 / .1)`
|
|
53
|
+
* does not, but `var(--a, var(--b, red))` does — so only the FIRST counts. */
|
|
54
|
+
function comma(inner) {
|
|
55
|
+
let depth = 0;
|
|
56
|
+
for (let i = 0; i < inner.length; i++) {
|
|
57
|
+
if (inner[i] === '(')
|
|
58
|
+
depth++;
|
|
59
|
+
else if (inner[i] === ')')
|
|
60
|
+
depth--;
|
|
61
|
+
else if (inner[i] === ',' && depth === 0)
|
|
62
|
+
return i;
|
|
63
|
+
}
|
|
64
|
+
return -1;
|
|
65
|
+
}
|
|
66
|
+
function expand(value, vars, seen) {
|
|
67
|
+
const start = value.indexOf('var(');
|
|
68
|
+
if (start === -1)
|
|
69
|
+
return value;
|
|
70
|
+
const end = close(value, start + 3);
|
|
71
|
+
if (end === -1)
|
|
72
|
+
return value; // unbalanced — not a value we can reason about
|
|
73
|
+
const inner = value.slice(start + 4, end);
|
|
74
|
+
const split = comma(inner);
|
|
75
|
+
const name = (split === -1 ? inner : inner.slice(0, split)).trim();
|
|
76
|
+
const fallback = split === -1 ? undefined : inner.slice(split + 1).trim();
|
|
77
|
+
let resolved;
|
|
78
|
+
if (seen.has(name)) {
|
|
79
|
+
// A cycle (`--a: var(--b)`, `--b: var(--a)`) is invalid at computed-value
|
|
80
|
+
// time too, and left unguarded it is an infinite recursion.
|
|
81
|
+
resolved = INVALID;
|
|
82
|
+
}
|
|
83
|
+
else if (name in vars) {
|
|
84
|
+
resolved = expand(vars[name], vars, new Set(seen).add(name));
|
|
85
|
+
}
|
|
86
|
+
else if (fallback !== undefined) {
|
|
87
|
+
resolved = expand(fallback, vars, seen);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
resolved = INVALID;
|
|
91
|
+
}
|
|
92
|
+
if (resolved === INVALID)
|
|
93
|
+
return INVALID;
|
|
94
|
+
const rest = expand(value.slice(end + 1), vars, seen);
|
|
95
|
+
if (rest === INVALID)
|
|
96
|
+
return INVALID;
|
|
97
|
+
return value.slice(0, start) + resolved + rest;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* `value` with every `var()` reference replaced by what it resolves to.
|
|
101
|
+
*
|
|
102
|
+
* `vars` maps custom-property names (with the leading `--`) to their declared
|
|
103
|
+
* values and defaults to none, which is the jsdom case. Returns '' when the
|
|
104
|
+
* value references something undeclared with no fallback, or references itself
|
|
105
|
+
* — both are invalid at computed-value time, and a browser drops the whole
|
|
106
|
+
* declaration rather than part of it.
|
|
107
|
+
*/
|
|
108
|
+
export function substitute(value, vars = {}) {
|
|
109
|
+
const out = expand(value, vars, new Set());
|
|
110
|
+
return out === INVALID ? '' : out;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/core/css.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ const slot_1 = require("../backends/gui/slot.cjs");
|
|
|
25
25
|
const instrument_1 = require("./instrument.cjs");
|
|
26
26
|
/** How long the control shows its confirmation, in ms. */
|
|
27
27
|
const CONFIRM = 2000;
|
|
28
|
-
function CopyButton({ value, label
|
|
28
|
+
function CopyButton({ value, children, label, size = 24, id }) {
|
|
29
29
|
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
30
30
|
const timer = (0, react_1.useRef)(undefined);
|
|
31
31
|
const track = (0, instrument_1.useEmit)();
|
|
@@ -50,5 +50,19 @@ function CopyButton({ value, label = 'Copy', size = 24, id }) {
|
|
|
50
50
|
track({ component: 'CopyButton', action: 'error', id });
|
|
51
51
|
});
|
|
52
52
|
};
|
|
53
|
-
|
|
53
|
+
const name = label ?? (typeof children === 'string' ? children : 'Copy');
|
|
54
|
+
const glyph = Math.round(size * 0.58);
|
|
55
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.XStack
|
|
56
|
+
// The label form is a pill that sizes to its text; the icon form is the
|
|
57
|
+
// square it has always been. `height` is shared so a labeled control lines
|
|
58
|
+
// up with an unlabeled one in the same row.
|
|
59
|
+
, {
|
|
60
|
+
// The label form is a pill that sizes to its text; the icon form is the
|
|
61
|
+
// square it has always been. `height` is shared so a labeled control lines
|
|
62
|
+
// up with an unlabeled one in the same row.
|
|
63
|
+
width: children == null ? size : undefined, height: size, px: children == null ? undefined : '$2', gap: children == null ? undefined : '$1.5', items: "center", justify: "center", rounded: "$2", cursor: "pointer", opacity: 0.7, onPress: copy, role: "button", tabIndex: 0, "aria-label": copied ? 'Copied' : name, ...(0, slot_1.tip)(copied ? 'Copied' : name), hoverStyle: { bg: '$color4', opacity: 1 }, pressStyle: { bg: '$color5' }, children: [copied ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Check, { size: glyph }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Copy, { size: glyph }), children == null ? null : (
|
|
64
|
+
// The word carries the confirmation too. A tick alone, at 14px, beside
|
|
65
|
+
// text that did not change is the smallest possible way to say the thing
|
|
66
|
+
// the control exists to say.
|
|
67
|
+
(0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$color12", numberOfLines: 1, children: copied ? 'Copied' : children }))] }));
|
|
54
68
|
}
|
|
@@ -1,12 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CopyButton — copy with a confirmation tick.
|
|
3
|
+
*
|
|
4
|
+
* The tick is the point. A control that looks identical before and after leaves
|
|
5
|
+
* the reader unsure whether it fired, and the usual response is to press it
|
|
6
|
+
* again. Reverts after `CONFIRM`, and clears its timer on unmount so it cannot
|
|
7
|
+
* set state on a component that is gone.
|
|
8
|
+
*
|
|
9
|
+
* It lived inside `chat/Code.tsx` and was reachable only as `@hanzo/ui/chat`.
|
|
10
|
+
* Nobody looks in a chat module for a copy button, so every surface wrote its
|
|
11
|
+
* own — an API key here, a deposit address there, a referral link, a wire
|
|
12
|
+
* instruction — each with its own confirmation window, or none. Copying text is
|
|
13
|
+
* not a chat idea; it belongs to the product layer, and `Code` now imports it
|
|
14
|
+
* from here rather than owning it.
|
|
15
|
+
*/
|
|
16
|
+
import { type ReactNode } from 'react';
|
|
1
17
|
export interface CopyButtonProps {
|
|
2
18
|
/** The text placed on the clipboard. */
|
|
3
19
|
value: string;
|
|
4
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Visible text beside the glyph — "Copy key", "Copy address". Omit for the
|
|
22
|
+
* bare square the icon form has always been.
|
|
23
|
+
*
|
|
24
|
+
* There is no second prop and no variant to pick, because the two forms differ
|
|
25
|
+
* in exactly one thing: whether the label is drawn. A control standing alone —
|
|
26
|
+
* under a minted key, beside a wire instruction — has no neighbours to explain
|
|
27
|
+
* it, and an unlabeled glyph there is a guess; inside a code header or a table
|
|
28
|
+
* row the label is noise. Passing the text is what asks for it.
|
|
29
|
+
*/
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
/** The tooltip and the accessible name. Defaults to the visible text, else "Copy". */
|
|
5
32
|
label?: string;
|
|
6
|
-
/** Edge of the square
|
|
33
|
+
/** Edge of the glyph's square. Default 24. */
|
|
7
34
|
size?: number;
|
|
8
35
|
/** Names the copied thing in analytics ("api-key", "address"). Never the value. */
|
|
9
36
|
id?: string;
|
|
10
37
|
}
|
|
11
|
-
export declare function CopyButton({ value, label, size, id }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare function CopyButton({ value, children, label, size, id }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
12
39
|
//# sourceMappingURL=CopyButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../src/product/CopyButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../src/product/CopyButton.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAUnE,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mFAAmF;IACnF,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE,EAAE,EAAE,eAAe,2CAgEpF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
4
|
* CopyButton — copy with a confirmation tick.
|
|
5
5
|
*
|
|
@@ -16,13 +16,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
16
16
|
* from here rather than owning it.
|
|
17
17
|
*/
|
|
18
18
|
import { useEffect, useRef, useState } from 'react';
|
|
19
|
-
import { XStack } from '@hanzo/gui';
|
|
19
|
+
import { Text, XStack } from '@hanzo/gui';
|
|
20
20
|
import { Check, Copy } from '@hanzogui/lucide-icons-2';
|
|
21
21
|
import { tip } from '../backends/gui/slot.js';
|
|
22
22
|
import { useEmit } from './instrument.js';
|
|
23
23
|
/** How long the control shows its confirmation, in ms. */
|
|
24
24
|
const CONFIRM = 2000;
|
|
25
|
-
export function CopyButton({ value, label
|
|
25
|
+
export function CopyButton({ value, children, label, size = 24, id }) {
|
|
26
26
|
const [copied, setCopied] = useState(false);
|
|
27
27
|
const timer = useRef(undefined);
|
|
28
28
|
const track = useEmit();
|
|
@@ -47,6 +47,20 @@ export function CopyButton({ value, label = 'Copy', size = 24, id }) {
|
|
|
47
47
|
track({ component: 'CopyButton', action: 'error', id });
|
|
48
48
|
});
|
|
49
49
|
};
|
|
50
|
-
|
|
50
|
+
const name = label ?? (typeof children === 'string' ? children : 'Copy');
|
|
51
|
+
const glyph = Math.round(size * 0.58);
|
|
52
|
+
return (_jsxs(XStack
|
|
53
|
+
// The label form is a pill that sizes to its text; the icon form is the
|
|
54
|
+
// square it has always been. `height` is shared so a labeled control lines
|
|
55
|
+
// up with an unlabeled one in the same row.
|
|
56
|
+
, {
|
|
57
|
+
// The label form is a pill that sizes to its text; the icon form is the
|
|
58
|
+
// square it has always been. `height` is shared so a labeled control lines
|
|
59
|
+
// up with an unlabeled one in the same row.
|
|
60
|
+
width: children == null ? size : undefined, height: size, px: children == null ? undefined : '$2', gap: children == null ? undefined : '$1.5', items: "center", justify: "center", rounded: "$2", cursor: "pointer", opacity: 0.7, onPress: copy, role: "button", tabIndex: 0, "aria-label": copied ? 'Copied' : name, ...tip(copied ? 'Copied' : name), hoverStyle: { bg: '$color4', opacity: 1 }, pressStyle: { bg: '$color5' }, children: [copied ? _jsx(Check, { size: glyph }) : _jsx(Copy, { size: glyph }), children == null ? null : (
|
|
61
|
+
// The word carries the confirmation too. A tick alone, at 14px, beside
|
|
62
|
+
// text that did not change is the smallest possible way to say the thing
|
|
63
|
+
// the control exists to say.
|
|
64
|
+
_jsx(Text, { fontSize: "$2", color: "$color12", numberOfLines: 1, children: copied ? 'Copied' : children }))] }));
|
|
51
65
|
}
|
|
52
66
|
//# sourceMappingURL=CopyButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyButton.js","sourceRoot":"","sources":["../../src/product/CopyButton.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"CopyButton.js","sourceRoot":"","sources":["../../src/product/CopyButton.tsx"],"names":[],"mappings":"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"}
|