@stll/ui 0.55.1 → 0.57.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 (71) hide show
  1. package/README.md +3 -0
  2. package/THIRD_PARTY_NOTICES +24 -0
  3. package/dist/components/badge.d.ts +28 -0
  4. package/dist/components/badge.js +64 -0
  5. package/dist/components/button.d.ts +2 -6
  6. package/dist/components/button.js +33 -25
  7. package/dist/components/button.native.d.ts +15 -0
  8. package/dist/components/button.native.js +165 -0
  9. package/dist/components/button.shared.d.ts +65 -0
  10. package/dist/components/button.shared.js +61 -0
  11. package/dist/components/dialog.d.ts +20 -2
  12. package/dist/components/dialog.js +31 -9
  13. package/dist/components/horizontal-scroller.js +31 -34
  14. package/dist/components/input.native.d.ts +23 -0
  15. package/dist/components/input.native.js +66 -0
  16. package/dist/components/input.shared.d.ts +19 -0
  17. package/dist/components/input.shared.js +0 -0
  18. package/dist/components/loader.d.ts +1 -6
  19. package/dist/components/loader.native.d.ts +28 -0
  20. package/dist/components/loader.native.js +23 -0
  21. package/dist/components/loader.shared.d.ts +17 -0
  22. package/dist/components/loader.shared.js +9 -0
  23. package/dist/components/matter-icon.d.ts +2 -8
  24. package/dist/components/matter-icon.js +10 -30
  25. package/dist/components/matter-icon.native.d.ts +25 -0
  26. package/dist/components/matter-icon.native.js +78 -0
  27. package/dist/components/matter-icon.shared.d.ts +21 -0
  28. package/dist/components/matter-icon.shared.js +18 -0
  29. package/dist/components/separator.native.d.ts +14 -0
  30. package/dist/components/separator.native.js +16 -0
  31. package/dist/components/separator.shared.d.ts +6 -0
  32. package/dist/components/separator.shared.js +0 -0
  33. package/dist/components/sheet.native.d.ts +27 -0
  34. package/dist/components/sheet.native.js +69 -0
  35. package/dist/components/sheet.shared.d.ts +9 -0
  36. package/dist/components/sheet.shared.js +0 -0
  37. package/dist/components/sidebar.js +1 -1
  38. package/dist/components/stella-wordmark.js +5 -13
  39. package/dist/components/stella-wordmark.native.d.ts +9 -0
  40. package/dist/components/stella-wordmark.native.js +27 -0
  41. package/dist/components/stella-wordmark.shared.d.ts +6 -0
  42. package/dist/components/stella-wordmark.shared.js +16 -0
  43. package/dist/components/switch.native.d.ts +13 -0
  44. package/dist/components/switch.native.js +33 -0
  45. package/dist/components/switch.shared.d.ts +9 -0
  46. package/dist/components/switch.shared.js +0 -0
  47. package/dist/components/table.d.ts +86 -8
  48. package/dist/components/table.js +46 -20
  49. package/dist/components/text.d.ts +11 -0
  50. package/dist/components/text.js +25 -0
  51. package/dist/components/text.native.d.ts +15 -0
  52. package/dist/components/text.native.js +46 -0
  53. package/dist/components/text.shared.d.ts +78 -0
  54. package/dist/components/text.shared.js +71 -0
  55. package/dist/components/textarea.native.d.ts +10 -0
  56. package/dist/components/textarea.native.js +28 -0
  57. package/dist/components/textarea.shared.d.ts +4 -0
  58. package/dist/components/textarea.shared.js +0 -0
  59. package/dist/components/tooltip.d.ts +15 -2
  60. package/dist/components/tooltip.js +18 -2
  61. package/dist/components/truncated-text.d.ts +33 -0
  62. package/dist/components/truncated-text.js +111 -0
  63. package/dist/index.d.ts +6 -5
  64. package/dist/index.js +5 -3
  65. package/dist/inspector/dock.js +1 -1
  66. package/dist/lib/scroll-edge-fade.d.ts +23 -0
  67. package/dist/lib/scroll-edge-fade.js +62 -0
  68. package/dist/native-env.d.ts +1 -0
  69. package/package.json +112 -7
  70. package/dist/calendar/index.d.ts +0 -4
  71. package/dist/calendar/index.js +0 -4
@@ -0,0 +1,6 @@
1
+ //#region src/components/separator.shared.d.ts
2
+ /** The props every separator renderer accepts, with one meaning. */
3
+ export type SeparatorContract = {
4
+ orientation?: "horizontal" | "vertical";
5
+ };
6
+ //#endregion
File without changes
@@ -0,0 +1,27 @@
1
+ import { Button } from "./button.native.js";
2
+ import { ComponentProps } from "react";
3
+ import { ScrollView, ViewProps } from "react-native";
4
+ import { SheetContract } from "./sheet.shared.js";
5
+ import { Text as Text$1 } from "./text.native.js";
6
+ //#region src/components/sheet.native.d.ts
7
+ /**
8
+ * The web's `Sheet` (./sheet.tsx) on a phone: the platform's page sheet,
9
+ * sliding up over the screen. A swipe down or the system back gesture asks
10
+ * to close it through `onOpenChange(false)`, as Escape does on the web.
11
+ */
12
+ export declare const Sheet: ({ children, onOpenChange, open }: SheetContract) => import("react").JSX.Element;
13
+ /** The sheet's surface: the background, inset, and room for the keyboard. */
14
+ export declare const SheetPopup: ({ className, ...props }: ViewProps & {
15
+ className?: string | undefined;
16
+ }) => import("react").JSX.Element;
17
+ /** The title row: the title leading, a close or done action trailing. */
18
+ export declare const SheetHeader: ({ className, ...props }: ViewProps & {
19
+ className?: string | undefined;
20
+ }) => import("react").JSX.Element;
21
+ export declare const SheetTitle: (props: ComponentProps<typeof Text$1>) => import("react").JSX.Element;
22
+ export declare const SheetDescription: (props: ComponentProps<typeof Text$1>) => import("react").JSX.Element;
23
+ /** The sheet's body, scrolling when it outgrows the sheet. */
24
+ export declare const SheetPanel: ({ contentContainerClassName, ...props }: ComponentProps<typeof ScrollView>) => import("react").JSX.Element;
25
+ /** A button that closes the sheet, after its own `onPress`. */
26
+ export declare const SheetClose: ({ onPress, size, variant, ...props }: ComponentProps<typeof Button>) => import("react").JSX.Element;
27
+ //#endregion
@@ -0,0 +1,69 @@
1
+ import { Text as Text$1 } from "./text.native.js";
2
+ import { Button } from "./button.native.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { createContext, use } from "react";
5
+ import { KeyboardAvoidingView, Modal, Platform, ScrollView, View } from "react-native";
6
+ //#region src/components/sheet.native.tsx
7
+ /** Closes the sheet that holds it; nothing outside a sheet. */
8
+ const SheetCloseContext = createContext(() => void 0);
9
+ /**
10
+ * The web's `Sheet` (./sheet.tsx) on a phone: the platform's page sheet,
11
+ * sliding up over the screen. A swipe down or the system back gesture asks
12
+ * to close it through `onOpenChange(false)`, as Escape does on the web.
13
+ */
14
+ const Sheet = ({ children, onOpenChange, open = false }) => {
15
+ const close = () => {
16
+ onOpenChange?.(false);
17
+ };
18
+ return /* @__PURE__ */ jsx(Modal, {
19
+ animationType: "slide",
20
+ onRequestClose: close,
21
+ presentationStyle: "pageSheet",
22
+ visible: open,
23
+ children: /* @__PURE__ */ jsx(SheetCloseContext, {
24
+ value: close,
25
+ children
26
+ })
27
+ });
28
+ };
29
+ /** The sheet's surface: the background, inset, and room for the keyboard. */
30
+ const SheetPopup = ({ className, ...props }) => /* @__PURE__ */ jsx(KeyboardAvoidingView, {
31
+ behavior: Platform.OS === "ios" ? "padding" : void 0,
32
+ className: `bg-background flex-1 gap-4 px-5 pt-5 ${className ?? ""}`,
33
+ ...props
34
+ });
35
+ /** The title row: the title leading, a close or done action trailing. */
36
+ const SheetHeader = ({ className, ...props }) => /* @__PURE__ */ jsx(View, {
37
+ className: `flex-row items-center justify-between gap-4 ${className ?? ""}`,
38
+ ...props
39
+ });
40
+ const SheetTitle = (props) => /* @__PURE__ */ jsx(Text$1, {
41
+ accessibilityRole: "header",
42
+ variant: "headline",
43
+ ...props
44
+ });
45
+ const SheetDescription = (props) => /* @__PURE__ */ jsx(Text$1, {
46
+ variant: "caption",
47
+ ...props
48
+ });
49
+ /** The sheet's body, scrolling when it outgrows the sheet. */
50
+ const SheetPanel = ({ contentContainerClassName, ...props }) => /* @__PURE__ */ jsx(ScrollView, {
51
+ contentContainerClassName: `gap-4 ${contentContainerClassName ?? ""}`,
52
+ keyboardShouldPersistTaps: "handled",
53
+ ...props
54
+ });
55
+ /** A button that closes the sheet, after its own `onPress`. */
56
+ const SheetClose = ({ onPress, size = "sm", variant = "ghost", ...props }) => {
57
+ const close = use(SheetCloseContext);
58
+ return /* @__PURE__ */ jsx(Button, {
59
+ onPress: (event) => {
60
+ onPress?.(event);
61
+ close();
62
+ },
63
+ size,
64
+ variant,
65
+ ...props
66
+ });
67
+ };
68
+ //#endregion
69
+ export { Sheet, SheetClose, SheetDescription, SheetHeader, SheetPanel, SheetPopup, SheetTitle };
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/components/sheet.shared.d.ts
3
+ /** The props every sheet root accepts, with one meaning. */
4
+ export type SheetContract = {
5
+ open?: boolean;
6
+ onOpenChange?: (open: boolean) => void;
7
+ children?: ReactNode;
8
+ };
9
+ //#endregion
File without changes
@@ -346,7 +346,7 @@ const SidebarMenuButton = ({ asChild = false, isActive = false, variant = "defau
346
346
  };
347
347
  const SidebarMenuAction = ({ className, asChild = false, showOnHover = false, ...props }) => {
348
348
  return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
349
- className: cn("text-sidebar-foreground ring-sidebar-ring peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute end-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", "after:absolute after:-inset-2 md:after:hidden", "peer-data-[size=sm]/menu-button:top-1", "peer-data-[size=default]/menu-button:top-1.5", "peer-data-[size=lg]/menu-button:top-2.5", "group-data-[collapsible=icon]:hidden", showOnHover && "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0", className),
349
+ className: cn("text-sidebar-foreground ring-sidebar-ring peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute end-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", "after:absolute after:-inset-2 md:after:hidden", "peer-data-[size=sm]/menu-button:top-1", "peer-data-[size=default]/menu-button:top-1.5", "peer-data-[size=lg]/menu-button:top-2.5", "group-data-[collapsible=icon]:hidden", showOnHover && "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0 pointer-coarse:opacity-100", className),
350
350
  "data-sidebar": "menu-action",
351
351
  "data-slot": "sidebar-menu-action",
352
352
  ...props
@@ -1,21 +1,13 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { STELLA_WORDMARK } from "./stella-wordmark.shared.js";
2
+ import { jsx } from "react/jsx-runtime";
2
3
  //#region src/components/stella-wordmark.tsx
3
- const StellaWordmarkLatin = (props) => /* @__PURE__ */ jsxs("svg", {
4
+ const StellaWordmarkLatin = (props) => /* @__PURE__ */ jsx("svg", {
4
5
  "aria-hidden": "true",
5
6
  fill: "currentColor",
6
- viewBox: "0 0 573 151",
7
+ viewBox: STELLA_WORDMARK.viewBox,
7
8
  xmlns: "http://www.w3.org/2000/svg",
8
9
  ...props,
9
- children: [
10
- /* @__PURE__ */ jsx("path", { d: "M23.54 44.93L59.65 22.32C63.19 20.1 67.28 18.94 71.49 18.94C75.7 18.94 79.79 20.1 83.32 22.32L135.77 55.14V37.56L91.2 9.63C85.32 5.96 78.5 3.99 71.49 3.99C64.48 3.99 57.63 5.93 51.74 9.63L15.63 32.24C5.85 38.39 0 48.96 0 60.52C0 72.08 5.85 82.65 15.63 88.77L27.27 96.05L67.11 121.04C67.63 121.36 68.08 121.59 68.5 121.75C70.94 122.68 73.58 122.42 75.77 121.07L110.05 99.62C110.05 99.62 110.3 99.46 110.4 99.36L117.8 94.72L107.73 88.48L103.78 86L71.55 106.13L70.07 105.26L23.57 76.11C18.11 72.66 14.95 66.99 14.95 60.52C14.95 54.05 18.11 48.38 23.57 44.93H23.54Z" }),
11
- /* @__PURE__ */ jsx("path", { d: "M119.18 109.86L83.07 132.47C79.53 134.7 75.44 135.85 71.23 135.85C67.02 135.85 62.93 134.7 59.4 132.47L6.91 99.65V117.24L51.49 145.13C57.37 148.8 64.19 150.77 71.2 150.77C78.21 150.77 85.06 148.84 90.94 145.13L127.06 122.52C136.83 116.4 142.69 105.84 142.69 94.27C142.69 82.71 136.83 72.15 127.06 66.03L115.42 58.75L75.57 33.75C75.06 33.43 74.61 33.21 74.19 33.05C71.75 32.11 69.11 32.37 66.92 33.72L32.64 55.17C32.64 55.17 32.38 55.33 32.29 55.43L24.89 60.07L34.96 66.32L38.91 68.8L71.13 48.67L72.61 49.54L119.12 78.69C124.58 82.13 127.73 87.8 127.73 94.27C127.73 100.75 124.58 106.42 119.12 109.86H119.18Z" }),
12
- /* @__PURE__ */ jsx("path", { d: "M230.38 123.02C212.11 123.02 195.46 115.06 189.49 98.78L200.89 89.91C203.96 99.87 213.55 109.82 230.92 109.82C241.23 109.82 248.11 105.84 248.11 98.06C248.11 90.1 240.15 87.56 229.83 85.21L218.26 82.5C205.77 79.6 192.2 73.63 192.2 57.53C192.2 41.61 204.51 31.84 223.5 31.84C241.96 31.84 254.8 41.61 259.69 53.19L247.75 62.05C243.4 51.74 235.08 45.23 222.6 45.23C213.55 45.23 207.04 49.21 207.04 56.63C207.04 64.41 212.83 67.12 224.77 70.01L235.99 72.91C255.71 77.61 262.22 85.75 262.22 97.88C262.22 115.24 247.38 123.02 230.38 123.02Z" }),
13
- /* @__PURE__ */ jsx("path", { d: "M304.21 123.2C289.92 123.2 279.79 113.8 279.79 98.78V45.95H265.67V33.65H279.79V22.43L295.52 10.85V33.65H324.29V45.95H295.52V94.08C295.52 105.29 300.77 108.01 307.65 108.01C315.43 108.01 320.85 101.49 323.21 96.07L328.45 111.63C324.65 117.6 316.33 123.2 304.21 123.2Z" }),
14
- /* @__PURE__ */ jsx("path", { d: "M371.45 123.02C346.66 123.02 329.48 105.29 329.48 77.43C329.48 49.75 346.48 31.84 370.54 31.84C395.33 31.84 410.34 48.3 410.34 73.99C410.34 76.71 409.98 79.42 409.62 81.05H344.67C345.58 99.5 355.89 110 371.45 110C389 110 396.05 100.41 399.49 92.81L409.08 103.66C402.57 114.16 390.44 123.02 371.45 123.02ZM370.54 45.05C356.43 45.05 347.02 53.37 345.03 69.65H396.23C394.6 53.55 385.2 45.05 370.54 45.05Z" }),
15
- /* @__PURE__ */ jsx("path", { d: "M442.77 121.21H427.03V0H442.77V121.21Z" }),
16
- /* @__PURE__ */ jsx("path", { d: "M478.55 121.21H462.81V0H478.55V121.21Z" }),
17
- /* @__PURE__ */ jsx("path", { d: "M516.68 123.02C501.84 123.02 493.52 114.52 493.52 102.94C493.52 91.18 502.39 83.76 514.87 78.16L546.53 64.04C545.99 53.73 541.1 46.13 527.35 46.13C514.87 46.13 506.55 53.37 502.02 62.96L491.35 51.92C496.6 42.88 509.62 31.84 529.16 31.84C550.69 31.84 562.27 44.69 562.27 65.49V101.49C562.27 105.66 563.9 106.92 567.15 106.92H572.76V121.21H562.63C553.58 121.21 547.07 116.87 547.07 104.57V98.42C544.18 110 534.77 123.02 516.68 123.02ZM509.44 100.41C509.44 106.38 513.6 110 521.74 110C536.58 110 547.07 100.23 547.07 87.56V75.44L521.56 87.38C513.24 91.36 509.44 94.98 509.44 100.41Z" })
18
- ]
10
+ children: STELLA_WORDMARK.paths.map((d) => /* @__PURE__ */ jsx("path", { d }, d))
19
11
  });
20
12
  //#endregion
21
13
  export { StellaWordmarkLatin };
@@ -0,0 +1,9 @@
1
+ //#region src/components/stella-wordmark.native.d.ts
2
+ /**
3
+ * The web's `StellaWordmarkLatin` (./stella-wordmark.tsx) on a phone: the
4
+ * same paths, in the foreground colour, `height` points tall.
5
+ */
6
+ export declare const StellaWordmarkLatin: ({ height }: {
7
+ height?: number | undefined;
8
+ }) => import("react").JSX.Element;
9
+ //#endregion
@@ -0,0 +1,27 @@
1
+ import { STELLA_WORDMARK } from "./stella-wordmark.shared.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import Svg, { Path } from "react-native-svg";
4
+ import { useCSSVariable } from "uniwind";
5
+ //#region src/components/stella-wordmark.native.tsx
6
+ const BOX = STELLA_WORDMARK.viewBox.split(" ").map(Number);
7
+ const WIDTH = BOX[2] ?? 1;
8
+ const HEIGHT = BOX[3] ?? 1;
9
+ /**
10
+ * The web's `StellaWordmarkLatin` (./stella-wordmark.tsx) on a phone: the
11
+ * same paths, in the foreground colour, `height` points tall.
12
+ */
13
+ const StellaWordmarkLatin = ({ height = 20 }) => {
14
+ const foreground = useCSSVariable("--color-foreground");
15
+ return /* @__PURE__ */ jsx(Svg, {
16
+ accessibilityLabel: "stella",
17
+ height,
18
+ viewBox: STELLA_WORDMARK.viewBox,
19
+ width: height * WIDTH / HEIGHT,
20
+ children: STELLA_WORDMARK.paths.map((d) => /* @__PURE__ */ jsx(Path, {
21
+ d,
22
+ fill: typeof foreground === "string" ? foreground : "currentColor"
23
+ }, d))
24
+ });
25
+ };
26
+ //#endregion
27
+ export { StellaWordmarkLatin };
@@ -0,0 +1,6 @@
1
+ //#region src/components/stella-wordmark.shared.d.ts
2
+ export declare const STELLA_WORDMARK: {
3
+ readonly viewBox: "0 0 573 151";
4
+ readonly paths: readonly ["M23.54 44.93L59.65 22.32C63.19 20.1 67.28 18.94 71.49 18.94C75.7 18.94 79.79 20.1 83.32 22.32L135.77 55.14V37.56L91.2 9.63C85.32 5.96 78.5 3.99 71.49 3.99C64.48 3.99 57.63 5.93 51.74 9.63L15.63 32.24C5.85 38.39 0 48.96 0 60.52C0 72.08 5.85 82.65 15.63 88.77L27.27 96.05L67.11 121.04C67.63 121.36 68.08 121.59 68.5 121.75C70.94 122.68 73.58 122.42 75.77 121.07L110.05 99.62C110.05 99.62 110.3 99.46 110.4 99.36L117.8 94.72L107.73 88.48L103.78 86L71.55 106.13L70.07 105.26L23.57 76.11C18.11 72.66 14.95 66.99 14.95 60.52C14.95 54.05 18.11 48.38 23.57 44.93H23.54Z", "M119.18 109.86L83.07 132.47C79.53 134.7 75.44 135.85 71.23 135.85C67.02 135.85 62.93 134.7 59.4 132.47L6.91 99.65V117.24L51.49 145.13C57.37 148.8 64.19 150.77 71.2 150.77C78.21 150.77 85.06 148.84 90.94 145.13L127.06 122.52C136.83 116.4 142.69 105.84 142.69 94.27C142.69 82.71 136.83 72.15 127.06 66.03L115.42 58.75L75.57 33.75C75.06 33.43 74.61 33.21 74.19 33.05C71.75 32.11 69.11 32.37 66.92 33.72L32.64 55.17C32.64 55.17 32.38 55.33 32.29 55.43L24.89 60.07L34.96 66.32L38.91 68.8L71.13 48.67L72.61 49.54L119.12 78.69C124.58 82.13 127.73 87.8 127.73 94.27C127.73 100.75 124.58 106.42 119.12 109.86H119.18Z", "M230.38 123.02C212.11 123.02 195.46 115.06 189.49 98.78L200.89 89.91C203.96 99.87 213.55 109.82 230.92 109.82C241.23 109.82 248.11 105.84 248.11 98.06C248.11 90.1 240.15 87.56 229.83 85.21L218.26 82.5C205.77 79.6 192.2 73.63 192.2 57.53C192.2 41.61 204.51 31.84 223.5 31.84C241.96 31.84 254.8 41.61 259.69 53.19L247.75 62.05C243.4 51.74 235.08 45.23 222.6 45.23C213.55 45.23 207.04 49.21 207.04 56.63C207.04 64.41 212.83 67.12 224.77 70.01L235.99 72.91C255.71 77.61 262.22 85.75 262.22 97.88C262.22 115.24 247.38 123.02 230.38 123.02Z", "M304.21 123.2C289.92 123.2 279.79 113.8 279.79 98.78V45.95H265.67V33.65H279.79V22.43L295.52 10.85V33.65H324.29V45.95H295.52V94.08C295.52 105.29 300.77 108.01 307.65 108.01C315.43 108.01 320.85 101.49 323.21 96.07L328.45 111.63C324.65 117.6 316.33 123.2 304.21 123.2Z", "M371.45 123.02C346.66 123.02 329.48 105.29 329.48 77.43C329.48 49.75 346.48 31.84 370.54 31.84C395.33 31.84 410.34 48.3 410.34 73.99C410.34 76.71 409.98 79.42 409.62 81.05H344.67C345.58 99.5 355.89 110 371.45 110C389 110 396.05 100.41 399.49 92.81L409.08 103.66C402.57 114.16 390.44 123.02 371.45 123.02ZM370.54 45.05C356.43 45.05 347.02 53.37 345.03 69.65H396.23C394.6 53.55 385.2 45.05 370.54 45.05Z", "M442.77 121.21H427.03V0H442.77V121.21Z", "M478.55 121.21H462.81V0H478.55V121.21Z", "M516.68 123.02C501.84 123.02 493.52 114.52 493.52 102.94C493.52 91.18 502.39 83.76 514.87 78.16L546.53 64.04C545.99 53.73 541.1 46.13 527.35 46.13C514.87 46.13 506.55 53.37 502.02 62.96L491.35 51.92C496.6 42.88 509.62 31.84 529.16 31.84C550.69 31.84 562.27 44.69 562.27 65.49V101.49C562.27 105.66 563.9 106.92 567.15 106.92H572.76V121.21H562.63C553.58 121.21 547.07 116.87 547.07 104.57V98.42C544.18 110 534.77 123.02 516.68 123.02ZM509.44 100.41C509.44 106.38 513.6 110 521.74 110C536.58 110 547.07 100.23 547.07 87.56V75.44L521.56 87.38C513.24 91.36 509.44 94.98 509.44 100.41Z"];
5
+ };
6
+ //#endregion
@@ -0,0 +1,16 @@
1
+ //#region src/components/stella-wordmark.shared.ts
2
+ const STELLA_WORDMARK = {
3
+ viewBox: "0 0 573 151",
4
+ paths: [
5
+ "M23.54 44.93L59.65 22.32C63.19 20.1 67.28 18.94 71.49 18.94C75.7 18.94 79.79 20.1 83.32 22.32L135.77 55.14V37.56L91.2 9.63C85.32 5.96 78.5 3.99 71.49 3.99C64.48 3.99 57.63 5.93 51.74 9.63L15.63 32.24C5.85 38.39 0 48.96 0 60.52C0 72.08 5.85 82.65 15.63 88.77L27.27 96.05L67.11 121.04C67.63 121.36 68.08 121.59 68.5 121.75C70.94 122.68 73.58 122.42 75.77 121.07L110.05 99.62C110.05 99.62 110.3 99.46 110.4 99.36L117.8 94.72L107.73 88.48L103.78 86L71.55 106.13L70.07 105.26L23.57 76.11C18.11 72.66 14.95 66.99 14.95 60.52C14.95 54.05 18.11 48.38 23.57 44.93H23.54Z",
6
+ "M119.18 109.86L83.07 132.47C79.53 134.7 75.44 135.85 71.23 135.85C67.02 135.85 62.93 134.7 59.4 132.47L6.91 99.65V117.24L51.49 145.13C57.37 148.8 64.19 150.77 71.2 150.77C78.21 150.77 85.06 148.84 90.94 145.13L127.06 122.52C136.83 116.4 142.69 105.84 142.69 94.27C142.69 82.71 136.83 72.15 127.06 66.03L115.42 58.75L75.57 33.75C75.06 33.43 74.61 33.21 74.19 33.05C71.75 32.11 69.11 32.37 66.92 33.72L32.64 55.17C32.64 55.17 32.38 55.33 32.29 55.43L24.89 60.07L34.96 66.32L38.91 68.8L71.13 48.67L72.61 49.54L119.12 78.69C124.58 82.13 127.73 87.8 127.73 94.27C127.73 100.75 124.58 106.42 119.12 109.86H119.18Z",
7
+ "M230.38 123.02C212.11 123.02 195.46 115.06 189.49 98.78L200.89 89.91C203.96 99.87 213.55 109.82 230.92 109.82C241.23 109.82 248.11 105.84 248.11 98.06C248.11 90.1 240.15 87.56 229.83 85.21L218.26 82.5C205.77 79.6 192.2 73.63 192.2 57.53C192.2 41.61 204.51 31.84 223.5 31.84C241.96 31.84 254.8 41.61 259.69 53.19L247.75 62.05C243.4 51.74 235.08 45.23 222.6 45.23C213.55 45.23 207.04 49.21 207.04 56.63C207.04 64.41 212.83 67.12 224.77 70.01L235.99 72.91C255.71 77.61 262.22 85.75 262.22 97.88C262.22 115.24 247.38 123.02 230.38 123.02Z",
8
+ "M304.21 123.2C289.92 123.2 279.79 113.8 279.79 98.78V45.95H265.67V33.65H279.79V22.43L295.52 10.85V33.65H324.29V45.95H295.52V94.08C295.52 105.29 300.77 108.01 307.65 108.01C315.43 108.01 320.85 101.49 323.21 96.07L328.45 111.63C324.65 117.6 316.33 123.2 304.21 123.2Z",
9
+ "M371.45 123.02C346.66 123.02 329.48 105.29 329.48 77.43C329.48 49.75 346.48 31.84 370.54 31.84C395.33 31.84 410.34 48.3 410.34 73.99C410.34 76.71 409.98 79.42 409.62 81.05H344.67C345.58 99.5 355.89 110 371.45 110C389 110 396.05 100.41 399.49 92.81L409.08 103.66C402.57 114.16 390.44 123.02 371.45 123.02ZM370.54 45.05C356.43 45.05 347.02 53.37 345.03 69.65H396.23C394.6 53.55 385.2 45.05 370.54 45.05Z",
10
+ "M442.77 121.21H427.03V0H442.77V121.21Z",
11
+ "M478.55 121.21H462.81V0H478.55V121.21Z",
12
+ "M516.68 123.02C501.84 123.02 493.52 114.52 493.52 102.94C493.52 91.18 502.39 83.76 514.87 78.16L546.53 64.04C545.99 53.73 541.1 46.13 527.35 46.13C514.87 46.13 506.55 53.37 502.02 62.96L491.35 51.92C496.6 42.88 509.62 31.84 529.16 31.84C550.69 31.84 562.27 44.69 562.27 65.49V101.49C562.27 105.66 563.9 106.92 567.15 106.92H572.76V121.21H562.63C553.58 121.21 547.07 116.87 547.07 104.57V98.42C544.18 110 534.77 123.02 516.68 123.02ZM509.44 100.41C509.44 106.38 513.6 110 521.74 110C536.58 110 547.07 100.23 547.07 87.56V75.44L521.56 87.38C513.24 91.36 509.44 94.98 509.44 100.41Z"
13
+ ]
14
+ };
15
+ //#endregion
16
+ export { STELLA_WORDMARK };
@@ -0,0 +1,13 @@
1
+ import { SwitchContract } from "./switch.shared.js";
2
+ import { SwitchProps } from "react-native";
3
+ //#region src/components/switch.native.d.ts
4
+ type SwitchProps$1 = Omit<SwitchProps, "value" | "onValueChange" | "disabled" | keyof SwitchContract> & SwitchContract;
5
+ /**
6
+ * The web's `Switch` (./switch.tsx) on a phone: the platform's own switch, in
7
+ * the web's colours (the primary fill when on, the input fill when off).
8
+ * Controlled through `checked`, or holding its own state from
9
+ * `defaultChecked`.
10
+ */
11
+ export declare const Switch: ({ checked, defaultChecked, disabled, onCheckedChange, ...props }: SwitchProps$1) => import("react").JSX.Element;
12
+ //#endregion
13
+ export {};
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Switch as Switch$1 } from "react-native";
4
+ //#region src/components/switch.native.tsx
5
+ /**
6
+ * The web's `Switch` (./switch.tsx) on a phone: the platform's own switch, in
7
+ * the web's colours (the primary fill when on, the input fill when off).
8
+ * Controlled through `checked`, or holding its own state from
9
+ * `defaultChecked`.
10
+ */
11
+ const Switch = ({ checked, defaultChecked = false, disabled = false, onCheckedChange, ...props }) => {
12
+ const [own, setOwn] = useState(defaultChecked);
13
+ const value = checked ?? own;
14
+ return /* @__PURE__ */ jsx(Switch$1, {
15
+ ...props,
16
+ accessibilityState: {
17
+ checked: value,
18
+ disabled
19
+ },
20
+ disabled,
21
+ ios_backgroundColorClassName: "accent-input",
22
+ onValueChange: (next) => {
23
+ setOwn(next);
24
+ onCheckedChange?.(next);
25
+ },
26
+ thumbColorClassName: "accent-background",
27
+ trackColorOffClassName: "accent-input",
28
+ trackColorOnClassName: "accent-primary",
29
+ value
30
+ });
31
+ };
32
+ //#endregion
33
+ export { Switch };
@@ -0,0 +1,9 @@
1
+ //#region src/components/switch.shared.d.ts
2
+ /** The props every switch renderer accepts, with one meaning. */
3
+ export type SwitchContract = {
4
+ checked?: boolean;
5
+ defaultChecked?: boolean;
6
+ disabled?: boolean;
7
+ onCheckedChange?: (checked: boolean) => void;
8
+ };
9
+ //#endregion
File without changes
@@ -1,20 +1,98 @@
1
1
  import * as React$1 from "react";
2
2
  //#region src/components/table.d.ts
3
- declare const Table: ({ className, ...props }: React$1.ComponentProps<"table">) => React$1.JSX.Element;
4
- declare const TableHeader: ({ className, ...props }: React$1.ComponentProps<"thead">) => React$1.JSX.Element;
3
+ /**
4
+ * How far cells pad their content from the column edges.
5
+ *
6
+ * `card` pads 16px, the inset of a card's header and body, so a table set
7
+ * directly inside a bordered card lines its columns up with the card's title.
8
+ */
9
+ type TableInset = "default" | "card";
10
+ /**
11
+ * Who scrolls a table wider or taller than its box. `self` wraps it in its own
12
+ * horizontal scroller. `parent` renders the bare table for a page that already
13
+ * scrolls it (a `ScrollArea`, a scrolling pane): a scroller of its own would
14
+ * become the reference box of a sticky header and stop it from sticking.
15
+ */
16
+ type TableScroll = "self" | "parent";
17
+ type TableProps = React$1.ComponentProps<"table"> & {
18
+ inset?: TableInset;
19
+ scroll?: TableScroll;
20
+ };
21
+ declare const Table: ({ className, inset, scroll, ...props }: TableProps) => React$1.JSX.Element;
22
+ type TableHeaderProps = React$1.ComponentProps<"thead"> & {
23
+ /**
24
+ * `muted` lays the header row on a muted band, separating it from the rows
25
+ * of a long list.
26
+ */
27
+ surface?: "plain" | "muted";
28
+ /**
29
+ * Keeps the header in view while the rows scroll under it, on a translucent
30
+ * muted band. The table must scroll with its parent (`scroll="parent"`).
31
+ */
32
+ sticky?: boolean;
33
+ };
34
+ declare const TableHeader: ({ className, surface, sticky, ...props }: TableHeaderProps) => React$1.JSX.Element;
5
35
  declare const TableBody: ({ className, ...props }: React$1.ComponentProps<"tbody">) => React$1.JSX.Element;
6
36
  declare const TableFooter: ({ className, ...props }: React$1.ComponentProps<"tfoot">) => React$1.JSX.Element;
7
- declare const TableRow: ({ className, ...props }: React$1.ComponentProps<"tr">) => React$1.JSX.Element;
8
- declare const TableHead: ({ className, ...props }: React$1.ComponentProps<"th">) => React$1.JSX.Element;
9
- declare const TableCell: ({ className, ...props }: React$1.ComponentProps<"td">) => React$1.JSX.Element;
37
+ /**
38
+ * `muted` greys out a row or a cell whose value no longer counts (a voided
39
+ * payment) or that only supports its neighbours (a secondary column).
40
+ */
41
+ type TableTone = "default" | "muted";
42
+ declare const TableRow: ({ className, tone, ...props }: React$1.ComponentProps<"tr"> & {
43
+ tone?: TableTone | undefined;
44
+ }) => React$1.JSX.Element;
45
+ /**
46
+ * Where a column sets its content. `end` lines up figures and amounts;
47
+ * `start` is the default reading edge. A `numeric` head or cell sets to the
48
+ * end unless it names an alignment, so a figures column needs one prop.
49
+ */
50
+ type TableAlign = "start" | "center" | "end";
51
+ type TableHeadProps = Omit<React$1.ComponentProps<"th">, "align"> & {
52
+ align?: TableAlign | undefined;
53
+ /**
54
+ * Heads a column of figures: tabular numerals, like its cells, set to the
55
+ * end unless `align` says otherwise.
56
+ */
57
+ numeric?: boolean | undefined;
58
+ };
59
+ declare const TableHead: ({ className, align, numeric, ...props }: TableHeadProps) => React$1.JSX.Element;
60
+ type TableCellProps = Omit<React$1.ComponentProps<"td">, "align"> & {
61
+ align?: TableAlign | undefined;
62
+ tone?: TableTone | undefined;
63
+ /**
64
+ * Figures set in tabular numerals and to the end of the cell (unless
65
+ * `align` says otherwise), so digits line up down the column.
66
+ */
67
+ numeric?: boolean | undefined;
68
+ /**
69
+ * Cuts text that overflows the cell with an ellipsis; the caller bounds the
70
+ * cell's width (`max-w-xs`).
71
+ */
72
+ truncate?: boolean;
73
+ /**
74
+ * The cell holds one control that fills it edge to edge and pads itself (a
75
+ * button that opens the row's record), so the cell adds no padding and the
76
+ * control's hover band reaches the cell's borders.
77
+ */
78
+ flush?: boolean;
79
+ };
80
+ declare const TableCell: ({ className, align, tone, numeric, truncate, flush, ...props }: TableCellProps) => React$1.JSX.Element;
10
81
  type SortDirection = "asc" | "desc" | null;
11
- type SortableHeadProps = Omit<React$1.ComponentProps<"th">, "onClick"> & {
82
+ type SortableHeadProps = Omit<TableHeadProps, "onClick"> & {
12
83
  sortDirection?: SortDirection;
13
84
  onSort: () => void;
14
85
  /** Rendered next to the sort button inside the same cell (e.g. filter icon). */
15
86
  trailing?: React$1.ReactNode;
16
87
  };
17
- declare const SortableHead: ({ children, sortDirection, onSort, trailing, className, ...props }: SortableHeadProps) => React$1.JSX.Element;
88
+ /**
89
+ * A column head the reader sorts by. The label is a quiet `Button`, so it
90
+ * has the design system's hover band, focus ring and touch target; its
91
+ * padding is pulled back so the label still lines up with the cells below.
92
+ * In an end-aligned (numeric) column the arrow sits before the label, keeping
93
+ * the label flush with the figures.
94
+ */
95
+ declare const SortableHead: ({ children, sortDirection, onSort, trailing, className, align, numeric, ...props }: SortableHeadProps) => React$1.JSX.Element;
18
96
  declare const TableCaption: ({ className, ...props }: React$1.ComponentProps<"caption">) => React$1.JSX.Element;
19
97
  //#endregion
20
- export { type SortDirection, SortableHead, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
98
+ export { type SortDirection, SortableHead, Table, type TableAlign, TableBody, TableCaption, TableCell, type TableCellProps, TableFooter, TableHead, type TableHeadProps, TableHeader, type TableHeaderProps, type TableInset, type TableProps, TableRow, type TableScroll, type TableTone };
@@ -1,18 +1,24 @@
1
1
  import { ArrowDownIcon, ArrowUpIcon } from "../icons.js";
2
2
  import { cn } from "../lib/utils.js";
3
+ import { Button } from "./button.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/components/table.tsx
5
- const Table = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
6
- className: "relative w-full overflow-x-auto",
7
- "data-slot": "table-container",
8
- children: /* @__PURE__ */ jsx("table", {
6
+ const Table = ({ className, inset = "default", scroll = "self", ...props }) => {
7
+ const table = /* @__PURE__ */ jsx("table", {
9
8
  className: cn("w-full caption-bottom text-sm in-data-[slot=frame]:border-separate in-data-[slot=frame]:border-spacing-0", className),
9
+ "data-inset": inset,
10
10
  "data-slot": "table",
11
11
  ...props
12
- })
13
- });
14
- const TableHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("thead", {
15
- className: cn("[&_tr]:border-b in-data-[slot=frame]:**:[th]:h-9 in-data-[slot=frame]:*:[tr]:border-none in-data-[slot=frame]:*:[tr]:hover:bg-transparent", className),
12
+ });
13
+ if (scroll === "parent") return table;
14
+ return /* @__PURE__ */ jsx("div", {
15
+ className: "relative w-full overflow-x-auto",
16
+ "data-slot": "table-container",
17
+ children: table
18
+ });
19
+ };
20
+ const TableHeader = ({ className, surface = "plain", sticky = false, ...props }) => /* @__PURE__ */ jsx("thead", {
21
+ className: cn("[&_tr]:border-b in-data-[slot=frame]:**:[th]:h-9 in-data-[slot=frame]:*:[tr]:border-none in-data-[slot=frame]:*:[tr]:hover:bg-transparent", surface === "muted" && "bg-muted/50", sticky && "bg-muted/80 sticky top-0 z-10 backdrop-blur", className),
16
22
  "data-slot": "table-header",
17
23
  ...props
18
24
  });
@@ -26,22 +32,39 @@ const TableFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("tfoot", {
26
32
  "data-slot": "table-footer",
27
33
  ...props
28
34
  });
29
- const TableRow = ({ className, ...props }) => /* @__PURE__ */ jsx("tr", {
30
- className: cn("hover:bg-muted/72 data-[state=selected]:bg-muted/72 border-b in-data-[slot=frame]:hover:bg-transparent in-data-[slot=frame]:data-[state=selected]:bg-transparent", className),
35
+ const TableRow = ({ className, tone = "default", ...props }) => /* @__PURE__ */ jsx("tr", {
36
+ className: cn("hover:bg-muted/72 data-[state=selected]:bg-muted/72 border-b in-data-[slot=frame]:hover:bg-transparent in-data-[slot=frame]:data-[state=selected]:bg-transparent", tone === "muted" && "text-muted-foreground", className),
31
37
  "data-slot": "table-row",
32
38
  ...props
33
39
  });
34
- const TableHead = ({ className, ...props }) => /* @__PURE__ */ jsx("th", {
35
- className: cn("text-muted-foreground h-10 px-2.5 text-start align-middle leading-none font-medium whitespace-nowrap has-[[role=checkbox]]:w-px has-[[role=checkbox]]:pe-0", className),
40
+ const TABLE_ALIGN_CLASS = {
41
+ center: "text-center",
42
+ end: "text-end",
43
+ start: "text-start"
44
+ };
45
+ const resolveTableAlign = (align, numeric) => align ?? (numeric ? "end" : void 0);
46
+ const TableHead = ({ className, align, numeric = false, ...props }) => /* @__PURE__ */ jsx("th", {
47
+ className: cn("text-muted-foreground h-10 px-2.5 align-middle leading-none font-medium whitespace-nowrap in-data-[inset=card]:px-4 has-[[role=checkbox]]:w-px has-[[role=checkbox]]:pe-0", TABLE_ALIGN_CLASS[resolveTableAlign(align, numeric) ?? "start"], numeric && "tabular-nums", className),
36
48
  "data-slot": "table-head",
37
49
  ...props
38
50
  });
39
- const TableCell = ({ className, ...props }) => /* @__PURE__ */ jsx("td", {
40
- className: cn("p-2.5 align-middle leading-none whitespace-nowrap in-data-[slot=frame]:first:p-[calc(--spacing(2.5)-1px)] in-data-[slot=frame]:last:p-[calc(--spacing(2.5)-1px)] has-[[role=checkbox]]:pe-0", className),
41
- "data-slot": "table-cell",
42
- ...props
43
- });
44
- const SortableHead = ({ children, sortDirection = null, onSort, trailing, className, ...props }) => {
51
+ const TableCell = ({ className, align, tone = "default", numeric = false, truncate = false, flush = false, ...props }) => {
52
+ const resolvedAlign = resolveTableAlign(align, numeric);
53
+ return /* @__PURE__ */ jsx("td", {
54
+ className: cn("align-middle leading-none whitespace-nowrap has-[[role=checkbox]]:pe-0", flush ? "p-0" : "p-2.5 in-data-[inset=card]:px-4 in-data-[slot=frame]:first:p-[calc(--spacing(2.5)-1px)] in-data-[slot=frame]:last:p-[calc(--spacing(2.5)-1px)]", resolvedAlign !== void 0 && TABLE_ALIGN_CLASS[resolvedAlign], tone === "muted" && "text-muted-foreground", numeric && "tabular-nums", truncate && "truncate", className),
55
+ "data-slot": "table-cell",
56
+ ...props
57
+ });
58
+ };
59
+ /**
60
+ * A column head the reader sorts by. The label is a quiet `Button`, so it
61
+ * has the design system's hover band, focus ring and touch target; its
62
+ * padding is pulled back so the label still lines up with the cells below.
63
+ * In an end-aligned (numeric) column the arrow sits before the label, keeping
64
+ * the label flush with the figures.
65
+ */
66
+ const SortableHead = ({ children, sortDirection = null, onSort, trailing, className, align, numeric = false, ...props }) => {
67
+ const endAligned = resolveTableAlign(align, numeric) === "end";
45
68
  let ariaSort = "none";
46
69
  if (sortDirection === "asc") ariaSort = "ascending";
47
70
  else if (sortDirection === "desc") ariaSort = "descending";
@@ -49,16 +72,19 @@ const SortableHead = ({ children, sortDirection = null, onSort, trailing, classN
49
72
  if (sortDirection === "asc") sortIcon = /* @__PURE__ */ jsx(ArrowUpIcon, { className: "size-3" });
50
73
  else if (sortDirection === "desc") sortIcon = /* @__PURE__ */ jsx(ArrowDownIcon, { className: "size-3" });
51
74
  return /* @__PURE__ */ jsx(TableHead, {
75
+ align,
52
76
  "aria-sort": ariaSort,
53
77
  className,
78
+ numeric,
54
79
  ...props,
55
80
  onClick: void 0,
56
81
  children: /* @__PURE__ */ jsxs("span", {
57
82
  className: "inline-flex items-center gap-1",
58
- children: [/* @__PURE__ */ jsxs("button", {
59
- className: "text-muted-foreground hover:text-foreground inline-flex cursor-pointer items-center gap-1 font-medium select-none",
83
+ children: [/* @__PURE__ */ jsxs(Button, {
84
+ className: cn("min-w-0 gap-1", endAligned ? "-me-3 flex-row-reverse" : "-ms-3"),
60
85
  onClick: onSort,
61
86
  type: "button",
87
+ variant: "muted",
62
88
  children: [/* @__PURE__ */ jsx("span", {
63
89
  className: "truncate",
64
90
  children
@@ -0,0 +1,11 @@
1
+ import { ComponentProps } from "react";
2
+ import { TextContract, TextVariant } from "./text.shared.js";
3
+ //#region src/components/text.d.ts
4
+ /**
5
+ * Text in one of the design system's roles (./text.shared.ts), the same role
6
+ * the React Native renderer (./text.native.tsx) sets on a phone. Inline, so a
7
+ * role can sit inside a paragraph; a block of prose is `Prose`.
8
+ */
9
+ declare const Text: ({ className, variant, ...props }: Omit<ComponentProps<"span">, keyof TextContract> & TextContract) => import("react").JSX.Element;
10
+ //#endregion
11
+ export { Text, type TextVariant };
@@ -0,0 +1,25 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { TEXT_VARIANT_CLASS_NAMES, TEXT_VARIANT_FACES } from "./text.shared.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/text.tsx
5
+ const WEIGHT_CLASS_NAMES = {
6
+ light: "font-light",
7
+ regular: "font-normal",
8
+ medium: "font-medium",
9
+ semibold: "font-semibold",
10
+ bold: "font-bold"
11
+ };
12
+ const faceClassName = (face) => cn(face.family === "serif" && "font-serif", WEIGHT_CLASS_NAMES[face.weight], face.italic === true && "italic");
13
+ /**
14
+ * Text in one of the design system's roles (./text.shared.ts), the same role
15
+ * the React Native renderer (./text.native.tsx) sets on a phone. Inline, so a
16
+ * role can sit inside a paragraph; a block of prose is `Prose`.
17
+ */
18
+ const Text = ({ className, variant = "body", ...props }) => /* @__PURE__ */ jsx("span", {
19
+ className: cn("text-foreground", TEXT_VARIANT_CLASS_NAMES[variant], faceClassName(TEXT_VARIANT_FACES[variant]), className),
20
+ "data-slot": "text",
21
+ "data-variant": variant,
22
+ ...props
23
+ });
24
+ //#endregion
25
+ export { Text };
@@ -0,0 +1,15 @@
1
+ import { TextContract, TextVariant } from "./text.shared.js";
2
+ import { TextProps } from "react-native";
3
+ //#region src/components/text.native.d.ts
4
+ /** The font a role is set in, for a native control that draws its own text. */
5
+ export declare const textFontFamily: (variant: TextContract["variant"]) => string;
6
+ /**
7
+ * Text in one of the design system's roles (./text.shared.ts), as the web
8
+ * renderer (./text.tsx) sets it: the same size and colour, in the role's
9
+ * embedded face.
10
+ */
11
+ export declare const Text: ({ className, style, variant, ...props }: Omit<TextProps, keyof TextContract> & TextContract & {
12
+ className?: string | undefined;
13
+ }) => import("react").JSX.Element;
14
+ //#endregion
15
+ export type { TextVariant };
@@ -0,0 +1,46 @@
1
+ import { TEXT_VARIANT_CLASS_NAMES, TEXT_VARIANT_FACES } from "./text.shared.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Text as Text$1 } from "react-native";
4
+ //#region src/components/text.native.tsx
5
+ /**
6
+ * The embedded font each face is, by the name the app registers it under:
7
+ * DM Sans, the web's typeface, for the interface; the platform's Georgia for
8
+ * reading, since the web reader's Source Serif 4 ships only as web fonts.
9
+ */
10
+ const faceName = ({ family, weight, italic }) => {
11
+ if (family === "serif") {
12
+ if (weight === "bold" || weight === "semibold") return italic === true ? "Georgia-BoldItalic" : "Georgia-Bold";
13
+ return italic === true ? "Georgia-Italic" : "Georgia";
14
+ }
15
+ return SANS_FACES[weight];
16
+ };
17
+ const SANS_FACES = {
18
+ light: "DMSans-Light",
19
+ regular: "DMSans-Regular",
20
+ medium: "DMSans-Medium",
21
+ semibold: "DMSans-SemiBold",
22
+ bold: "DMSans-Bold"
23
+ };
24
+ /** `text-` utilities that set a size, alignment or wrapping, not a colour. */
25
+ const NOT_A_COLOUR = /^text-(?:xs|sm|base|lg|\d*xl|\[|left|center|right|justify|start|end|wrap|nowrap|balance|pretty|ellipsis|clip)/u;
26
+ /**
27
+ * `classes` with the foreground colour first, unless they name a colour of
28
+ * their own. Both would be one utility, and the stylesheet orders utilities
29
+ * by name, so `text-foreground` would otherwise win over `text-destructive`
30
+ * whatever order they were written in.
31
+ */
32
+ const withForeground = (classes) => classes.split(/\s+/u).some((name) => name.startsWith("text-") && !NOT_A_COLOUR.test(name)) ? classes : `text-foreground ${classes}`;
33
+ /** The font a role is set in, for a native control that draws its own text. */
34
+ const textFontFamily = (variant) => faceName(TEXT_VARIANT_FACES[variant ?? "body"]);
35
+ /**
36
+ * Text in one of the design system's roles (./text.shared.ts), as the web
37
+ * renderer (./text.tsx) sets it: the same size and colour, in the role's
38
+ * embedded face.
39
+ */
40
+ const Text = ({ className, style, variant = "body", ...props }) => /* @__PURE__ */ jsx(Text$1, {
41
+ className: withForeground(`${TEXT_VARIANT_CLASS_NAMES[variant]} ${className ?? ""}`),
42
+ style: [{ fontFamily: textFontFamily(variant) }, style],
43
+ ...props
44
+ });
45
+ //#endregion
46
+ export { Text, textFontFamily };