@kanso-labs/kanso-ui 0.2.0

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.
Files changed (112) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +83 -0
  3. package/dist/assets/stylex.css +1623 -0
  4. package/dist/cjs/assets/stylex.css +1623 -0
  5. package/dist/cjs/components/avatar/index.cjs +89 -0
  6. package/dist/cjs/components/avatar/index.cjs.map +1 -0
  7. package/dist/cjs/components/avatar/index.d.cts +29 -0
  8. package/dist/cjs/components/badge/index.cjs +93 -0
  9. package/dist/cjs/components/badge/index.cjs.map +1 -0
  10. package/dist/cjs/components/badge/index.d.cts +27 -0
  11. package/dist/cjs/components/button/index.cjs +101 -0
  12. package/dist/cjs/components/button/index.cjs.map +1 -0
  13. package/dist/cjs/components/button/index.d.cts +22 -0
  14. package/dist/cjs/components/card/index.cjs +84 -0
  15. package/dist/cjs/components/card/index.cjs.map +1 -0
  16. package/dist/cjs/components/card/index.d.cts +29 -0
  17. package/dist/cjs/components/chip/index.cjs +53 -0
  18. package/dist/cjs/components/chip/index.cjs.map +1 -0
  19. package/dist/cjs/components/chip/index.d.cts +13 -0
  20. package/dist/cjs/components/currency/index.cjs +56 -0
  21. package/dist/cjs/components/currency/index.cjs.map +1 -0
  22. package/dist/cjs/components/currency/index.d.cts +36 -0
  23. package/dist/cjs/components/icon-button/index.cjs +80 -0
  24. package/dist/cjs/components/icon-button/index.cjs.map +1 -0
  25. package/dist/cjs/components/icon-button/index.d.cts +32 -0
  26. package/dist/cjs/components/index.d.cts +15 -0
  27. package/dist/cjs/components/link/index.cjs +61 -0
  28. package/dist/cjs/components/link/index.cjs.map +1 -0
  29. package/dist/cjs/components/link/index.d.cts +30 -0
  30. package/dist/cjs/components/list-item/index.cjs +42 -0
  31. package/dist/cjs/components/list-item/index.cjs.map +1 -0
  32. package/dist/cjs/components/list-item/index.d.cts +22 -0
  33. package/dist/cjs/components/separator/index.cjs +34 -0
  34. package/dist/cjs/components/separator/index.cjs.map +1 -0
  35. package/dist/cjs/components/separator/index.d.cts +14 -0
  36. package/dist/cjs/components/sheet/index.cjs +266 -0
  37. package/dist/cjs/components/sheet/index.cjs.map +1 -0
  38. package/dist/cjs/components/sheet/index.d.cts +73 -0
  39. package/dist/cjs/components/tabs/index.cjs +77 -0
  40. package/dist/cjs/components/tabs/index.cjs.map +1 -0
  41. package/dist/cjs/components/tabs/index.d.cts +24 -0
  42. package/dist/cjs/components/text/index.cjs +173 -0
  43. package/dist/cjs/components/text/index.cjs.map +1 -0
  44. package/dist/cjs/components/text/index.d.cts +19 -0
  45. package/dist/cjs/components/text-field/index.cjs +53 -0
  46. package/dist/cjs/components/text-field/index.cjs.map +1 -0
  47. package/dist/cjs/components/text-field/index.d.cts +30 -0
  48. package/dist/cjs/hooks/useRipple.cjs +391 -0
  49. package/dist/cjs/hooks/useRipple.cjs.map +1 -0
  50. package/dist/cjs/index.cjs +29 -0
  51. package/dist/cjs/index.d.cts +16 -0
  52. package/dist/cjs/node_modules/@stylexjs/stylex/lib/es/stylex.cjs +121 -0
  53. package/dist/cjs/node_modules/@stylexjs/stylex/lib/es/stylex.cjs.map +1 -0
  54. package/dist/cjs/styles/ripple.cjs +33 -0
  55. package/dist/cjs/styles/ripple.cjs.map +1 -0
  56. package/dist/cjs/tokens/values.cjs +36 -0
  57. package/dist/cjs/tokens/values.cjs.map +1 -0
  58. package/dist/components/avatar/index.d.ts +29 -0
  59. package/dist/components/avatar/index.js +89 -0
  60. package/dist/components/avatar/index.js.map +1 -0
  61. package/dist/components/badge/index.d.ts +27 -0
  62. package/dist/components/badge/index.js +93 -0
  63. package/dist/components/badge/index.js.map +1 -0
  64. package/dist/components/button/index.d.ts +22 -0
  65. package/dist/components/button/index.js +101 -0
  66. package/dist/components/button/index.js.map +1 -0
  67. package/dist/components/card/index.d.ts +29 -0
  68. package/dist/components/card/index.js +84 -0
  69. package/dist/components/card/index.js.map +1 -0
  70. package/dist/components/chip/index.d.ts +13 -0
  71. package/dist/components/chip/index.js +53 -0
  72. package/dist/components/chip/index.js.map +1 -0
  73. package/dist/components/currency/index.d.ts +36 -0
  74. package/dist/components/currency/index.js +56 -0
  75. package/dist/components/currency/index.js.map +1 -0
  76. package/dist/components/icon-button/index.d.ts +32 -0
  77. package/dist/components/icon-button/index.js +80 -0
  78. package/dist/components/icon-button/index.js.map +1 -0
  79. package/dist/components/index.d.ts +15 -0
  80. package/dist/components/link/index.d.ts +30 -0
  81. package/dist/components/link/index.js +61 -0
  82. package/dist/components/link/index.js.map +1 -0
  83. package/dist/components/list-item/index.d.ts +22 -0
  84. package/dist/components/list-item/index.js +42 -0
  85. package/dist/components/list-item/index.js.map +1 -0
  86. package/dist/components/separator/index.d.ts +14 -0
  87. package/dist/components/separator/index.js +34 -0
  88. package/dist/components/separator/index.js.map +1 -0
  89. package/dist/components/sheet/index.d.ts +73 -0
  90. package/dist/components/sheet/index.js +266 -0
  91. package/dist/components/sheet/index.js.map +1 -0
  92. package/dist/components/tabs/index.d.ts +24 -0
  93. package/dist/components/tabs/index.js +77 -0
  94. package/dist/components/tabs/index.js.map +1 -0
  95. package/dist/components/text/index.d.ts +19 -0
  96. package/dist/components/text/index.js +173 -0
  97. package/dist/components/text/index.js.map +1 -0
  98. package/dist/components/text-field/index.d.ts +30 -0
  99. package/dist/components/text-field/index.js +53 -0
  100. package/dist/components/text-field/index.js.map +1 -0
  101. package/dist/hooks/useRipple.js +391 -0
  102. package/dist/hooks/useRipple.js.map +1 -0
  103. package/dist/index.d.ts +16 -0
  104. package/dist/index.js +15 -0
  105. package/dist/node_modules/@stylexjs/stylex/lib/es/stylex.js +121 -0
  106. package/dist/node_modules/@stylexjs/stylex/lib/es/stylex.js.map +1 -0
  107. package/dist/styles/ripple.js +33 -0
  108. package/dist/styles/ripple.js.map +1 -0
  109. package/dist/tokens/values.js +34 -0
  110. package/dist/tokens/values.js.map +1 -0
  111. package/dist/tokens.css +282 -0
  112. package/package.json +109 -0
@@ -0,0 +1,29 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ //#region src/components/card/index.d.ts
3
+ type CardProps = {
4
+ children?: ReactNode;
5
+ /**
6
+ * Renders a `<button>` that ripples and lifts on hover, for a card that is
7
+ * itself the thing you press. Leave it off for a card that merely holds
8
+ * content, including one containing its own buttons.
9
+ * @default false
10
+ */
11
+ interactive?: boolean;
12
+ /**
13
+ * `none` removes the card's own padding, for a card whose children run to
14
+ * its edges — a list of rows separated by rules.
15
+ * @default 'default'
16
+ */
17
+ padding?: 'default' | 'none';
18
+ /**
19
+ * How the card separates itself from the page: `elevated` casts a shadow,
20
+ * `filled` sits on a darker surface, `outlined` draws a border.
21
+ * @default 'elevated'
22
+ */
23
+ variant?: CardVariant;
24
+ } & HTMLAttributes<HTMLElement>;
25
+ type CardVariant = 'elevated' | 'filled' | 'outlined';
26
+ declare function Card({ children, interactive, padding, variant, ...props }: CardProps): import("react").JSX.Element;
27
+ //#endregion
28
+ export { type CardProps, Card as default };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,84 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { useRipple } from "../../hooks/useRipple.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/card/index.tsx
5
+ const styles = {
6
+ base: {
7
+ kaIpWk: "xhpdng0",
8
+ kMzoRj: "xc342km",
9
+ k1xSpc: "x1lliihq",
10
+ kVQacm: "xb3r6kr",
11
+ kVAEAm: "x1n2onr6",
12
+ $$css: true
13
+ },
14
+ elevated: {
15
+ kWkggS: "x1vnz5z6",
16
+ kGVxlE: "x19efjv6",
17
+ $$css: true
18
+ },
19
+ filled: {
20
+ kWkggS: "x1rrhr5q",
21
+ $$css: true
22
+ },
23
+ interactive: {
24
+ kkrTdU: "x1ypdohk",
25
+ kVVagm: "xln7xf2",
26
+ kzqmXN: "xh8yej3",
27
+ kjBf7l: "xrgy624",
28
+ kInvED: "x1hl8ikr",
29
+ k3XXqK: "x9v5kkp x1t137rt",
30
+ kMeerF: "x1de99jn",
31
+ k9WMMc: "x1yc453h",
32
+ $$css: true
33
+ },
34
+ outlined: {
35
+ kWkggS: "x14s9m32",
36
+ kVAM5u: "x133yhug",
37
+ ksu8eU: "x1y0btm7",
38
+ kMzoRj: "xmkeg23",
39
+ $$css: true
40
+ },
41
+ paddingDefault: {
42
+ kmVPX3: "xgc26li",
43
+ $$css: true
44
+ },
45
+ paddingNone: {
46
+ kmVPX3: "x1717udv",
47
+ $$css: true
48
+ }
49
+ };
50
+ const interactionStyles = {
51
+ elevated: {
52
+ kWkggS: "xu5m21g x5r8g2b x1vnz5z6",
53
+ kGVxlE: "x1g60mc1 x1fzngjt x19efjv6",
54
+ $$css: true
55
+ },
56
+ filled: {
57
+ kWkggS: "x1w49kxs xovjh5a x1rrhr5q",
58
+ $$css: true
59
+ },
60
+ outlined: {
61
+ kWkggS: "x1jqfdmz x1dmgsxd x14s9m32",
62
+ $$css: true
63
+ }
64
+ };
65
+ function Card({ children, interactive = false, padding = "default", variant = "elevated", ...props$1 }) {
66
+ const ripple = useRipple(interactive);
67
+ const padded = padding === "none" ? styles.paddingNone : styles.paddingDefault;
68
+ if (!interactive) return /* @__PURE__ */ jsx("div", {
69
+ ...props$1,
70
+ ...props(styles.base, styles[variant], padded),
71
+ children
72
+ });
73
+ return /* @__PURE__ */ jsxs("button", {
74
+ type: "button",
75
+ ...ripple.handlers,
76
+ ...props$1,
77
+ ...props(styles.base, styles[variant], padded, styles.interactive, interactionStyles[variant]),
78
+ children: [children, ripple.surface]
79
+ });
80
+ }
81
+ //#endregion
82
+ export { Card as default };
83
+
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/card/index.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { useRipple } from '../../hooks/useRipple';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, radii, shadows, spacing, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// The three variants differ only in how they separate themselves from the\n// page: a shadow, a darker fill, or a border. Each therefore sits on a\n// different background, which is why the interaction styles below are keyed\n// by variant too — a state layer composites an 'on-color' over whatever the\n// container already is, so it cannot be written once for all three.\n//\n// color-mix() is inlined at each property rather than factored into a helper:\n// @stylexjs/babel-plugin only statically recognizes expressions written\n// directly as property values. Button's header comment records the same\n// constraint, and the :not(:disabled) guard there applies here for the same\n// reason — stylex's fixed pseudo-class ordering puts :hover after :disabled.\nconst styles = {\n base: {\n kaIpWk: \"xhpdng0\",\n kMzoRj: \"xc342km\",\n k1xSpc: \"x1lliihq\",\n kVQacm: \"xb3r6kr\",\n kVAEAm: \"x1n2onr6\",\n $$css: true\n },\n elevated: {\n kWkggS: \"x1vnz5z6\",\n kGVxlE: \"x19efjv6\",\n $$css: true\n },\n filled: {\n kWkggS: \"x1rrhr5q\",\n $$css: true\n },\n interactive: {\n kkrTdU: \"x1ypdohk\",\n kVVagm: \"xln7xf2\",\n kzqmXN: \"xh8yej3\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n k9WMMc: \"x1yc453h\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x14s9m32\",\n kVAM5u: \"x133yhug\",\n ksu8eU: \"x1y0btm7\",\n kMzoRj: \"xmkeg23\",\n $$css: true\n },\n paddingDefault: {\n kmVPX3: \"xgc26li\",\n $$css: true\n },\n paddingNone: {\n kmVPX3: \"x1717udv\",\n $$css: true\n }\n};\nconst interactionStyles = {\n elevated: {\n kWkggS: \"xu5m21g x5r8g2b x1vnz5z6\",\n kGVxlE: \"x1g60mc1 x1fzngjt x19efjv6\",\n $$css: true\n },\n filled: {\n kWkggS: \"x1w49kxs xovjh5a x1rrhr5q\",\n $$css: true\n },\n outlined: {\n kWkggS: \"x1jqfdmz x1dmgsxd x14s9m32\",\n $$css: true\n }\n};\n\n// Typed as the attributes a <div> and a <button> both accept, because\n// `interactive` decides which one renders. Anything element-specific — a\n// button's `type`, a div's ref type — would be wrong for one of the two, so\n// the shared surface is what the prop type can honestly promise.\ntype CardProps = {\n children?: ReactNode;\n /**\n * Renders a `<button>` that ripples and lifts on hover, for a card that is\n * itself the thing you press. Leave it off for a card that merely holds\n * content, including one containing its own buttons.\n * @default false\n */\n interactive?: boolean;\n /**\n * `none` removes the card's own padding, for a card whose children run to\n * its edges — a list of rows separated by rules.\n * @default 'default'\n */\n padding?: 'default' | 'none';\n /**\n * How the card separates itself from the page: `elevated` casts a shadow,\n * `filled` sits on a darker surface, `outlined` draws a border.\n * @default 'elevated'\n */\n variant?: CardVariant;\n} & HTMLAttributes<HTMLElement>;\ntype CardVariant = 'elevated' | 'filled' | 'outlined';\nfunction Card({\n children,\n interactive = false,\n padding = 'default',\n variant = 'elevated',\n ...props\n}: CardProps) {\n const ripple = useRipple<HTMLButtonElement>(interactive);\n const padded = padding === 'none' ? styles.paddingNone : styles.paddingDefault;\n if (!interactive) {\n return <div {...props} {...stylex.props(styles.base, styles[variant], padded)}>\n {children}\n </div>;\n }\n return <button type=\"button\" {...ripple.handlers} {...props} {...stylex.props(styles.base, styles[variant], padded, styles.interactive, interactionStyles[variant])}>\n {children}\n {ripple.surface}\n </button>;\n}\nexport type { CardProps };\nexport default Card;"],"mappings":";;;;AAiBA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,gBAAgB;EACd,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAM,oBAAoB;CACxB,UAAU;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;AACF;AA6BA,SAAS,KAAK,EACZ,UACA,cAAc,OACd,UAAU,WACV,UAAU,YACV,GAAG,WACS;CACZ,MAAM,SAAS,UAA6B,WAAW;CACvD,MAAM,SAAS,YAAY,SAAS,OAAO,cAAc,OAAO;CAChE,IAAI,CAAC,aACH,OAAO,oBAAC,OAAD;EAAK,GAAI;EAAO,GAAI,MAAa,OAAO,MAAM,OAAO,UAAU,MAAM;EACvE;CACE,CAAA;CAET,OAAO,qBAAC,UAAD;EAAQ,MAAK;EAAS,GAAI,OAAO;EAAU,GAAI;EAAO,GAAI,MAAa,OAAO,MAAM,OAAO,UAAU,QAAQ,OAAO,aAAa,kBAAkB,QAAQ;EAA3J,UAAA,CACF,UACA,OAAO,OACF;;AACZ"}
@@ -0,0 +1,13 @@
1
+ import { ToggleProps } from "@base-ui/react/toggle";
2
+ //#region src/components/chip/index.d.ts
3
+ type ChipProps<Value extends string = string> = ToggleProps<Value>;
4
+ /**
5
+ * A chip is a two-state button, so its selected state is Base UI's `pressed`:
6
+ * pass `pressed` with `onPressedChange` to control it, or `defaultPressed` to
7
+ * let it keep its own state. Selection is announced through `aria-pressed`
8
+ * rather than a role of its own.
9
+ */
10
+ declare function Chip<Value extends string = string>({ children, ...props }: ChipProps<Value>): import("react").JSX.Element;
11
+ //#endregion
12
+ export { type ChipProps, Chip as default };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,53 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { Toggle } from "@base-ui/react/toggle";
4
+ //#region src/components/chip/index.tsx
5
+ /**
6
+ * A chip is a two-state button, so its selected state is Base UI's `pressed`:
7
+ * pass `pressed` with `onPressedChange` to control it, or `defaultPressed` to
8
+ * let it keep its own state. Selection is announced through `aria-pressed`
9
+ * rather than a role of its own.
10
+ */
11
+ function Chip(t0) {
12
+ const $ = c(6);
13
+ let children;
14
+ let props;
15
+ if ($[0] !== t0) {
16
+ ({children, ...props} = t0);
17
+ $[0] = t0;
18
+ $[1] = children;
19
+ $[2] = props;
20
+ } else {
21
+ children = $[1];
22
+ props = $[2];
23
+ }
24
+ let t1;
25
+ if ($[3] !== children || $[4] !== props) {
26
+ t1 = /* @__PURE__ */ jsx(Toggle, {
27
+ ...props,
28
+ className: classNameForState,
29
+ style: styleForState,
30
+ children
31
+ });
32
+ $[3] = children;
33
+ $[4] = props;
34
+ $[5] = t1;
35
+ } else t1 = $[5];
36
+ return t1;
37
+ }
38
+ function classNameForState(state) {
39
+ return propsFor(state).className;
40
+ }
41
+ function propsFor(state) {
42
+ return {
43
+ 0: { className: "x6s0dn4 x10w6t97 x1xdvaa9 x1y0btm7 xmkeg23 x1s07b3s x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo x126z3so x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh x1eaenvl xpc4ca7 x1a42vn9 x6gcojk xjbqb8w xd8uu4e x1fwvt7v xhfb3ry x1w5n3ug" },
44
+ 1: { className: "x6s0dn4 x10w6t97 x1xdvaa9 x1y0btm7 xmkeg23 x1s07b3s x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo x126z3so x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh x1eaenvl xpc4ca7 xctpbsp x1n0xrd1 x1qndd53 x15dekr4 x9r1u3d xhfb3ry x1sawysd" }
45
+ }[!!state.pressed << 0];
46
+ }
47
+ function styleForState(state) {
48
+ return propsFor(state).style;
49
+ }
50
+ //#endregion
51
+ export { Chip as default };
52
+
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["classNameForState","styleForState","children"],"sources":["../../../src/components/chip/index.tsx"],"sourcesContent":["import type { ToggleProps as BaseUIToggleProps, ToggleState as BaseUIToggleState } from '@base-ui/react/toggle';\nimport { Toggle as BaseUIToggle } from '@base-ui/react/toggle';\nimport * as stylex from '@stylexjs/stylex';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// Each state composites an 'on-color' over its own container at the\n// interaction state's opacity rather than swapping in a separate hover color.\n// calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes, and it is inlined at each property because\n// @stylexjs/babel-plugin only statically recognizes expressions written\n// directly as property values.\n//\n// The selected chip drops its border rather than recolouring it: it has a\n// container of its own to define its edge, and a border on top of that reads\n// as a second, competing outline.\n\ntype ChipProps<Value extends string = string> = BaseUIToggleProps<Value>;\n\n/**\n * A chip is a two-state button, so its selected state is Base UI's `pressed`:\n * pass `pressed` with `onPressedChange` to control it, or `defaultPressed` to\n * let it keep its own state. Selection is announced through `aria-pressed`\n * rather than a role of its own.\n */\nfunction Chip<Value extends string = string>({\n children,\n ...props\n}: ChipProps<Value>) {\n return <BaseUIToggle {...props} className={classNameForState} style={styleForState}>\n {children}\n </BaseUIToggle>;\n}\nfunction classNameForState(state: BaseUIToggleState) {\n return propsFor(state).className;\n}\n\n// StyleX has no way to target [data-pressed] on the element it is styling, so\n// the selected styles cannot be chosen in CSS. Base UI's answer is to let\n// className and style be functions of the component's own state, which is\n// what these two are — and it is why an uncontrolled chip styles itself\n// correctly without this component keeping a copy of the state.\n//\n// Declared at module scope so each is one stable reference rather than a\n// fresh closure per render, which is what react-perf's no-new-function-as-prop\n// is after. They close over nothing, so there is nothing to capture.\nfunction propsFor(state: BaseUIToggleState) {\n return {\n 0: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 x1y0btm7 xmkeg23 x1s07b3s x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo x126z3so x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh x1eaenvl xpc4ca7 x1a42vn9 x6gcojk xjbqb8w xd8uu4e x1fwvt7v xhfb3ry x1w5n3ug\"\n },\n 1: {\n className: \"x6s0dn4 x10w6t97 x1xdvaa9 x1y0btm7 xmkeg23 x1s07b3s x1ypdohk x3nfvp2 x2lah0s xkknnkr x14zspaw x1v9cpvo x126z3so x155f00i x1lz68p4 xrgy624 x1hl8ikr x9v5kkp x1t137rt x1de99jn xt970qd x18fpw6u x1qno0dh x1eaenvl xpc4ca7 xctpbsp x1n0xrd1 x1qndd53 x15dekr4 x9r1u3d xhfb3ry x1sawysd\"\n }\n }[!!state.pressed << 0];\n}\nfunction styleForState(state: BaseUIToggleState) {\n return propsFor(state).style;\n}\nexport type { ChipProps };\nexport default Chip;"],"mappings":";;;;;;;;;;AAyBA,SAAA,KAAA,IAAA;CAAA,MAAA,IAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,IAAA;EAA6C,CAAA,CAAA,aAAA,SAAA;EAG1B,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA;EAAA,WAAA,EAAA;EAAA,QAAA,EAAA;CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,YAAA,EAAA,OAAA,OAAA;EACV,KAAA,oBAAC,QAAD;GAAa,GAAK;GAAkBA,WAAA;GAA0BC,OAAA;GAChE;EADe,CAAA;EAEH,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAFV;AAEU;AAEnB,SAAS,kBAAkB,OAA0B;CACnD,OAAO,SAAS,KAAK,CAAC,CAAC;AACzB;AAWA,SAAS,SAAS,OAA0B;CAC1C,OAAO;EACL,GAAG,EACD,WAAW,qRACb;EACA,GAAG,EACD,WAAW,sRACb;CACF,EAAE,CAAC,CAAC,MAAM,WAAW;AACvB;AACA,SAAS,cAAc,OAA0B;CAC/C,OAAO,SAAS,KAAK,CAAC,CAAC;AACzB"}
@@ -0,0 +1,36 @@
1
+ import { useRender } from "@base-ui/react/use-render";
2
+ //#region src/components/currency/index.d.ts
3
+ type CurrencyProps = Omit<useRender.ComponentProps<'span'>, 'children'> & {
4
+ /**
5
+ * ISO 4217 code for the currency to format in.
6
+ * @default 'USD'
7
+ */
8
+ currency?: string;
9
+ /**
10
+ * BCP 47 locale to format for. Defaults to the runtime's own locale, so an
11
+ * app that has not chosen one still formats the way its reader expects.
12
+ */
13
+ locale?: string;
14
+ /**
15
+ * When to show the sign. `auto` shows one only on negatives, `always` also
16
+ * prefixes positives with a plus, and `never` shows neither — which leaves
17
+ * colour as the only thing separating a credit from a debt, so reach for it
18
+ * only where the direction is already stated some other way.
19
+ * @default 'auto'
20
+ */
21
+ sign?: SignDisplay;
22
+ /**
23
+ * Which colour role to render in. `auto` follows the sign of `value`, with
24
+ * zero reading as neutral.
25
+ * @default 'auto'
26
+ */
27
+ tone?: Tone;
28
+ /** The amount, in the currency's major units. */
29
+ value: number;
30
+ };
31
+ type SignDisplay = 'always' | 'auto' | 'never';
32
+ type Tone = 'auto' | 'negative' | 'neutral' | 'positive';
33
+ declare function Currency({ currency, locale, render, sign, tone, value, ...props }: CurrencyProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
34
+ //#endregion
35
+ export { type CurrencyProps, Currency as default };
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,56 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ //#region src/components/currency/index.tsx
4
+ const styles = { base: {
5
+ kMv6JI: "xbppi91",
6
+ kcqcaj: "xss6m8b",
7
+ k63SB2: "x1bf3uqz",
8
+ $$css: true
9
+ } };
10
+ const tones = {
11
+ negative: {
12
+ kMwMTN: "x12gp0t",
13
+ $$css: true
14
+ },
15
+ neutral: {
16
+ kMwMTN: "x139gbkf",
17
+ $$css: true
18
+ },
19
+ positive: {
20
+ kMwMTN: "x4no3js",
21
+ $$css: true
22
+ }
23
+ };
24
+ const MINUS_SIGN = "−";
25
+ function Currency({ currency = "USD", locale, render, sign = "auto", tone = "auto", value, ...props$1 }) {
26
+ return useRender({
27
+ defaultTagName: "span",
28
+ props: {
29
+ ...props$1,
30
+ children: formatCurrency(value, {
31
+ currency,
32
+ locale,
33
+ sign
34
+ }),
35
+ ...props(styles.base, tones[resolveTone(value, tone)])
36
+ },
37
+ render
38
+ });
39
+ }
40
+ function formatCurrency(value, options) {
41
+ return new Intl.NumberFormat(options.locale, {
42
+ currency: options.currency,
43
+ signDisplay: options.sign,
44
+ style: "currency"
45
+ }).formatToParts(value).map((part) => part.type === "minusSign" ? MINUS_SIGN : part.value).join("");
46
+ }
47
+ function resolveTone(value, tone) {
48
+ if (tone !== "auto") return tone;
49
+ if (value > 0) return "positive";
50
+ if (value < 0) return "negative";
51
+ return "neutral";
52
+ }
53
+ //#endregion
54
+ export { Currency as default };
55
+
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/currency/index.tsx"],"sourcesContent":["import { useRender } from '@base-ui/react/use-render';\nimport * as stylex from '@stylexjs/stylex';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, typography } from '../../tokens/design.tokens.stylex';\n\n// Deliberately sets no font-size. The same value turns up at several sizes —\n// inside a list row, as a heading-scale figure, as a total — differing in\n// nothing else, so the size is the container's decision. What must never vary\n// is here: the mono face, tabular figures so a column of them lines up on the\n// decimal point, and the medium weight that separates a figure from the prose\n// around it.\nconst styles = {\n base: {\n kMv6JI: \"xbppi91\",\n kcqcaj: \"xss6m8b\",\n k63SB2: \"x1bf3uqz\",\n $$css: true\n }\n};\nconst tones = {\n negative: {\n kMwMTN: \"x12gp0t\",\n $$css: true\n },\n neutral: {\n kMwMTN: \"x139gbkf\",\n $$css: true\n },\n positive: {\n kMwMTN: \"x4no3js\",\n $$css: true\n }\n};\n\n// U+2212 MINUS SIGN, not the U+002D hyphen Intl actually emits. The hyphen is\n// a typographic stand-in: it is narrower than the plus it pairs with and does\n// not sit on the same optical centre as the digits, which shows up as a\n// wobbling column the moment amounts are stacked.\nconst MINUS_SIGN = '−';\ntype CurrencyProps = Omit<useRender.ComponentProps<'span'>, 'children'> & {\n /**\n * ISO 4217 code for the currency to format in.\n * @default 'USD'\n */\n currency?: string;\n /**\n * BCP 47 locale to format for. Defaults to the runtime's own locale, so an\n * app that has not chosen one still formats the way its reader expects.\n */\n locale?: string;\n /**\n * When to show the sign. `auto` shows one only on negatives, `always` also\n * prefixes positives with a plus, and `never` shows neither — which leaves\n * colour as the only thing separating a credit from a debt, so reach for it\n * only where the direction is already stated some other way.\n * @default 'auto'\n */\n sign?: SignDisplay;\n /**\n * Which colour role to render in. `auto` follows the sign of `value`, with\n * zero reading as neutral.\n * @default 'auto'\n */\n tone?: Tone;\n /** The amount, in the currency's major units. */\n value: number;\n};\ntype SignDisplay = 'always' | 'auto' | 'never';\ntype Tone = 'auto' | 'negative' | 'neutral' | 'positive';\nfunction Currency({\n currency = 'USD',\n locale,\n render,\n sign = 'auto',\n tone = 'auto',\n value,\n ...props\n}: CurrencyProps) {\n // stylex.props() spreads after `props` for the same reason Text does it: it\n // wins over a consumer-supplied className rather than merging with one.\n return useRender({\n defaultTagName: 'span',\n props: {\n ...props,\n children: formatCurrency(value, {\n currency,\n locale,\n sign\n }),\n ...stylex.props(styles.base, tones[resolveTone(value, tone)])\n },\n render\n });\n}\n\n// formatToParts rather than a replace over the formatted string, so only the\n// sign is substituted. A blind replace would also hit a hyphen inside a\n// locale's currency name or grouping, and locales that wrap negatives in\n// parentheses have no minus to swap at all — both of which this leaves alone.\nfunction formatCurrency(value: number, options: {\n currency: string;\n locale: string | undefined;\n sign: SignDisplay;\n}) {\n return new Intl.NumberFormat(options.locale, {\n currency: options.currency,\n signDisplay: options.sign,\n style: 'currency'\n }).formatToParts(value).map(part => part.type === 'minusSign' ? MINUS_SIGN : part.value).join('');\n}\n\n// Zero is neither owed nor owing, so it takes the neutral role rather than\n// being forced into one of the two. Negative zero lands here too, which is\n// what a rounded-away debt should read as.\nfunction resolveTone(value: number, tone: Tone) {\n if (tone !== 'auto') {\n return tone;\n }\n if (value > 0) {\n return 'positive';\n }\n if (value < 0) {\n return 'negative';\n }\n return 'neutral';\n}\nexport type { CurrencyProps };\nexport default Currency;"],"mappings":";;;AAWA,MAAM,SAAS,EACb,MAAM;CACJ,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,OAAO;AACT,EACF;AACA,MAAM,QAAQ;CACZ,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,OAAO;CACT;AACF;AAMA,MAAM,aAAa;AA+BnB,SAAS,SAAS,EAChB,WAAW,OACX,QACA,QACA,OAAO,QACP,OAAO,QACP,OACA,GAAG,WACa;CAGhB,OAAO,UAAU;EACf,gBAAgB;EAChB,OAAO;GACL,GAAG;GACH,UAAU,eAAe,OAAO;IAC9B;IACA;IACA;GACF,CAAC;GACD,GAAG,MAAa,OAAO,MAAM,MAAM,YAAY,OAAO,IAAI,EAAE;EAC9D;EACA;CACF,CAAC;AACH;AAMA,SAAS,eAAe,OAAe,SAIpC;CACD,OAAO,IAAI,KAAK,aAAa,QAAQ,QAAQ;EAC3C,UAAU,QAAQ;EAClB,aAAa,QAAQ;EACrB,OAAO;CACT,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,CAAC,KAAI,SAAQ,KAAK,SAAS,cAAc,aAAa,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE;AAClG;AAKA,SAAS,YAAY,OAAe,MAAY;CAC9C,IAAI,SAAS,QACX,OAAO;CAET,IAAI,QAAQ,GACV,OAAO;CAET,IAAI,QAAQ,GACV,OAAO;CAET,OAAO;AACT"}
@@ -0,0 +1,32 @@
1
+ import { ButtonProps } from "@base-ui/react/button";
2
+ //#region src/components/icon-button/index.d.ts
3
+ type IconButtonProps = ButtonProps & {
4
+ /**
5
+ * What the button does, in words. Required rather than optional: an icon
6
+ * on its own has no accessible name, so without this the control announces
7
+ * nothing at all.
8
+ */
9
+ 'aria-label': string;
10
+ /**
11
+ * Disables the press ripple. The hover and pressed state layers are
12
+ * unaffected.
13
+ * @default false
14
+ */
15
+ disableRipple?: boolean;
16
+ /**
17
+ * Control size: `xs` 32px, `md` 40px, `lg` 56px — the same heights `Button`
18
+ * uses, so the two line up beside each other in a row.
19
+ * @default 'md'
20
+ */
21
+ size?: 'lg' | 'md' | 'xs';
22
+ /**
23
+ * `standard` is transparent and tints what it sits on; `filled` and `tonal`
24
+ * carry a container of their own.
25
+ * @default 'standard'
26
+ */
27
+ variant?: 'filled' | 'standard' | 'tonal';
28
+ };
29
+ declare function IconButton({ children, disabled, disableRipple, onClick, onContextMenu, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, size, variant, ...props }: IconButtonProps): import("react").JSX.Element;
30
+ //#endregion
31
+ export { type IconButtonProps, IconButton as default };
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { useRipple } from "../../hooks/useRipple.js";
3
+ import { jsxs } from "react/jsx-runtime";
4
+ import { Button } from "@base-ui/react/button";
5
+ //#region src/components/icon-button/index.tsx
6
+ const styles = {
7
+ base: {
8
+ kGNEyG: "x6s0dn4",
9
+ kaIpWk: "xtecew7 x3y1ksm",
10
+ kMzoRj: "xc342km",
11
+ kkrTdU: "x1s07b3s x1ypdohk",
12
+ k1xSpc: "x3nfvp2",
13
+ kmuXW: "x2lah0s",
14
+ kjj79g: "xl56j7k",
15
+ kjBf7l: "xrgy624",
16
+ kInvED: "x1hl8ikr",
17
+ k3XXqK: "x9v5kkp x1t137rt",
18
+ kMeerF: "x1de99jn",
19
+ kmVPX3: "x1717udv",
20
+ kVAEAm: "x1n2onr6",
21
+ kIyJzY: "x1iuyhda",
22
+ k1ekBW: "xb5u718",
23
+ kAMwcw: "x15l9jch",
24
+ $$css: true
25
+ },
26
+ filled: {
27
+ kWkggS: "xm7dzmu x1n0xrd1 x197hsbc xnety89",
28
+ kMwMTN: "xhfb3ry xwjo7ld",
29
+ $$css: true
30
+ },
31
+ lg: {
32
+ kZKoxP: "xnnlda6",
33
+ kGuDYH: "x1s3cmhv",
34
+ kzqmXN: "x15yg21f",
35
+ $$css: true
36
+ },
37
+ md: {
38
+ kZKoxP: "x1vqgdyp",
39
+ kGuDYH: "x1pvqxga",
40
+ kzqmXN: "x100vrsf",
41
+ $$css: true
42
+ },
43
+ standard: {
44
+ kWkggS: "x1a42vn9 x6gcojk xjbqb8w",
45
+ kMwMTN: "xhfb3ry x1w5n3ug",
46
+ $$css: true
47
+ },
48
+ tonal: {
49
+ kWkggS: "x1c3n7wt x1n0xrd1 xwypj8i xp89om9",
50
+ kMwMTN: "xhfb3ry xscdzaa",
51
+ $$css: true
52
+ },
53
+ xs: {
54
+ kZKoxP: "x10w6t97",
55
+ kGuDYH: "xwsyq91",
56
+ kzqmXN: "x1td3qas",
57
+ $$css: true
58
+ }
59
+ };
60
+ function IconButton({ children, disabled = false, disableRipple = false, onClick, onContextMenu, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, size = "md", variant = "standard", ...props$1 }) {
61
+ const ripple = useRipple(!disableRipple, {
62
+ onClick,
63
+ onContextMenu,
64
+ onPointerCancel,
65
+ onPointerDown,
66
+ onPointerLeave,
67
+ onPointerUp
68
+ });
69
+ return /* @__PURE__ */ jsxs(Button, {
70
+ disabled,
71
+ ...ripple.handlers,
72
+ ...props$1,
73
+ ...props(styles.base, styles[variant], styles[size]),
74
+ children: [children, ripple.surface]
75
+ });
76
+ }
77
+ //#endregion
78
+ export { IconButton as default };
79
+
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/icon-button/index.tsx"],"sourcesContent":["import type { ButtonProps as BaseUIButtonProps } from '@base-ui/react/button';\nimport { Button as BaseUIButton } from '@base-ui/react/button';\nimport * as stylex from '@stylexjs/stylex';\nimport { useRipple } from '../../hooks/useRipple';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii, stateLayerOpacity } from '../../tokens/design.tokens.stylex';\n\n// Each variant composites an 'on-color' over its own container at the\n// interaction state's opacity, rather than swapping in a separate hover\n// color. calc(<opacity> * 100%) turns the token's unitless 0-1 ratio into the\n// percentage color-mix() takes. Inlined at each property rather than factored\n// into a helper: @stylexjs/babel-plugin only statically recognizes\n// expressions written directly as property values.\n//\n// :hover and :active still match a disabled native <button>, and stylex's\n// fixed pseudo-class ordering places both after :disabled, so without the\n// :not(:disabled) guard a hovered disabled button would render with the\n// interaction color instead of the disabled one.\n//\n// The corner softens from a circle to a rounded square while pressed, which\n// is the shape morph the source design gives this control. The two\n// transitioned properties take different curves — the colour change is\n// linear-ish and the shape change is emphasized — so the timing functions are\n// a matching comma list rather than one value.\nconst styles = {\n base: {\n kGNEyG: \"x6s0dn4\",\n kaIpWk: \"xtecew7 x3y1ksm\",\n kMzoRj: \"xc342km\",\n kkrTdU: \"x1s07b3s x1ypdohk\",\n k1xSpc: \"x3nfvp2\",\n kmuXW: \"x2lah0s\",\n kjj79g: \"xl56j7k\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kmVPX3: \"x1717udv\",\n kVAEAm: \"x1n2onr6\",\n kIyJzY: \"x1iuyhda\",\n k1ekBW: \"xb5u718\",\n kAMwcw: \"x15l9jch\",\n $$css: true\n },\n filled: {\n kWkggS: \"xm7dzmu x1n0xrd1 x197hsbc xnety89\",\n kMwMTN: \"xhfb3ry xwjo7ld\",\n $$css: true\n },\n lg: {\n kZKoxP: \"xnnlda6\",\n kGuDYH: \"x1s3cmhv\",\n kzqmXN: \"x15yg21f\",\n $$css: true\n },\n md: {\n kZKoxP: \"x1vqgdyp\",\n kGuDYH: \"x1pvqxga\",\n kzqmXN: \"x100vrsf\",\n $$css: true\n },\n standard: {\n kWkggS: \"x1a42vn9 x6gcojk xjbqb8w\",\n kMwMTN: \"xhfb3ry x1w5n3ug\",\n $$css: true\n },\n tonal: {\n kWkggS: \"x1c3n7wt x1n0xrd1 xwypj8i xp89om9\",\n kMwMTN: \"xhfb3ry xscdzaa\",\n $$css: true\n },\n xs: {\n kZKoxP: \"x10w6t97\",\n kGuDYH: \"xwsyq91\",\n kzqmXN: \"x1td3qas\",\n $$css: true\n }\n};\ntype IconButtonProps = BaseUIButtonProps & {\n /**\n * What the button does, in words. Required rather than optional: an icon\n * on its own has no accessible name, so without this the control announces\n * nothing at all.\n */\n 'aria-label': string;\n /**\n * Disables the press ripple. The hover and pressed state layers are\n * unaffected.\n * @default false\n */\n disableRipple?: boolean;\n /**\n * Control size: `xs` 32px, `md` 40px, `lg` 56px — the same heights `Button`\n * uses, so the two line up beside each other in a row.\n * @default 'md'\n */\n size?: 'lg' | 'md' | 'xs';\n /**\n * `standard` is transparent and tints what it sits on; `filled` and `tonal`\n * carry a container of their own.\n * @default 'standard'\n */\n variant?: 'filled' | 'standard' | 'tonal';\n};\nfunction IconButton({\n children,\n disabled = false,\n disableRipple = false,\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp,\n size = 'md',\n variant = 'standard',\n ...props\n}: IconButtonProps) {\n // `props` (className/style/render, etc.) is spread separately: `className`\n // and `style` there may be functions of render state, a Base UI extension\n // ripple's own handler-only merge doesn't need to know about.\n const ripple = useRipple<HTMLButtonElement>(!disableRipple, {\n onClick,\n onContextMenu,\n onPointerCancel,\n onPointerDown,\n onPointerLeave,\n onPointerUp\n });\n return <BaseUIButton disabled={disabled} {...ripple.handlers} {...props} {...stylex.props(styles.base, styles[variant], styles[size])}>\n {children}\n {ripple.surface}\n </BaseUIButton>;\n}\nexport type { IconButtonProps };\nexport default IconButton;"],"mappings":";;;;;AAwBA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;AACF;AA2BA,SAAS,WAAW,EAClB,UACA,WAAW,OACX,gBAAgB,OAChB,SACA,eACA,iBACA,eACA,gBACA,aACA,OAAO,MACP,UAAU,YACV,GAAG,WACe;CAIlB,MAAM,SAAS,UAA6B,CAAC,eAAe;EAC1D;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,OAAO,qBAAC,QAAD;EAAwB;EAAU,GAAI,OAAO;EAAU,GAAI;EAAO,GAAI,MAAa,OAAO,MAAM,OAAO,UAAU,OAAO,KAAK;EAA7H,UAAA,CACF,UACA,OAAO,OACI;;AAClB"}
@@ -0,0 +1,15 @@
1
+ import Avatar, { AvatarProps } from "./avatar/index.js";
2
+ import Badge, { BadgeProps } from "./badge/index.js";
3
+ import Button, { ButtonProps } from "./button/index.js";
4
+ import Card, { CardProps } from "./card/index.js";
5
+ import Chip, { ChipProps } from "./chip/index.js";
6
+ import Currency, { CurrencyProps } from "./currency/index.js";
7
+ import IconButton, { IconButtonProps } from "./icon-button/index.js";
8
+ import Link, { LinkProps } from "./link/index.js";
9
+ import ListItem, { ListItemProps } from "./list-item/index.js";
10
+ import Separator, { SeparatorProps } from "./separator/index.js";
11
+ import Sheet, { SheetProps } from "./sheet/index.js";
12
+ import Tabs, { TabsProps } from "./tabs/index.js";
13
+ import Text, { TextProps } from "./text/index.js";
14
+ import TextField, { TextFieldProps } from "./text-field/index.js";
15
+ export { Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Chip, type ChipProps, Currency, type CurrencyProps, IconButton, type IconButtonProps, Link, type LinkProps, ListItem, type ListItemProps, Separator, type SeparatorProps, Sheet, type SheetProps, Tabs, type TabsProps, Text, TextField, type TextFieldProps, type TextProps };
@@ -0,0 +1,30 @@
1
+ import { useRender } from "@base-ui/react/use-render";
2
+ //#region src/components/link/index.d.ts
3
+ type LinkProps = {
4
+ /**
5
+ * Which colour role to render in. `primary` marks the link out from the
6
+ * text around it; `inherit` takes the surrounding colour and leans on the
7
+ * underline alone, for a link in a place already understood to be links —
8
+ * a footer, a breadcrumb, a nav.
9
+ * @default 'primary'
10
+ */
11
+ tone?: LinkTone;
12
+ /**
13
+ * When to draw the rule. Leave it at `always` in prose: without it, colour
14
+ * is the only thing separating the link from the sentence, which some
15
+ * readers cannot see. `hover` and `none` are for links whose position
16
+ * already announces them, such as a row of footer links.
17
+ * @default 'always'
18
+ */
19
+ underline?: LinkUnderline;
20
+ } & useRender.ComponentProps<'a'>;
21
+ type LinkTone = 'inherit' | 'primary';
22
+ type LinkUnderline = 'always' | 'hover' | 'none';
23
+ /**
24
+ * A navigational link. It renders an `<a>` and sets no type of its own, so it
25
+ * takes the size and face of the text it sits in.
26
+ */
27
+ declare function Link({ render, tone, underline, ...props }: LinkProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
28
+ //#endregion
29
+ export { type LinkProps, Link as default };
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,61 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ //#region src/components/link/index.tsx
4
+ const styles = { base: {
5
+ kaIpWk: "x1tfhd1",
6
+ kkrTdU: "x1ypdohk",
7
+ kjBf7l: "xrgy624",
8
+ kInvED: "x1hl8ikr",
9
+ k3XXqK: "x9v5kkp x1t137rt",
10
+ kMeerF: "x1de99jn",
11
+ kNySMw: "xyi4chj",
12
+ kcSHmL: "x1ohr1zr",
13
+ kIyJzY: "x1qno0dh",
14
+ k1ekBW: "xz1df8t",
15
+ kAMwcw: "xpc4ca7",
16
+ $$css: true
17
+ } };
18
+ const tones = {
19
+ inherit: {
20
+ kMwMTN: "x1aetzt3 x1heor9g",
21
+ k1TLXF: "x1rdisx9 x1dbr5dg",
22
+ $$css: true
23
+ },
24
+ primary: {
25
+ kMwMTN: "x1mxwv8y",
26
+ k1TLXF: "x1rdisx9 xfhk6l2",
27
+ $$css: true
28
+ }
29
+ };
30
+ const underlines = {
31
+ always: {
32
+ kMnn75: "xujl8zx",
33
+ $$css: true
34
+ },
35
+ hover: {
36
+ kMnn75: "x1sur9pj xkrqix3",
37
+ $$css: true
38
+ },
39
+ none: {
40
+ kMnn75: "xkrqix3",
41
+ $$css: true
42
+ }
43
+ };
44
+ /**
45
+ * A navigational link. It renders an `<a>` and sets no type of its own, so it
46
+ * takes the size and face of the text it sits in.
47
+ */
48
+ function Link({ render, tone = "primary", underline = "always", ...props$1 }) {
49
+ return useRender({
50
+ defaultTagName: "a",
51
+ props: {
52
+ ...props$1,
53
+ ...props(styles.base, tones[tone], underlines[underline])
54
+ },
55
+ render
56
+ });
57
+ }
58
+ //#endregion
59
+ export { Link as default };
60
+
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/link/index.tsx"],"sourcesContent":["import { useRender } from '@base-ui/react/use-render';\nimport * as stylex from '@stylexjs/stylex';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, radii } from '../../tokens/design.tokens.stylex';\n\n// Deliberately sets no font size or family. A link is nearly always a run of\n// words inside something else — a paragraph, a list, a table cell — so its\n// type is the surrounding text's decision. What is here is only what makes it\n// read as a link: the colour, the rule under it, and the focus ring.\n//\n// The underline is on by default rather than an opt-in. Colour alone fails\n// anyone who cannot separate the two hues, so a link in prose that is not\n// underlined is only distinguishable to some readers.\nconst styles = {\n base: {\n kaIpWk: \"x1tfhd1\",\n kkrTdU: \"x1ypdohk\",\n kjBf7l: \"xrgy624\",\n kInvED: \"x1hl8ikr\",\n k3XXqK: \"x9v5kkp x1t137rt\",\n kMeerF: \"x1de99jn\",\n kNySMw: \"xyi4chj\",\n kcSHmL: \"x1ohr1zr\",\n kIyJzY: \"x1qno0dh\",\n k1ekBW: \"xz1df8t\",\n kAMwcw: \"xpc4ca7\",\n $$css: true\n }\n};\n\n// Each tone gets a hover that means something. `primary` is already the accent\n// colour, so hovering it deepens the rule instead of restating the colour;\n// `inherit` sits in body text, so hovering moves it to the accent — which is\n// what tells the reader the words are a link and not emphasis.\nconst tones = {\n inherit: {\n kMwMTN: \"x1aetzt3 x1heor9g\",\n k1TLXF: \"x1rdisx9 x1dbr5dg\",\n $$css: true\n },\n primary: {\n kMwMTN: \"x1mxwv8y\",\n k1TLXF: \"x1rdisx9 xfhk6l2\",\n $$css: true\n }\n};\nconst underlines = {\n always: {\n kMnn75: \"xujl8zx\",\n $$css: true\n },\n hover: {\n kMnn75: \"x1sur9pj xkrqix3\",\n $$css: true\n },\n none: {\n kMnn75: \"xkrqix3\",\n $$css: true\n }\n};\ntype LinkProps = {\n /**\n * Which colour role to render in. `primary` marks the link out from the\n * text around it; `inherit` takes the surrounding colour and leans on the\n * underline alone, for a link in a place already understood to be links —\n * a footer, a breadcrumb, a nav.\n * @default 'primary'\n */\n tone?: LinkTone;\n /**\n * When to draw the rule. Leave it at `always` in prose: without it, colour\n * is the only thing separating the link from the sentence, which some\n * readers cannot see. `hover` and `none` are for links whose position\n * already announces them, such as a row of footer links.\n * @default 'always'\n */\n underline?: LinkUnderline;\n} & useRender.ComponentProps<'a'>;\ntype LinkTone = 'inherit' | 'primary';\ntype LinkUnderline = 'always' | 'hover' | 'none';\n\n/**\n * A navigational link. It renders an `<a>` and sets no type of its own, so it\n * takes the size and face of the text it sits in.\n */\nfunction Link({\n render,\n tone = 'primary',\n underline = 'always',\n ...props\n}: LinkProps) {\n // stylex.props() spreads after `props` for the same reason Text and Currency\n // do it: it wins over a consumer-supplied className rather than merging with\n // one, so which of the two applies is not left to stylesheet order.\n return useRender({\n defaultTagName: 'a',\n props: {\n ...props,\n ...stylex.props(styles.base, tones[tone], underlines[underline])\n },\n render\n });\n}\nexport type { LinkProps };\nexport default Link;"],"mappings":";;;AAaA,MAAM,SAAS,EACb,MAAM;CACJ,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,OAAO;AACT,EACF;AAMA,MAAM,QAAQ;CACZ,SAAS;EACP,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAM,aAAa;CACjB,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;AACF;;;;;AA0BA,SAAS,KAAK,EACZ,QACA,OAAO,WACP,YAAY,UACZ,GAAG,WACS;CAIZ,OAAO,UAAU;EACf,gBAAgB;EAChB,OAAO;GACL,GAAG;GACH,GAAG,MAAa,OAAO,MAAM,MAAM,OAAO,WAAW,UAAU;EACjE;EACA;CACF,CAAC;AACH"}
@@ -0,0 +1,22 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ //#region src/components/list-item/index.d.ts
3
+ type ListItemProps = {
4
+ /** The row's headline — the one thing it is mostly about. */
5
+ children?: ReactNode;
6
+ /**
7
+ * Renders a `<button>` that ripples and tints on hover, for a row that is
8
+ * itself pressable. Leave it off for a row that only presents.
9
+ * @default false
10
+ */
11
+ interactive?: boolean;
12
+ /** Content before the headline: an avatar, an icon, a checkbox. */
13
+ leading?: ReactNode;
14
+ /** A second line under the headline, in the muted role. */
15
+ supporting?: ReactNode;
16
+ /** Content after the headline, such as an amount or a control. */
17
+ trailing?: ReactNode;
18
+ } & HTMLAttributes<HTMLElement>;
19
+ declare function ListItem({ children, interactive, leading, supporting, trailing, ...props }: ListItemProps): import("react").JSX.Element;
20
+ //#endregion
21
+ export { type ListItemProps, ListItem as default };
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,42 @@
1
+ import { useRipple } from "../../hooks/useRipple.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/components/list-item/index.tsx
4
+ function ListItem({ children, interactive = false, leading, supporting, trailing, ...props }) {
5
+ const ripple = useRipple(interactive);
6
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
7
+ leading === void 0 ? null : /* @__PURE__ */ jsx("span", {
8
+ className: "x6s0dn4 x78zum5 x2lah0s",
9
+ children: leading
10
+ }),
11
+ /* @__PURE__ */ jsxs("span", {
12
+ className: "x78zum5 xdt5ytf x1iyjqo2 x14qo01y xeuugli",
13
+ children: [/* @__PURE__ */ jsx("span", {
14
+ className: "xkknnkr x14zspaw x1v9cpvo x155f00i x1lz68p4",
15
+ children
16
+ }), supporting === void 0 ? null : /* @__PURE__ */ jsx("span", {
17
+ className: "x1w5n3ug x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh",
18
+ children: supporting
19
+ })]
20
+ }),
21
+ trailing === void 0 ? null : /* @__PURE__ */ jsx("span", {
22
+ className: "x6s0dn4 x78zum5 x2lah0s",
23
+ children: trailing
24
+ })
25
+ ] });
26
+ if (!interactive) return /* @__PURE__ */ jsx("div", {
27
+ ...props,
28
+ className: "x6s0dn4 xjbqb8w xc342km x139gbkf x78zum5 xxj4525 xh8yej3 xbktkl8 x1uvvd8r x790zyz x1n2onr6 x1yc453h",
29
+ children: content
30
+ });
31
+ return /* @__PURE__ */ jsxs("button", {
32
+ type: "button",
33
+ ...ripple.handlers,
34
+ ...props,
35
+ className: "x6s0dn4 xc342km x139gbkf x78zum5 xxj4525 xh8yej3 xbktkl8 x1uvvd8r x790zyz x1n2onr6 x1yc453h x83qkoq x1p2om7n xjbqb8w x1ypdohk xln7xf2 xrgy624 x2ssjo2 x9v5kkp x1t137rt x1de99jn",
36
+ children: [content, ripple.surface]
37
+ });
38
+ }
39
+ //#endregion
40
+ export { ListItem as default };
41
+
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/list-item/index.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { useRipple } from '../../hooks/useRipple';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, spacing, stateLayerOpacity, typography } from '../../tokens/design.tokens.stylex';\n\n// Laid out with flex rather than the grid the design draws. The design's\n// three columns are `auto 1fr auto`, which is what flex does natively — and\n// unlike a fixed three-column grid it stays correct when a row has no leading\n// or no trailing content, where the remaining children would otherwise slide\n// into the wrong columns.\n//\n// Rows align with each other through their leading content being the same\n// size, not through a fixed column width: a list of Avatars all at one size\n// lines up, and that is the same thing the design's 40px column achieves.\n//\n// The state layer composites over `transparent` rather than over a container\n// colour, because a row's own background is transparent and it therefore\n// tints whatever it happens to be sitting on — a card, or the page.\n\ntype ListItemProps = {\n /** The row's headline — the one thing it is mostly about. */\n children?: ReactNode;\n /**\n * Renders a `<button>` that ripples and tints on hover, for a row that is\n * itself pressable. Leave it off for a row that only presents.\n * @default false\n */\n interactive?: boolean;\n /** Content before the headline: an avatar, an icon, a checkbox. */\n leading?: ReactNode;\n /** A second line under the headline, in the muted role. */\n supporting?: ReactNode;\n /** Content after the headline, such as an amount or a control. */\n trailing?: ReactNode;\n} & HTMLAttributes<HTMLElement>;\nfunction ListItem({\n children,\n interactive = false,\n leading,\n supporting,\n trailing,\n ...props\n}: ListItemProps) {\n const ripple = useRipple<HTMLButtonElement>(interactive);\n const content = <>\n {leading === undefined ? null : <span className=\"x6s0dn4 x78zum5 x2lah0s\">{leading}</span>}\n <span className=\"x78zum5 xdt5ytf x1iyjqo2 x14qo01y xeuugli\">\n <span className=\"xkknnkr x14zspaw x1v9cpvo x155f00i x1lz68p4\">{children}</span>\n {supporting === undefined ? null : <span className=\"x1w5n3ug x1yicsit x1b35g6e x9d6959 xwth0xh xybisxh\">{supporting}</span>}\n </span>\n {trailing === undefined ? null : <span className=\"x6s0dn4 x78zum5 x2lah0s\">{trailing}</span>}\n </>;\n if (!interactive) {\n return <div {...props} className=\"x6s0dn4 xjbqb8w xc342km x139gbkf x78zum5 xxj4525 xh8yej3 xbktkl8 x1uvvd8r x790zyz x1n2onr6 x1yc453h\">\n {content}\n </div>;\n }\n return <button type=\"button\" {...ripple.handlers} {...props} className=\"x6s0dn4 xc342km x139gbkf x78zum5 xxj4525 xh8yej3 xbktkl8 x1uvvd8r x790zyz x1n2onr6 x1yc453h x83qkoq x1p2om7n xjbqb8w x1ypdohk xln7xf2 xrgy624 x2ssjo2 x9v5kkp x1t137rt x1de99jn\">\n {content}\n {ripple.surface}\n </button>;\n}\nexport type { ListItemProps };\nexport default ListItem;"],"mappings":";;;AAoCA,SAAS,SAAS,EAChB,UACA,cAAc,OACd,SACA,YACA,UACA,GAAG,SACa;CAChB,MAAM,SAAS,UAA6B,WAAW;CACvD,MAAM,UAAU,qBAAA,UAAA,EAAA,UAAA;EACX,YAAY,KAAA,IAAY,OAAO,oBAAC,QAAD;GAAM,WAAU;GAA2B,UAAA;EAAc,CAAA;EACzF,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;IAA+C;GAAe,CAAA,GAC7E,eAAe,KAAA,IAAY,OAAO,oBAAC,QAAD;IAAM,WAAU;IAAsD,UAAA;GAAiB,CAAA,CACtH;;EACL,aAAa,KAAA,IAAY,OAAO,oBAAC,QAAD;GAAM,WAAU;GAA2B,UAAA;EAAe,CAAA;CAC7F,EAAA,CAAA;CACF,IAAI,CAAC,aACH,OAAO,oBAAC,OAAD;EAAK,GAAI;EAAO,WAAU;EAC5B,UAAA;CACE,CAAA;CAET,OAAO,qBAAC,UAAD;EAAQ,MAAK;EAAS,GAAI,OAAO;EAAU,GAAI;EAAO,WAAU;EAAhE,UAAA,CACF,SACA,OAAO,OACF;;AACZ"}