@hanzo/ui 8.0.61 → 8.0.63
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/backends/gui/switch.cjs +16 -2
- package/dist/backends/gui/switch.d.ts +14 -0
- package/dist/backends/gui/switch.d.ts.map +1 -1
- package/dist/backends/gui/switch.js +16 -2
- package/dist/backends/gui/switch.js.map +1 -1
- 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/Palette.cjs +65 -0
- package/dist/product/Palette.d.ts +67 -0
- package/dist/product/Palette.d.ts.map +1 -0
- package/dist/product/Palette.js +63 -0
- package/dist/product/Palette.js.map +1 -0
- 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 +21 -3
- package/dist/product/index.d.ts +4 -1
- package/dist/product/index.d.ts.map +1 -1
- package/dist/product/index.js +20 -1
- package/dist/product/index.js.map +1 -1
- package/dist/product/match.cjs +76 -0
- package/dist/product/match.d.ts +78 -0
- package/dist/product/match.d.ts.map +1 -0
- package/dist/product/match.js +72 -0
- package/dist/product/match.js.map +1 -0
- 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/product/useCommandK.cjs +46 -0
- package/dist/product/useCommandK.d.ts +4 -0
- package/dist/product/useCommandK.d.ts.map +1 -0
- package/dist/product/useCommandK.js +44 -0
- package/dist/product/useCommandK.js.map +1 -0
- package/dist/styles/motion.css +52 -17
- package/dist/styles.css +53 -20
- package/package.json +31 -3
|
@@ -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"}
|
|
@@ -28,6 +28,20 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
28
28
|
* with no signal in it — which is what a full page of these actually looked
|
|
29
29
|
* like. Off is muted, on is filled, and the loudest treatment is the one that
|
|
30
30
|
* means something.
|
|
31
|
+
*
|
|
32
|
+
* THE THUMB TAKES THE SAME TOKEN AS ITS TRACK, and that is not a copy-paste
|
|
33
|
+
* slip. gui wraps the thumb in a `t_SwitchThumb` sub-theme that INVERTS the
|
|
34
|
+
* whole ramp — measured live, `$color3` is rgb(26,26,26) at the frame and
|
|
35
|
+
* rgb(171,171,171) inside the thumb; `$color12` is rgb(250,250,250) and
|
|
36
|
+
* rgb(10,10,10). So naming one token paints both sides of the pair and the
|
|
37
|
+
* contrast is structural: the thumb cannot come out the same colour as the
|
|
38
|
+
* track it sits on, in either state, whatever the palette does later.
|
|
39
|
+
*
|
|
40
|
+
* Picking the tokens by eye instead shipped once, in 8.0.57-8.0.59, and it
|
|
41
|
+
* shipped INVISIBLE: `$color10` under the thumb resolved to the off track's own
|
|
42
|
+
* rgb(26,26,26) and `$color1` to the on track's rgb(255,255,255). The tests
|
|
43
|
+
* passed, because they asked whether the two states DIFFER from each other and
|
|
44
|
+
* never whether either one differs from the thing behind it.
|
|
31
45
|
*/
|
|
32
46
|
const gui_1 = require("@hanzo/gui");
|
|
33
47
|
const slot_1 = require("./slot.cjs");
|
|
@@ -42,7 +56,7 @@ const Switch = ({ disabled, ...props }) => ((0, jsx_runtime_1.jsx)(gui_1.Switch,
|
|
|
42
56
|
// else: a control that ignores its own disabled prop looks identical to a
|
|
43
57
|
// live one, and the page this was found on had a disabled switch sitting
|
|
44
58
|
// beside eight enabled ones with nothing to tell them apart.
|
|
45
|
-
disabled: disabled, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'not-allowed' : 'pointer', ...(0, gesture_1.touch)(TRACK_H, 44, 'y'), ...props, children: (0, jsx_runtime_1.jsx)(gui_1.Switch.Thumb, { ...(0, slot_1.slot)('switch-thumb'), width: THUMB, height: THUMB, backgroundColor: "$
|
|
59
|
+
disabled: disabled, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'not-allowed' : 'pointer', ...(0, gesture_1.touch)(TRACK_H, 44, 'y'), ...props, children: (0, jsx_runtime_1.jsx)(gui_1.Switch.Thumb, { ...(0, slot_1.slot)('switch-thumb'), width: THUMB, height: THUMB, backgroundColor: "$color3",
|
|
46
60
|
// `bg`, and it is the only one of the three spellings that is both typed
|
|
47
61
|
// and correct. The Thumb's activeStyle is typed as the SHORTHAND style set:
|
|
48
62
|
// `backgroundColor` paints but is not in that type; `background` is in it
|
|
@@ -51,5 +65,5 @@ const Switch = ({ disabled, ...props }) => ((0, jsx_runtime_1.jsx)(gui_1.Switch,
|
|
|
51
65
|
// Consumers build with ignoreBuildErrors, so the first would have shipped
|
|
52
66
|
// an error nobody sees and the second a colour that lands or does not
|
|
53
67
|
// depending on stylesheet order.
|
|
54
|
-
activeStyle: { bg: '$
|
|
68
|
+
activeStyle: { bg: '$color12' } }) }));
|
|
55
69
|
exports.Switch = Switch;
|
|
@@ -23,6 +23,20 @@
|
|
|
23
23
|
* with no signal in it — which is what a full page of these actually looked
|
|
24
24
|
* like. Off is muted, on is filled, and the loudest treatment is the one that
|
|
25
25
|
* means something.
|
|
26
|
+
*
|
|
27
|
+
* THE THUMB TAKES THE SAME TOKEN AS ITS TRACK, and that is not a copy-paste
|
|
28
|
+
* slip. gui wraps the thumb in a `t_SwitchThumb` sub-theme that INVERTS the
|
|
29
|
+
* whole ramp — measured live, `$color3` is rgb(26,26,26) at the frame and
|
|
30
|
+
* rgb(171,171,171) inside the thumb; `$color12` is rgb(250,250,250) and
|
|
31
|
+
* rgb(10,10,10). So naming one token paints both sides of the pair and the
|
|
32
|
+
* contrast is structural: the thumb cannot come out the same colour as the
|
|
33
|
+
* track it sits on, in either state, whatever the palette does later.
|
|
34
|
+
*
|
|
35
|
+
* Picking the tokens by eye instead shipped once, in 8.0.57-8.0.59, and it
|
|
36
|
+
* shipped INVISIBLE: `$color10` under the thumb resolved to the off track's own
|
|
37
|
+
* rgb(26,26,26) and `$color1` to the on track's rgb(255,255,255). The tests
|
|
38
|
+
* passed, because they asked whether the two states DIFFER from each other and
|
|
39
|
+
* never whether either one differs from the thing behind it.
|
|
26
40
|
*/
|
|
27
41
|
import { Switch as GuiSwitch } from '@hanzo/gui';
|
|
28
42
|
import type { ComponentProps } from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/switch.tsx"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/switch.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAQ3C,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,SAAS,CAAC,CAAA;AAE1D,QAAA,MAAM,MAAM,GAAI,wBAAwB,WAAW,4CAuClD,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA"}
|
|
@@ -25,6 +25,20 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
25
25
|
* with no signal in it — which is what a full page of these actually looked
|
|
26
26
|
* like. Off is muted, on is filled, and the loudest treatment is the one that
|
|
27
27
|
* means something.
|
|
28
|
+
*
|
|
29
|
+
* THE THUMB TAKES THE SAME TOKEN AS ITS TRACK, and that is not a copy-paste
|
|
30
|
+
* slip. gui wraps the thumb in a `t_SwitchThumb` sub-theme that INVERTS the
|
|
31
|
+
* whole ramp — measured live, `$color3` is rgb(26,26,26) at the frame and
|
|
32
|
+
* rgb(171,171,171) inside the thumb; `$color12` is rgb(250,250,250) and
|
|
33
|
+
* rgb(10,10,10). So naming one token paints both sides of the pair and the
|
|
34
|
+
* contrast is structural: the thumb cannot come out the same colour as the
|
|
35
|
+
* track it sits on, in either state, whatever the palette does later.
|
|
36
|
+
*
|
|
37
|
+
* Picking the tokens by eye instead shipped once, in 8.0.57-8.0.59, and it
|
|
38
|
+
* shipped INVISIBLE: `$color10` under the thumb resolved to the off track's own
|
|
39
|
+
* rgb(26,26,26) and `$color1` to the on track's rgb(255,255,255). The tests
|
|
40
|
+
* passed, because they asked whether the two states DIFFER from each other and
|
|
41
|
+
* never whether either one differs from the thing behind it.
|
|
28
42
|
*/
|
|
29
43
|
import { Switch as GuiSwitch } from '@hanzo/gui';
|
|
30
44
|
import { slot } from './slot.js';
|
|
@@ -39,7 +53,7 @@ const Switch = ({ disabled, ...props }) => (_jsx(GuiSwitch, { ...slot('switch'),
|
|
|
39
53
|
// else: a control that ignores its own disabled prop looks identical to a
|
|
40
54
|
// live one, and the page this was found on had a disabled switch sitting
|
|
41
55
|
// beside eight enabled ones with nothing to tell them apart.
|
|
42
|
-
disabled: disabled, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'not-allowed' : 'pointer', ...touch(TRACK_H, 44, 'y'), ...props, children: _jsx(GuiSwitch.Thumb, { ...slot('switch-thumb'), width: THUMB, height: THUMB, backgroundColor: "$
|
|
56
|
+
disabled: disabled, opacity: disabled ? 0.5 : 1, cursor: disabled ? 'not-allowed' : 'pointer', ...touch(TRACK_H, 44, 'y'), ...props, children: _jsx(GuiSwitch.Thumb, { ...slot('switch-thumb'), width: THUMB, height: THUMB, backgroundColor: "$color3",
|
|
43
57
|
// `bg`, and it is the only one of the three spellings that is both typed
|
|
44
58
|
// and correct. The Thumb's activeStyle is typed as the SHORTHAND style set:
|
|
45
59
|
// `backgroundColor` paints but is not in that type; `background` is in it
|
|
@@ -48,6 +62,6 @@ const Switch = ({ disabled, ...props }) => (_jsx(GuiSwitch, { ...slot('switch'),
|
|
|
48
62
|
// Consumers build with ignoreBuildErrors, so the first would have shipped
|
|
49
63
|
// an error nobody sees and the second a colour that lands or does not
|
|
50
64
|
// depending on stylesheet order.
|
|
51
|
-
activeStyle: { bg: '$
|
|
65
|
+
activeStyle: { bg: '$color12' } }) }));
|
|
52
66
|
export { Switch };
|
|
53
67
|
//# sourceMappingURL=switch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../src/backends/gui/switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ
|
|
1
|
+
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../src/backends/gui/switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAEjC,MAAM,OAAO,GAAG,EAAE,CAAA;AAClB,MAAM,OAAO,GAAG,EAAE,CAAA;AAClB,MAAM,KAAK,GAAG,EAAE,CAAA;AAIhB,MAAM,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAe,EAAE,EAAE,CAAC,CACtD,KAAC,SAAS,OACJ,IAAI,CAAC,QAAQ,CAAC,EAClB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,CAAC,EACb,eAAe,EAAC,SAAS;IACzB,sEAAsE;IACtE,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,WAAW,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE;IACrE,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,6DAA6D;IAC7D,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC3B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,KACxC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,KACvB,KAAK,YAET,KAAC,SAAS,CAAC,KAAK,OACV,IAAI,CAAC,cAAc,CAAC,EACxB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,KAAK,EACb,eAAe,EAAC,SAAS;QACzB,yEAAyE;QACzE,4EAA4E;QAC5E,0EAA0E;QAC1E,sEAAsE;QACtE,uEAAuE;QACvE,0EAA0E;QAC1E,sEAAsE;QACtE,iCAAiC;QACjC,WAAW,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,GAC/B,GACQ,CACb,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;iFAEiF;AACjF,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;AAEjC,uEAAuE;AACvE,SAAS,KAAK,CAAC,KAAa,EAAE,IAAY;IACxC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAA;aACxB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,CAAC,CAAC,CAAA;AACX,CAAC;AAED;;+EAE+E;AAC/E,SAAS,KAAK,CAAC,KAAa;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAA;aACxB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAA;aAC7B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IACD,OAAO,CAAC,CAAC,CAAA;AACX,CAAC;AAED,SAAS,MAAM,CAAC,KAAa,EAAE,IAA4B,EAAE,IAAiB;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACnC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAE9B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;IACnC,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA,CAAC,+CAA+C;IAE5E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAClE,MAAM,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAEzE,IAAI,QAAiC,CAAA;IACrC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,0EAA0E;QAC1E,4DAA4D;QAC5D,QAAQ,GAAG,OAAO,CAAA;IACpB,CAAC;SAAM,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAW,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACxE,CAAC;SAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,OAAO,CAAA;IACpB,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IAExC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACrD,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,OAAO,CAAA;IAEpC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAA;AAChD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,OAA+B,EAAE;IACzE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;IAC1C,OAAO,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;AACnC,CAAC"}
|
|
@@ -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
|
}
|