@acronis-platform/ui-react 0.21.2

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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -0
  3. package/dist/components/ui/breadcrumb/breadcrumb.js +116 -0
  4. package/dist/components/ui/breadcrumb/breadcrumb.js.map +1 -0
  5. package/dist/components/ui/button/button.js +50 -0
  6. package/dist/components/ui/button/button.js.map +1 -0
  7. package/dist/components/ui/button-dropdown/button-dropdown.js +52 -0
  8. package/dist/components/ui/button-dropdown/button-dropdown.js.map +1 -0
  9. package/dist/components/ui/button-icon/button-icon.js +35 -0
  10. package/dist/components/ui/button-icon/button-icon.js.map +1 -0
  11. package/dist/components/ui/checkbox/checkbox.js +68 -0
  12. package/dist/components/ui/checkbox/checkbox.js.map +1 -0
  13. package/dist/components/ui/input/input.js +22 -0
  14. package/dist/components/ui/input/input.js.map +1 -0
  15. package/dist/components/ui/input-text-area/input-text-area.js +21 -0
  16. package/dist/components/ui/input-text-area/input-text-area.js.map +1 -0
  17. package/dist/components/ui/radio/radio.js +44 -0
  18. package/dist/components/ui/radio/radio.js.map +1 -0
  19. package/dist/components/ui/search/search.js +93 -0
  20. package/dist/components/ui/search/search.js.map +1 -0
  21. package/dist/components/ui/select/select.js +105 -0
  22. package/dist/components/ui/select/select.js.map +1 -0
  23. package/dist/components/ui/sidebar-primary/sidebar-primary.js +242 -0
  24. package/dist/components/ui/sidebar-primary/sidebar-primary.js.map +1 -0
  25. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js +372 -0
  26. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js.map +1 -0
  27. package/dist/components/ui/switch/switch.js +41 -0
  28. package/dist/components/ui/switch/switch.js.map +1 -0
  29. package/dist/components/ui/tag/tag.js +47 -0
  30. package/dist/components/ui/tag/tag.js.map +1 -0
  31. package/dist/components/ui/tooltip/tooltip.js +49 -0
  32. package/dist/components/ui/tooltip/tooltip.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +79 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/lib/utils.js +9 -0
  37. package/dist/lib/utils.js.map +1 -0
  38. package/dist/node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js +36 -0
  39. package/dist/node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js.map +1 -0
  40. package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js +17 -0
  41. package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +1 -0
  42. package/dist/node_modules/.pnpm/tailwind-merge@3.6.0/node_modules/tailwind-merge/dist/bundle-mjs.js +2996 -0
  43. package/dist/node_modules/.pnpm/tailwind-merge@3.6.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  44. package/dist/react.d.ts +2 -0
  45. package/dist/react.js +79 -0
  46. package/dist/react.js.map +1 -0
  47. package/dist/src/components/ui/breadcrumb/breadcrumb.d.ts +30 -0
  48. package/dist/src/components/ui/breadcrumb/index.d.ts +1 -0
  49. package/dist/src/components/ui/button/button.d.ts +16 -0
  50. package/dist/src/components/ui/button/index.d.ts +1 -0
  51. package/dist/src/components/ui/button-dropdown/button-dropdown.d.ts +29 -0
  52. package/dist/src/components/ui/button-dropdown/index.d.ts +1 -0
  53. package/dist/src/components/ui/button-icon/button-icon.d.ts +20 -0
  54. package/dist/src/components/ui/button-icon/index.d.ts +1 -0
  55. package/dist/src/components/ui/checkbox/checkbox.d.ts +10 -0
  56. package/dist/src/components/ui/checkbox/index.d.ts +1 -0
  57. package/dist/src/components/ui/input/index.d.ts +1 -0
  58. package/dist/src/components/ui/input/input.d.ts +4 -0
  59. package/dist/src/components/ui/input-text-area/index.d.ts +1 -0
  60. package/dist/src/components/ui/input-text-area/input-text-area.d.ts +4 -0
  61. package/dist/src/components/ui/radio/index.d.ts +1 -0
  62. package/dist/src/components/ui/radio/radio.d.ts +8 -0
  63. package/dist/src/components/ui/search/index.d.ts +1 -0
  64. package/dist/src/components/ui/search/search.d.ts +7 -0
  65. package/dist/src/components/ui/select/index.d.ts +1 -0
  66. package/dist/src/components/ui/select/select.d.ts +14 -0
  67. package/dist/src/components/ui/sidebar-primary/index.d.ts +1 -0
  68. package/dist/src/components/ui/sidebar-primary/sidebar-primary.d.ts +54 -0
  69. package/dist/src/components/ui/sidebar-secondary/index.d.ts +1 -0
  70. package/dist/src/components/ui/sidebar-secondary/sidebar-secondary.d.ts +85 -0
  71. package/dist/src/components/ui/switch/index.d.ts +1 -0
  72. package/dist/src/components/ui/switch/switch.d.ts +8 -0
  73. package/dist/src/components/ui/tag/index.d.ts +1 -0
  74. package/dist/src/components/ui/tag/tag.d.ts +12 -0
  75. package/dist/src/components/ui/tooltip/index.d.ts +1 -0
  76. package/dist/src/components/ui/tooltip/tooltip.d.ts +13 -0
  77. package/dist/src/index.d.ts +16 -0
  78. package/dist/src/lib/utils.d.ts +2 -0
  79. package/dist/src/react.d.ts +1 -0
  80. package/dist/styles.d.ts +1 -0
  81. package/dist/ui-react.css +1 -0
  82. package/package.json +119 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Acronis International GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # @acronis-platform/ui-react
2
+
3
+ The next-generation Acronis React component library — a **Base UI**
4
+ implementation, themed by [`@acronis-platform/tokens-pd`](../tokens-pd)
5
+ (generated from [`@acronis-platform/design-tokens`](../design-tokens)).
6
+
7
+ > Early days: this package is being built out component by component. See
8
+ > [`AGENTS.md`](./AGENTS.md) for conventions.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ pnpm add @acronis-platform/ui-react react react-dom
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```tsx
19
+ import '@acronis-platform/ui-react/styles';
20
+ import { Button, Switch } from '@acronis-platform/ui-react';
21
+
22
+ export function Example() {
23
+ return (
24
+ <div>
25
+ <Button variant="default">Save</Button>
26
+ <Switch defaultChecked />
27
+ </div>
28
+ );
29
+ }
30
+ ```
31
+
32
+ Toggle dark mode by adding the `dark` class to an ancestor element.
33
+
34
+ ## Fonts
35
+
36
+ The design tokens use **Inter** as the default family, and the generated CSS
37
+ emits a graceful fallback stack (`font-family: Inter, system-ui, sans-serif`).
38
+ The library deliberately **does not bundle the font** — loading it is the
39
+ consumer's choice, so you control hosting, subsets, and weights.
40
+
41
+ To render in Inter, self-host it (recommended — no third-party CDN, GDPR-safe).
42
+ [`@fontsource/inter`](https://fontsource.org/fonts/inter) (SIL Open Font
43
+ License) is the simplest route:
44
+
45
+ ```sh
46
+ pnpm add @fontsource/inter
47
+ ```
48
+
49
+ ```tsx
50
+ // Load only the weights you use (the typography scale uses 400/500/600/700).
51
+ import '@fontsource/inter/400.css';
52
+ import '@fontsource/inter/500.css';
53
+ import '@fontsource/inter/600.css';
54
+ import '@fontsource/inter/700.css';
55
+
56
+ import '@acronis-platform/ui-react/styles';
57
+ ```
58
+
59
+ > The static `@fontsource/inter` registers the family as `Inter`, which matches
60
+ > the token output. The variable package `@fontsource-variable/inter` registers
61
+ > `Inter Variable` instead, so it won't match `font-family: Inter` without an
62
+ > extra alias — prefer the static package unless you add that mapping yourself.
63
+
64
+ If you skip this step, text falls back to `system-ui` / the platform sans-serif.
65
+
66
+ ## Develop
67
+
68
+ ```sh
69
+ pnpm --filter @acronis-platform/ui-react storybook # explore components
70
+ pnpm --filter @acronis-platform/ui-react test # Vitest + RTL
71
+ pnpm --filter @acronis-platform/ui-react build # library bundle + types
72
+ ```
@@ -0,0 +1,116 @@
1
+ import { jsx as i, jsxs as c } from "react/jsx-runtime";
2
+ import * as l from "react";
3
+ import { mergeProps as o } from "@base-ui/react/merge-props";
4
+ import { useRender as n } from "@base-ui/react/use-render";
5
+ import { EllipsisIcon as m, ChevronRightIcon as d } from "@acronis-platform/icons-react/stroke-mono";
6
+ import { cn as s } from "../../../lib/utils.js";
7
+ const u = l.forwardRef(
8
+ ({ render: e, ...r }, a) => n({
9
+ render: e,
10
+ ref: a,
11
+ defaultTagName: "nav",
12
+ props: o({ "aria-label": "breadcrumb" }, r)
13
+ })
14
+ );
15
+ u.displayName = "Breadcrumb";
16
+ const b = l.forwardRef(({ className: e, ...r }, a) => /* @__PURE__ */ i(
17
+ "ol",
18
+ {
19
+ ref: a,
20
+ className: s(
21
+ "flex flex-wrap items-center gap-[var(--ui-breadcrumb-list-gap)] break-words text-sm font-normal leading-6",
22
+ e
23
+ ),
24
+ ...r
25
+ }
26
+ ));
27
+ b.displayName = "BreadcrumbList";
28
+ const p = l.forwardRef(({ className: e, ...r }, a) => /* @__PURE__ */ i(
29
+ "li",
30
+ {
31
+ ref: a,
32
+ className: s(
33
+ "inline-flex items-center gap-[var(--ui-breadcrumb-list-gap)]",
34
+ e
35
+ ),
36
+ ...r
37
+ }
38
+ ));
39
+ p.displayName = "BreadcrumbItem";
40
+ const f = l.forwardRef(
41
+ ({ className: e, render: r, ...a }, t) => n({
42
+ render: r,
43
+ ref: t,
44
+ defaultTagName: "a",
45
+ props: o(
46
+ {
47
+ className: s(
48
+ "rounded-sm text-[var(--ui-breadcrumb-link-label-color-idle)] no-underline transition-colors hover:text-[var(--ui-breadcrumb-link-label-color-hover)] hover:underline active:text-[var(--ui-breadcrumb-link-label-color-active)] focus-visible:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 ring-offset-background",
49
+ e
50
+ )
51
+ },
52
+ a
53
+ )
54
+ })
55
+ );
56
+ f.displayName = "BreadcrumbLink";
57
+ const v = l.forwardRef(({ className: e, ...r }, a) => /* @__PURE__ */ i(
58
+ "span",
59
+ {
60
+ ref: a,
61
+ role: "link",
62
+ "aria-disabled": "true",
63
+ "aria-current": "page",
64
+ className: s("text-[var(--ui-breadcrumb-page-label-color)]", e),
65
+ ...r
66
+ }
67
+ ));
68
+ v.displayName = "BreadcrumbPage";
69
+ const g = ({
70
+ children: e,
71
+ className: r,
72
+ ...a
73
+ }) => /* @__PURE__ */ i(
74
+ "li",
75
+ {
76
+ role: "presentation",
77
+ "aria-hidden": "true",
78
+ className: s(
79
+ "inline-flex items-center text-[var(--ui-breadcrumb-separator-icon-color)] [&>svg]:size-[var(--ui-breadcrumb-separator-icon-size)]",
80
+ r
81
+ ),
82
+ ...a,
83
+ children: e ?? /* @__PURE__ */ i(d, { size: 16 })
84
+ }
85
+ );
86
+ g.displayName = "BreadcrumbSeparator";
87
+ const N = ({
88
+ className: e,
89
+ ...r
90
+ }) => /* @__PURE__ */ c(
91
+ "span",
92
+ {
93
+ role: "presentation",
94
+ "aria-hidden": "true",
95
+ className: s(
96
+ "inline-flex size-4 items-center justify-center text-[var(--ui-breadcrumb-link-label-color-idle)]",
97
+ e
98
+ ),
99
+ ...r,
100
+ children: [
101
+ /* @__PURE__ */ i(m, { size: 16 }),
102
+ /* @__PURE__ */ i("span", { className: "sr-only", children: "More" })
103
+ ]
104
+ }
105
+ );
106
+ N.displayName = "BreadcrumbEllipsis";
107
+ export {
108
+ u as Breadcrumb,
109
+ N as BreadcrumbEllipsis,
110
+ p as BreadcrumbItem,
111
+ f as BreadcrumbLink,
112
+ b as BreadcrumbList,
113
+ v as BreadcrumbPage,
114
+ g as BreadcrumbSeparator
115
+ };
116
+ //# sourceMappingURL=breadcrumb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumb.js","sources":["../../../../src/components/ui/breadcrumb/breadcrumb.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { ChevronRightIcon, EllipsisIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Composable breadcrumb primitives mirroring the Figma \"Breadcrumb\" component.\n// Colors are wired to the next-gen `--ui-breadcrumb-*` tokens from\n// @acronis-platform/tokens-pd: links use `--ui-breadcrumb-link-label-color-<state>`\n// (idle gray, darkening on hover/active), the current page uses\n// `--ui-breadcrumb-page-label-color`, and the chevron separator uses\n// `--ui-breadcrumb-separator-icon-color` sized by `--ui-breadcrumb-separator-icon-size`\n// (16px). The inter-item gap is `--ui-breadcrumb-list-gap` (4px). Type is\n// 14px / 24px line-height to match the design's `body/default`.\n\nexport interface BreadcrumbProps extends React.ComponentPropsWithoutRef<'nav'> {\n /**\n * Replace the rendered `<nav>` with another element or component\n * (Base UI composition). Accepts a React element or a render function.\n */\n render?: useRender.RenderProp;\n}\n\nconst Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(\n ({ render, ...props }, ref) => {\n return useRender({\n render,\n ref,\n defaultTagName: 'nav',\n props: mergeProps<'nav'>({ 'aria-label': 'breadcrumb' }, props),\n });\n }\n);\nBreadcrumb.displayName = 'Breadcrumb';\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<'ol'>\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n 'flex flex-wrap items-center gap-[var(--ui-breadcrumb-list-gap)] break-words text-sm font-normal leading-6',\n className\n )}\n {...props}\n />\n));\nBreadcrumbList.displayName = 'BreadcrumbList';\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<'li'>\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(\n 'inline-flex items-center gap-[var(--ui-breadcrumb-list-gap)]',\n className\n )}\n {...props}\n />\n));\nBreadcrumbItem.displayName = 'BreadcrumbItem';\n\nexport interface BreadcrumbLinkProps\n extends React.ComponentPropsWithoutRef<'a'> {\n /**\n * Replace the rendered `<a>` with another element or component (e.g. a\n * router `Link`) via Base UI composition.\n */\n render?: useRender.RenderProp;\n}\n\nconst BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n ({ className, render, ...props }, ref) => {\n return useRender({\n render,\n ref,\n defaultTagName: 'a',\n props: mergeProps<'a'>(\n {\n className: cn(\n 'rounded-sm text-[var(--ui-breadcrumb-link-label-color-idle)] no-underline transition-colors hover:text-[var(--ui-breadcrumb-link-label-color-hover)] hover:underline active:text-[var(--ui-breadcrumb-link-label-color-active)] focus-visible:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 ring-offset-background',\n className\n ),\n },\n props\n ),\n });\n }\n);\nBreadcrumbLink.displayName = 'BreadcrumbLink';\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<'span'>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('text-[var(--ui-breadcrumb-page-label-color)]', className)}\n {...props}\n />\n));\nBreadcrumbPage.displayName = 'BreadcrumbPage';\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentPropsWithoutRef<'li'>) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center text-[var(--ui-breadcrumb-separator-icon-color)] [&>svg]:size-[var(--ui-breadcrumb-separator-icon-size)]',\n className\n )}\n {...props}\n >\n {children ?? <ChevronRightIcon size={16} />}\n </li>\n);\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentPropsWithoutRef<'span'>) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex size-4 items-center justify-center text-[var(--ui-breadcrumb-link-label-color-idle)]',\n className\n )}\n {...props}\n >\n <EllipsisIcon size={16} />\n <span className=\"sr-only\">More</span>\n </span>\n);\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"],"names":["Breadcrumb","React","render","props","ref","useRender","mergeProps","BreadcrumbList","className","jsx","cn","BreadcrumbItem","BreadcrumbLink","BreadcrumbPage","BreadcrumbSeparator","children","ChevronRightIcon","BreadcrumbEllipsis","jsxs","EllipsisIcon"],"mappings":";;;;;;AAwBA,MAAMA,IAAaC,EAAM;AAAA,EACvB,CAAC,EAAE,QAAAC,GAAQ,GAAGC,EAAA,GAASC,MACdC,EAAU;AAAA,IACf,QAAAH;AAAA,IACA,KAAAE;AAAA,IACA,gBAAgB;AAAA,IAChB,OAAOE,EAAkB,EAAE,cAAc,aAAA,GAAgBH,CAAK;AAAA,EAAA,CAC/D;AAEL;AACAH,EAAW,cAAc;AAEzB,MAAMO,IAAiBN,EAAM,WAG3B,CAAC,EAAE,WAAAO,GAAW,GAAGL,EAAA,GAASC,MAC1B,gBAAAK;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAL;AAAA,IACA,WAAWM;AAAA,MACT;AAAA,MACAF;AAAA,IAAA;AAAA,IAED,GAAGL;AAAA,EAAA;AACN,CACD;AACDI,EAAe,cAAc;AAE7B,MAAMI,IAAiBV,EAAM,WAG3B,CAAC,EAAE,WAAAO,GAAW,GAAGL,EAAA,GAASC,MAC1B,gBAAAK;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAL;AAAA,IACA,WAAWM;AAAA,MACT;AAAA,MACAF;AAAA,IAAA;AAAA,IAED,GAAGL;AAAA,EAAA;AACN,CACD;AACDQ,EAAe,cAAc;AAW7B,MAAMC,IAAiBX,EAAM;AAAA,EAC3B,CAAC,EAAE,WAAAO,GAAW,QAAAN,GAAQ,GAAGC,EAAA,GAASC,MACzBC,EAAU;AAAA,IACf,QAAAH;AAAA,IACA,KAAAE;AAAA,IACA,gBAAgB;AAAA,IAChB,OAAOE;AAAA,MACL;AAAA,QACE,WAAWI;AAAA,UACT;AAAA,UACAF;AAAA,QAAA;AAAA,MACF;AAAA,MAEFL;AAAA,IAAA;AAAA,EACF,CACD;AAEL;AACAS,EAAe,cAAc;AAE7B,MAAMC,IAAiBZ,EAAM,WAG3B,CAAC,EAAE,WAAAO,GAAW,GAAGL,EAAA,GAASC,MAC1B,gBAAAK;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAL;AAAA,IACA,MAAK;AAAA,IACL,iBAAc;AAAA,IACd,gBAAa;AAAA,IACb,WAAWM,EAAG,gDAAgDF,CAAS;AAAA,IACtE,GAAGL;AAAA,EAAA;AACN,CACD;AACDU,EAAe,cAAc;AAE7B,MAAMC,IAAsB,CAAC;AAAA,EAC3B,UAAAC;AAAA,EACA,WAAAP;AAAA,EACA,GAAGL;AACL,MACE,gBAAAM;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,MAAK;AAAA,IACL,eAAY;AAAA,IACZ,WAAWC;AAAA,MACT;AAAA,MACAF;AAAA,IAAA;AAAA,IAED,GAAGL;AAAA,IAEH,UAAAY,KAAY,gBAAAN,EAACO,GAAA,EAAiB,MAAM,GAAA,CAAI;AAAA,EAAA;AAC3C;AAEFF,EAAoB,cAAc;AAElC,MAAMG,IAAqB,CAAC;AAAA,EAC1B,WAAAT;AAAA,EACA,GAAGL;AACL,MACE,gBAAAe;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,MAAK;AAAA,IACL,eAAY;AAAA,IACZ,WAAWR;AAAA,MACT;AAAA,MACAF;AAAA,IAAA;AAAA,IAED,GAAGL;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAM,EAACU,GAAA,EAAa,MAAM,GAAA,CAAI;AAAA,MACxB,gBAAAV,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA,OAAA,CAAI;AAAA,IAAA;AAAA,EAAA;AAChC;AAEFQ,EAAmB,cAAc;"}
@@ -0,0 +1,50 @@
1
+ import { jsxs as c, Fragment as v, jsx as u } from "react/jsx-runtime";
2
+ import * as b from "react";
3
+ import { mergeProps as l } from "@base-ui/react/merge-props";
4
+ import { useRender as d } from "@base-ui/react/use-render";
5
+ import { SparklesIcon as s } from "@acronis-platform/icons-react/stroke-mono";
6
+ import { cva as g } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
7
+ import { cn as x } from "../../../lib/utils.js";
8
+ const h = g(
9
+ "inline-flex h-[var(--ui-button-global-container-height)] items-center justify-center gap-[var(--ui-button-global-container-gap)] whitespace-nowrap rounded-[var(--ui-button-global-container-border-radius)] border border-transparent text-sm font-semibold leading-6 ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-global-icon-size)] [&_svg]:shrink-0",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "min-w-[var(--ui-button-primary-container-width-min)] px-[var(--ui-button-primary-container-padding-x)] bg-[var(--ui-button-primary-container-color-idle)] text-[var(--ui-button-primary-label-color-idle)] [&_svg]:text-[var(--ui-button-primary-icon-color-idle)] hover:bg-[var(--ui-button-primary-container-color-hover)] hover:text-[var(--ui-button-primary-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-primary-icon-color-hover)] active:bg-[var(--ui-button-primary-container-color-active)] active:text-[var(--ui-button-primary-label-color-active)] active:[&_svg]:text-[var(--ui-button-primary-icon-color-active)] disabled:bg-[var(--ui-button-primary-container-color-disabled)] disabled:text-[var(--ui-button-primary-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-primary-icon-color-disabled)]",
14
+ secondary: "min-w-[var(--ui-button-secondary-container-width-min)] px-[var(--ui-button-secondary-container-padding-x)] bg-[var(--ui-button-secondary-container-color-idle)] text-[var(--ui-button-secondary-label-color-idle)] border-[var(--ui-button-secondary-container-border-color-idle)] [&_svg]:text-[var(--ui-button-secondary-icon-color-idle)] hover:bg-[var(--ui-button-secondary-container-color-hover)] hover:text-[var(--ui-button-secondary-label-color-hover)] hover:border-[var(--ui-button-secondary-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-secondary-icon-color-hover)] active:bg-[var(--ui-button-secondary-container-color-active)] active:text-[var(--ui-button-secondary-label-color-active)] active:border-[var(--ui-button-secondary-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-secondary-icon-color-active)] disabled:bg-[var(--ui-button-secondary-container-color-disabled)] disabled:text-[var(--ui-button-secondary-label-color-disabled)] disabled:border-[var(--ui-button-secondary-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-secondary-icon-color-disabled)]",
15
+ ghost: "px-[var(--ui-button-ghost-container-padding-x)] text-[var(--ui-button-ghost-label-color-idle)] [&_svg]:text-[var(--ui-button-ghost-icon-color-idle)] hover:text-[var(--ui-button-ghost-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-ghost-icon-color-hover)] active:text-[var(--ui-button-ghost-label-color-active)] active:[&_svg]:text-[var(--ui-button-ghost-icon-color-active)] disabled:text-[var(--ui-button-ghost-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-ghost-icon-color-disabled)]",
16
+ destructive: "min-w-[var(--ui-button-destructive-container-width-min)] px-[var(--ui-button-destructive-container-padding-x)] bg-[var(--ui-button-destructive-container-color-idle)] text-[var(--ui-button-destructive-label-color-idle)] [&_svg]:text-[var(--ui-button-destructive-icon-color-idle)] hover:bg-[var(--ui-button-destructive-container-color-hover)] hover:text-[var(--ui-button-destructive-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-destructive-icon-color-hover)] active:bg-[var(--ui-button-destructive-container-color-active)] active:text-[var(--ui-button-destructive-label-color-active)] active:[&_svg]:text-[var(--ui-button-destructive-icon-color-active)] disabled:bg-[var(--ui-button-destructive-container-color-disabled)] disabled:text-[var(--ui-button-destructive-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-destructive-icon-color-disabled)]",
17
+ ai: "min-w-[var(--ui-button-ai-container-width-min)] px-[var(--ui-button-ai-container-padding-x)] bg-origin-border text-[var(--ui-button-ai-label-color-idle)] [&_svg]:text-[var(--ui-button-ai-icon-color-idle)] [background-image:var(--ui-button-ai-container-color-idle)] hover:text-[var(--ui-button-ai-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-ai-icon-color-hover)] hover:[background-image:var(--ui-button-ai-container-color-hover)] active:text-[var(--ui-button-ai-label-color-active)] active:[&_svg]:text-[var(--ui-button-ai-icon-color-active)] active:[background-image:var(--ui-button-ai-container-color-active)] disabled:text-[var(--ui-button-ai-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-ai-icon-color-disabled)] disabled:[background-image:var(--ui-button-ai-container-color-disabled)]",
18
+ inverted: "min-w-[var(--ui-button-inverted-container-width-min)] px-[var(--ui-button-inverted-container-padding-x)] bg-[var(--ui-button-inverted-container-color-idle)] text-[var(--ui-button-inverted-label-color-idle)] border-[var(--ui-button-inverted-container-border-color-idle)] [&_svg]:text-[var(--ui-button-inverted-icon-color-idle)] hover:bg-[var(--ui-button-inverted-container-color-hover)] hover:text-[var(--ui-button-inverted-label-color-hover)] hover:border-[var(--ui-button-inverted-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-inverted-icon-color-hover)] active:bg-[var(--ui-button-inverted-container-color-active)] active:text-[var(--ui-button-inverted-label-color-active)] active:border-[var(--ui-button-inverted-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-inverted-icon-color-active)] disabled:bg-[var(--ui-button-inverted-container-color-disabled)] disabled:text-[var(--ui-button-inverted-label-color-disabled)] disabled:border-[var(--ui-button-inverted-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-inverted-icon-color-disabled)]"
19
+ }
20
+ },
21
+ defaultVariants: {
22
+ variant: "default"
23
+ }
24
+ }
25
+ ), m = b.forwardRef(
26
+ ({ className: r, variant: t, render: e, children: o, ...i }, a) => {
27
+ const n = t === "ai" ? /* @__PURE__ */ c(v, { children: [
28
+ /* @__PURE__ */ u(s, {}),
29
+ o
30
+ ] }) : o;
31
+ return d({
32
+ render: e,
33
+ ref: a,
34
+ defaultTagName: "button",
35
+ props: l(
36
+ {
37
+ className: x(h({ variant: t, className: r })),
38
+ children: n
39
+ },
40
+ i
41
+ )
42
+ });
43
+ }
44
+ );
45
+ m.displayName = "Button";
46
+ export {
47
+ m as Button,
48
+ h as buttonVariants
49
+ };
50
+ //# sourceMappingURL=button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","sources":["../../../../src/components/ui/button/button.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { SparklesIcon } from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Variants mirror the Figma \"Button\" component's `Variant` property (Primary,\n// Secondary, Link→ghost, Destructive, Ai, Inverted). Each interaction state\n// (idle / hover / active / disabled) wires the container fill, label, icon, and\n// — for the variants that have one — the border to its own dedicated\n// `--ui-button-*` token from @acronis-platform/tokens-pd. Every state is wired\n// explicitly — even where acronis's value is unchanged — because these are\n// runtime `var()` references: a brand override is only honored if the matching\n// state token is referenced. The icon color is wired separately from the label\n// because the next-gen tier diverges the two on hover/active for `secondary` and\n// `ghost` (the icon keeps the brighter blue while the label darkens). Disabled\n// uses the design's explicit disabled tokens (not opacity); the focus ring uses\n// the `--ui-focus-*` tokens.\n//\n// Geometry is now tokenized: the shared box metrics (32px height, 8px gap, 4px\n// radius, 16px icon) come from `--ui-button-global-container-*` / `-icon-size`,\n// while padding-x and min-width are per-variant — `ghost` has 0 padding-x and no\n// min-width (it reads as an inline link), every other variant has 12px / 64px.\n// Only `secondary` and `inverted` define a container border (1px); the rest paint\n// a transparent border so the box geometry stays identical across variants. The\n// `ai` variant paints its gradient container via `background-image` and sets\n// `bg-origin-border` so it covers the (transparent) 1px border box.\nconst buttonVariants = cva(\n 'inline-flex h-[var(--ui-button-global-container-height)] items-center justify-center gap-[var(--ui-button-global-container-gap)] whitespace-nowrap rounded-[var(--ui-button-global-container-border-radius)] border border-transparent text-sm font-semibold leading-6 ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-global-icon-size)] [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n 'min-w-[var(--ui-button-primary-container-width-min)] px-[var(--ui-button-primary-container-padding-x)] bg-[var(--ui-button-primary-container-color-idle)] text-[var(--ui-button-primary-label-color-idle)] [&_svg]:text-[var(--ui-button-primary-icon-color-idle)] hover:bg-[var(--ui-button-primary-container-color-hover)] hover:text-[var(--ui-button-primary-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-primary-icon-color-hover)] active:bg-[var(--ui-button-primary-container-color-active)] active:text-[var(--ui-button-primary-label-color-active)] active:[&_svg]:text-[var(--ui-button-primary-icon-color-active)] disabled:bg-[var(--ui-button-primary-container-color-disabled)] disabled:text-[var(--ui-button-primary-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-primary-icon-color-disabled)]',\n secondary:\n 'min-w-[var(--ui-button-secondary-container-width-min)] px-[var(--ui-button-secondary-container-padding-x)] bg-[var(--ui-button-secondary-container-color-idle)] text-[var(--ui-button-secondary-label-color-idle)] border-[var(--ui-button-secondary-container-border-color-idle)] [&_svg]:text-[var(--ui-button-secondary-icon-color-idle)] hover:bg-[var(--ui-button-secondary-container-color-hover)] hover:text-[var(--ui-button-secondary-label-color-hover)] hover:border-[var(--ui-button-secondary-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-secondary-icon-color-hover)] active:bg-[var(--ui-button-secondary-container-color-active)] active:text-[var(--ui-button-secondary-label-color-active)] active:border-[var(--ui-button-secondary-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-secondary-icon-color-active)] disabled:bg-[var(--ui-button-secondary-container-color-disabled)] disabled:text-[var(--ui-button-secondary-label-color-disabled)] disabled:border-[var(--ui-button-secondary-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-secondary-icon-color-disabled)]',\n ghost:\n 'px-[var(--ui-button-ghost-container-padding-x)] text-[var(--ui-button-ghost-label-color-idle)] [&_svg]:text-[var(--ui-button-ghost-icon-color-idle)] hover:text-[var(--ui-button-ghost-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-ghost-icon-color-hover)] active:text-[var(--ui-button-ghost-label-color-active)] active:[&_svg]:text-[var(--ui-button-ghost-icon-color-active)] disabled:text-[var(--ui-button-ghost-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-ghost-icon-color-disabled)]',\n destructive:\n 'min-w-[var(--ui-button-destructive-container-width-min)] px-[var(--ui-button-destructive-container-padding-x)] bg-[var(--ui-button-destructive-container-color-idle)] text-[var(--ui-button-destructive-label-color-idle)] [&_svg]:text-[var(--ui-button-destructive-icon-color-idle)] hover:bg-[var(--ui-button-destructive-container-color-hover)] hover:text-[var(--ui-button-destructive-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-destructive-icon-color-hover)] active:bg-[var(--ui-button-destructive-container-color-active)] active:text-[var(--ui-button-destructive-label-color-active)] active:[&_svg]:text-[var(--ui-button-destructive-icon-color-active)] disabled:bg-[var(--ui-button-destructive-container-color-disabled)] disabled:text-[var(--ui-button-destructive-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-destructive-icon-color-disabled)]',\n ai: 'min-w-[var(--ui-button-ai-container-width-min)] px-[var(--ui-button-ai-container-padding-x)] bg-origin-border text-[var(--ui-button-ai-label-color-idle)] [&_svg]:text-[var(--ui-button-ai-icon-color-idle)] [background-image:var(--ui-button-ai-container-color-idle)] hover:text-[var(--ui-button-ai-label-color-hover)] hover:[&_svg]:text-[var(--ui-button-ai-icon-color-hover)] hover:[background-image:var(--ui-button-ai-container-color-hover)] active:text-[var(--ui-button-ai-label-color-active)] active:[&_svg]:text-[var(--ui-button-ai-icon-color-active)] active:[background-image:var(--ui-button-ai-container-color-active)] disabled:text-[var(--ui-button-ai-label-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-ai-icon-color-disabled)] disabled:[background-image:var(--ui-button-ai-container-color-disabled)]',\n inverted:\n 'min-w-[var(--ui-button-inverted-container-width-min)] px-[var(--ui-button-inverted-container-padding-x)] bg-[var(--ui-button-inverted-container-color-idle)] text-[var(--ui-button-inverted-label-color-idle)] border-[var(--ui-button-inverted-container-border-color-idle)] [&_svg]:text-[var(--ui-button-inverted-icon-color-idle)] hover:bg-[var(--ui-button-inverted-container-color-hover)] hover:text-[var(--ui-button-inverted-label-color-hover)] hover:border-[var(--ui-button-inverted-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-inverted-icon-color-hover)] active:bg-[var(--ui-button-inverted-container-color-active)] active:text-[var(--ui-button-inverted-label-color-active)] active:border-[var(--ui-button-inverted-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-inverted-icon-color-active)] disabled:bg-[var(--ui-button-inverted-container-color-disabled)] disabled:text-[var(--ui-button-inverted-label-color-disabled)] disabled:border-[var(--ui-button-inverted-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-inverted-icon-color-disabled)]',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * Replace the rendered `<button>` with another element or component\n * (Base UI composition). Accepts a React element or a render function —\n * the component's props and class names are merged onto it.\n */\n render?: useRender.RenderProp;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, render, children, ...props }, ref) => {\n // The AI variant always leads with the Sparkles icon before its label\n // (the Figma \"Ai\" button is a Sparkles instance + label).\n const content =\n variant === 'ai' ? (\n <>\n <SparklesIcon />\n {children}\n </>\n ) : (\n children\n );\n return useRender({\n render,\n ref,\n defaultTagName: 'button',\n props: mergeProps<'button'>(\n {\n className: cn(buttonVariants({ variant, className })),\n children: content,\n },\n props\n ),\n });\n }\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n"],"names":["buttonVariants","cva","Button","React","className","variant","render","children","props","ref","content","jsxs","Fragment","jsx","SparklesIcon","useRender","mergeProps","cn"],"mappings":";;;;;;;AA6BA,MAAMA,IAAiBC;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,aACE;AAAA,QACF,IAAI;AAAA,QACJ,UACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAcMC,IAASC,EAAM;AAAA,EACnB,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,QAAAC,GAAQ,UAAAC,GAAU,GAAGC,EAAA,GAASC,MAAQ;AAG3D,UAAMC,IACJL,MAAY,OACV,gBAAAM,EAAAC,GAAA,EACE,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EAAa;AAAA,MACbP;AAAA,IAAA,EAAA,CACH,IAEAA;AAEJ,WAAOQ,EAAU;AAAA,MACf,QAAAT;AAAA,MACA,KAAAG;AAAA,MACA,gBAAgB;AAAA,MAChB,OAAOO;AAAA,QACL;AAAA,UACE,WAAWC,EAAGjB,EAAe,EAAE,SAAAK,GAAS,WAAAD,EAAA,CAAW,CAAC;AAAA,UACpD,UAAUM;AAAA,QAAA;AAAA,QAEZF;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EACH;AACF;AACAN,EAAO,cAAc;"}
@@ -0,0 +1,52 @@
1
+ import { jsxs as c, Fragment as d, jsx as b } from "react/jsx-runtime";
2
+ import * as l from "react";
3
+ import { mergeProps as s } from "@base-ui/react/merge-props";
4
+ import { useRender as v } from "@base-ui/react/use-render";
5
+ import { ChevronUpIcon as m, ChevronDownIcon as p } from "@acronis-platform/icons-react/stroke-mono";
6
+ import { cva as g } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
7
+ import { cn as y } from "../../../lib/utils.js";
8
+ const f = g(
9
+ "inline-flex h-[var(--ui-button-menu-global-container-height)] min-w-[var(--ui-button-menu-global-container-width-min)] items-center justify-center gap-[var(--ui-button-menu-global-container-gap)] whitespace-nowrap rounded-[var(--ui-button-menu-global-container-border-radius)] border border-transparent px-[var(--ui-button-menu-global-container-padding-x)] text-sm font-semibold leading-6 ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-menu-global-icon-size)] [&_svg]:shrink-0",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ primary: "bg-[var(--ui-button-menu-primary-container-color-idle)] text-[var(--ui-button-menu-primary-label-color)] [&_svg]:text-[var(--ui-button-menu-primary-icon-color)] hover:bg-[var(--ui-button-menu-primary-container-color-hover)] active:bg-[var(--ui-button-menu-primary-container-color-active)] data-[open]:bg-[var(--ui-button-menu-primary-container-color-active)] disabled:bg-[var(--ui-button-menu-primary-container-color-disabled)]",
14
+ secondary: "bg-[var(--ui-button-menu-secondary-container-color-idle)] text-[var(--ui-button-menu-secondary-label-color-idle)] border-[var(--ui-button-menu-secondary-container-border-color-idle)] [&_svg]:text-[var(--ui-button-menu-secondary-icon-color-idle)] hover:bg-[var(--ui-button-menu-secondary-container-color-hover)] hover:text-[var(--ui-button-menu-secondary-label-color-hover)] hover:border-[var(--ui-button-menu-secondary-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-hover)] active:bg-[var(--ui-button-menu-secondary-container-color-active)] active:text-[var(--ui-button-menu-secondary-label-color-active)] active:border-[var(--ui-button-menu-secondary-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-active)] data-[open]:bg-[var(--ui-button-menu-secondary-container-color-active)] data-[open]:text-[var(--ui-button-menu-secondary-label-color-active)] data-[open]:border-[var(--ui-button-menu-secondary-container-border-color-active)] data-[open]:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-active)] disabled:bg-[var(--ui-button-menu-secondary-container-color-disabled)] disabled:text-[var(--ui-button-menu-secondary-label-color-disabled)] disabled:border-[var(--ui-button-menu-secondary-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-disabled)]"
15
+ }
16
+ },
17
+ defaultVariants: {
18
+ variant: "primary"
19
+ }
20
+ }
21
+ ), h = l.forwardRef(
22
+ ({ className: r, variant: e, open: o, render: n, children: t, ...a }, i) => {
23
+ const u = o ? m : p;
24
+ return v({
25
+ render: n,
26
+ ref: i,
27
+ defaultTagName: "button",
28
+ props: s(
29
+ {
30
+ className: y(f({ variant: e, className: r })),
31
+ "aria-expanded": o,
32
+ // `data-open` drives the open (`*-active`) token switch via attribute
33
+ // selectors; present only while open, and typed loosely because
34
+ // React's button attribute map doesn't include arbitrary data-* keys
35
+ // as literals.
36
+ ...o ? { "data-open": "" } : {},
37
+ children: /* @__PURE__ */ c(d, { children: [
38
+ t,
39
+ /* @__PURE__ */ b(u, {})
40
+ ] })
41
+ },
42
+ a
43
+ )
44
+ });
45
+ }
46
+ );
47
+ h.displayName = "ButtonDropdown";
48
+ export {
49
+ h as ButtonDropdown,
50
+ f as buttonDropdownVariants
51
+ };
52
+ //# sourceMappingURL=button-dropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-dropdown.js","sources":["../../../../src/components/ui/button-dropdown/button-dropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport {\n ChevronDownIcon,\n ChevronUpIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Mirrors the Figma \"ButtonDropdown\" component: a Button-like trigger (label +\n// trailing chevron) that opens a menu. `variant` maps to the Figma `variant`\n// property (Primary / Secondary); the Figma `active` state is the **open** state\n// — the chevron flips down→up and the container takes its `*-active` colors. Each\n// interaction state wires the container fill, label, icon, and — for `secondary`\n// — the border to its own dedicated `--ui-button-menu-*` token from\n// @acronis-platform/tokens-pd. Every state is referenced explicitly (runtime\n// `var()` lookups: a brand override is only honored if the matching state token is\n// referenced). `primary` keeps a single label/icon color across states; only\n// `secondary` diverges them per state. Geometry — 32px height, 8px gap, 12px\n// padding-x, 4px radius, 64px min-width, 16px icon — comes from the\n// `--ui-button-menu-global-*` tokens. The open treatment is driven by the\n// `data-open` attribute (set from the `open` prop) and CSS `:active` for press\n// feedback; disabled uses the explicit disabled tokens (not opacity) and the\n// focus ring uses `--ui-focus-*`.\nconst buttonDropdownVariants = cva(\n 'inline-flex h-[var(--ui-button-menu-global-container-height)] min-w-[var(--ui-button-menu-global-container-width-min)] items-center justify-center gap-[var(--ui-button-menu-global-container-gap)] whitespace-nowrap rounded-[var(--ui-button-menu-global-container-border-radius)] border border-transparent px-[var(--ui-button-menu-global-container-padding-x)] text-sm font-semibold leading-6 ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-menu-global-icon-size)] [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary:\n 'bg-[var(--ui-button-menu-primary-container-color-idle)] text-[var(--ui-button-menu-primary-label-color)] [&_svg]:text-[var(--ui-button-menu-primary-icon-color)] hover:bg-[var(--ui-button-menu-primary-container-color-hover)] active:bg-[var(--ui-button-menu-primary-container-color-active)] data-[open]:bg-[var(--ui-button-menu-primary-container-color-active)] disabled:bg-[var(--ui-button-menu-primary-container-color-disabled)]',\n secondary:\n 'bg-[var(--ui-button-menu-secondary-container-color-idle)] text-[var(--ui-button-menu-secondary-label-color-idle)] border-[var(--ui-button-menu-secondary-container-border-color-idle)] [&_svg]:text-[var(--ui-button-menu-secondary-icon-color-idle)] hover:bg-[var(--ui-button-menu-secondary-container-color-hover)] hover:text-[var(--ui-button-menu-secondary-label-color-hover)] hover:border-[var(--ui-button-menu-secondary-container-border-color-hover)] hover:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-hover)] active:bg-[var(--ui-button-menu-secondary-container-color-active)] active:text-[var(--ui-button-menu-secondary-label-color-active)] active:border-[var(--ui-button-menu-secondary-container-border-color-active)] active:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-active)] data-[open]:bg-[var(--ui-button-menu-secondary-container-color-active)] data-[open]:text-[var(--ui-button-menu-secondary-label-color-active)] data-[open]:border-[var(--ui-button-menu-secondary-container-border-color-active)] data-[open]:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-active)] disabled:bg-[var(--ui-button-menu-secondary-container-color-disabled)] disabled:text-[var(--ui-button-menu-secondary-label-color-disabled)] disabled:border-[var(--ui-button-menu-secondary-container-border-color-disabled)] disabled:[&_svg]:text-[var(--ui-button-menu-secondary-icon-color-disabled)]',\n },\n },\n defaultVariants: {\n variant: 'primary',\n },\n }\n);\n\nexport interface ButtonDropdownProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'>,\n VariantProps<typeof buttonDropdownVariants> {\n /**\n * Whether the associated menu is open. Flips the trailing chevron\n * (down → up), applies the open (`*-active`) treatment, and reflects\n * `aria-expanded`. Control this in sync with the menu you trigger.\n */\n open?: boolean;\n /** Label content rendered before the chevron. */\n children?: React.ReactNode;\n /**\n * Replace the rendered `<button>` with another element or component\n * (Base UI composition). Accepts a React element or a render function —\n * the component's props and class names are merged onto it.\n */\n render?: useRender.RenderProp;\n}\n\n/**\n * A button that opens a dropdown menu: a label followed by a chevron that\n * points up while `open`. Pair it with the menu/popover it controls and keep\n * the `open` prop in sync.\n */\nconst ButtonDropdown = React.forwardRef<HTMLButtonElement, ButtonDropdownProps>(\n ({ className, variant, open, render, children, ...props }, ref) => {\n const Chevron = open ? ChevronUpIcon : ChevronDownIcon;\n return useRender({\n render,\n ref,\n defaultTagName: 'button',\n props: mergeProps<'button'>(\n {\n className: cn(buttonDropdownVariants({ variant, className })),\n 'aria-expanded': open,\n // `data-open` drives the open (`*-active`) token switch via attribute\n // selectors; present only while open, and typed loosely because\n // React's button attribute map doesn't include arbitrary data-* keys\n // as literals.\n ...(open ? ({ 'data-open': '' } as Record<string, string>) : {}),\n children: (\n <>\n {children}\n <Chevron />\n </>\n ),\n },\n props\n ),\n });\n }\n);\nButtonDropdown.displayName = 'ButtonDropdown';\n\nexport { ButtonDropdown, buttonDropdownVariants };\n"],"names":["buttonDropdownVariants","cva","ButtonDropdown","React","className","variant","open","render","children","props","ref","Chevron","ChevronUpIcon","ChevronDownIcon","useRender","mergeProps","cn","jsxs","Fragment"],"mappings":";;;;;;;AA0BA,MAAMA,IAAyBC;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,WACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GA2BMC,IAAiBC,EAAM;AAAA,EAC3B,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,MAAAC,GAAM,QAAAC,GAAQ,UAAAC,GAAU,GAAGC,EAAA,GAASC,MAAQ;AACjE,UAAMC,IAAUL,IAAOM,IAAgBC;AACvC,WAAOC,EAAU;AAAA,MACf,QAAAP;AAAA,MACA,KAAAG;AAAA,MACA,gBAAgB;AAAA,MAChB,OAAOK;AAAA,QACL;AAAA,UACE,WAAWC,EAAGhB,EAAuB,EAAE,SAAAK,GAAS,WAAAD,EAAA,CAAW,CAAC;AAAA,UAC5D,iBAAiBE;AAAA;AAAA;AAAA;AAAA;AAAA,UAKjB,GAAIA,IAAQ,EAAE,aAAa,GAAA,IAAkC,CAAA;AAAA,UAC7D,UACE,gBAAAW,EAAAC,GAAA,EACG,UAAA;AAAA,YAAAV;AAAA,8BACAG,GAAA,CAAA,CAAQ;AAAA,UAAA,EAAA,CACX;AAAA,QAAA;AAAA,QAGJF;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EACH;AACF;AACAP,EAAe,cAAc;"}
@@ -0,0 +1,35 @@
1
+ import * as e from "react";
2
+ import { mergeProps as a } from "@base-ui/react/merge-props";
3
+ import { useRender as c } from "@base-ui/react/use-render";
4
+ import { cva as b } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
5
+ import { cn as l } from "../../../lib/utils.js";
6
+ const s = b(
7
+ "inline-flex size-[var(--ui-button-icon-global-container-height)] shrink-0 items-center justify-center rounded-[var(--ui-button-icon-global-container-border-radius)] border border-transparent transition-colors bg-[var(--ui-button-icon-global-container-color-idle)] text-[var(--ui-button-icon-global-icon-color-idle)] hover:bg-[var(--ui-button-icon-global-container-color-hover)] hover:text-[var(--ui-button-icon-global-icon-color-hover)] active:bg-[var(--ui-button-icon-global-container-color-active)] active:text-[var(--ui-button-icon-global-icon-color-active)] disabled:pointer-events-none disabled:bg-[var(--ui-button-icon-global-container-color-disabled)] disabled:text-[var(--ui-button-icon-global-icon-color-disabled)] ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 [&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-icon-global-icon-size)] [&_svg]:shrink-0",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ ghost: "",
12
+ secondary: "border-[var(--ui-button-icon-secondary-container-border-color-idle)] hover:border-[var(--ui-button-icon-secondary-container-border-color-hover)] active:border-[var(--ui-button-icon-secondary-container-border-color-active)] disabled:border-[var(--ui-button-icon-secondary-container-border-color-disabled)]"
13
+ }
14
+ },
15
+ defaultVariants: {
16
+ variant: "ghost"
17
+ }
18
+ }
19
+ ), u = e.forwardRef(
20
+ ({ className: o, variant: r, render: n, ...i }, t) => c({
21
+ render: n,
22
+ ref: t,
23
+ defaultTagName: "button",
24
+ props: a(
25
+ { className: l(s({ variant: r, className: o })) },
26
+ i
27
+ )
28
+ })
29
+ );
30
+ u.displayName = "ButtonIcon";
31
+ export {
32
+ u as ButtonIcon,
33
+ s as buttonIconVariants
34
+ };
35
+ //# sourceMappingURL=button-icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-icon.js","sources":["../../../../src/components/ui/button-icon/button-icon.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Mirrors the Figma \"ButtonIcon\" component set: an icon-only button (square 32px\n// box, 16px glyph) with a `variant` property (`ghost` / `secondary`) and idle /\n// hover / active / disabled states. The container fill and the glyph color are\n// shared across both variants and come from the `--ui-button-icon-global-*`\n// tokens; `secondary` additionally paints a 1px container border from the\n// `--ui-button-icon-secondary-container-border-color-*` tokens, while `ghost`\n// leaves the (transparent) border so the box geometry stays identical across\n// variants. Each interaction state is wired to its own token (runtime `var()`\n// references, so brand overrides are honored). Box geometry — 32px height, 4px\n// radius, 16px icon — comes from the `global-container-*` / `global-icon-size`\n// tokens. Like Button, disabled uses the design's explicit disabled tokens (not\n// opacity) and the focus ring uses `--ui-focus-*`.\nconst buttonIconVariants = cva(\n 'inline-flex size-[var(--ui-button-icon-global-container-height)] shrink-0 items-center justify-center rounded-[var(--ui-button-icon-global-container-border-radius)] border border-transparent transition-colors ' +\n 'bg-[var(--ui-button-icon-global-container-color-idle)] text-[var(--ui-button-icon-global-icon-color-idle)] ' +\n 'hover:bg-[var(--ui-button-icon-global-container-color-hover)] hover:text-[var(--ui-button-icon-global-icon-color-hover)] ' +\n 'active:bg-[var(--ui-button-icon-global-container-color-active)] active:text-[var(--ui-button-icon-global-icon-color-active)] ' +\n 'disabled:pointer-events-none disabled:bg-[var(--ui-button-icon-global-container-color-disabled)] disabled:text-[var(--ui-button-icon-global-icon-color-disabled)] ' +\n 'ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-offset-2 ' +\n '[&_svg]:pointer-events-none [&_svg]:size-[var(--ui-button-icon-global-icon-size)] [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n ghost: '',\n secondary:\n 'border-[var(--ui-button-icon-secondary-container-border-color-idle)] hover:border-[var(--ui-button-icon-secondary-container-border-color-hover)] active:border-[var(--ui-button-icon-secondary-container-border-color-active)] disabled:border-[var(--ui-button-icon-secondary-container-border-color-disabled)]',\n },\n },\n defaultVariants: {\n variant: 'ghost',\n },\n }\n);\n\nexport interface ButtonIconProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonIconVariants> {\n /**\n * Replace the rendered `<button>` with another element or component\n * (Base UI composition). Accepts a React element or a render function —\n * the component's props and class names are merged onto it.\n */\n render?: useRender.RenderProp;\n}\n\n/**\n * Icon-only button. The icon is passed as `children`; provide an `aria-label`\n * (or `aria-labelledby`) so the control has an accessible name.\n */\nconst ButtonIcon = React.forwardRef<HTMLButtonElement, ButtonIconProps>(\n ({ className, variant, render, ...props }, ref) => {\n return useRender({\n render,\n ref,\n defaultTagName: 'button',\n props: mergeProps<'button'>(\n { className: cn(buttonIconVariants({ variant, className })) },\n props\n ),\n });\n }\n);\nButtonIcon.displayName = 'ButtonIcon';\n\nexport { ButtonIcon, buttonIconVariants };\n"],"names":["buttonIconVariants","cva","ButtonIcon","React","className","variant","render","props","ref","useRender","mergeProps","cn"],"mappings":";;;;;AAmBA,MAAMA,IAAqBC;AAAA,EACzB;AAAA,EAOA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,OAAO;AAAA,QACP,WACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAkBMC,IAAaC,EAAM;AAAA,EACvB,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,QAAAC,GAAQ,GAAGC,EAAA,GAASC,MAClCC,EAAU;AAAA,IACf,QAAAH;AAAA,IACA,KAAAE;AAAA,IACA,gBAAgB;AAAA,IAChB,OAAOE;AAAA,MACL,EAAE,WAAWC,EAAGX,EAAmB,EAAE,SAAAK,GAAS,WAAAD,EAAA,CAAW,CAAC,EAAA;AAAA,MAC1DG;AAAA,IAAA;AAAA,EACF,CACD;AAEL;AACAL,EAAW,cAAc;"}
@@ -0,0 +1,68 @@
1
+ import { jsx as e, jsxs as n } from "react/jsx-runtime";
2
+ import * as l from "react";
3
+ import { Checkbox as h } from "@base-ui/react/checkbox";
4
+ import { MinusIcon as v, CheckIcon as u } from "@acronis-platform/icons-react/stroke-mono";
5
+ import { cn as m } from "../../../lib/utils.js";
6
+ const g = [
7
+ // geometry + focus ring
8
+ "inline-flex size-[var(--ui-checkbox-global-box-size)] shrink-0 cursor-pointer items-center justify-center rounded-[var(--ui-checkbox-global-box-border-radius)] border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&_svg]:shrink-0",
9
+ // unchecked (base): idle / hover / active
10
+ "bg-[var(--ui-checkbox-unchecked-box-color-idle)] border-[var(--ui-checkbox-unchecked-box-border-color-idle)]",
11
+ "not-data-[disabled]:hover:bg-[var(--ui-checkbox-unchecked-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-checkbox-unchecked-box-border-color-hover)]",
12
+ "not-data-[disabled]:active:bg-[var(--ui-checkbox-unchecked-box-color-active)] not-data-[disabled]:active:border-[var(--ui-checkbox-unchecked-box-border-color-active)]",
13
+ // checked: idle / hover / active
14
+ "data-[checked]:bg-[var(--ui-checkbox-checked-box-color-idle)] data-[checked]:border-[var(--ui-checkbox-checked-box-border-color-idle)] data-[checked]:text-[var(--ui-checkbox-checked-icon-color-idle)]",
15
+ "data-[checked]:not-data-[disabled]:hover:bg-[var(--ui-checkbox-checked-box-color-hover)] data-[checked]:not-data-[disabled]:hover:border-[var(--ui-checkbox-checked-box-border-color-hover)] data-[checked]:not-data-[disabled]:hover:text-[var(--ui-checkbox-checked-icon-color-hover)]",
16
+ "data-[checked]:not-data-[disabled]:active:bg-[var(--ui-checkbox-checked-box-color-active)] data-[checked]:not-data-[disabled]:active:border-[var(--ui-checkbox-checked-box-border-color-active)] data-[checked]:not-data-[disabled]:active:text-[var(--ui-checkbox-checked-icon-color-active)]",
17
+ // indeterminate: idle / hover / active
18
+ "data-[indeterminate]:bg-[var(--ui-checkbox-indeterminate-box-color-idle)] data-[indeterminate]:border-[var(--ui-checkbox-indeterminate-box-border-color-idle)] data-[indeterminate]:text-[var(--ui-checkbox-indeterminate-icon-color-idle)]",
19
+ "data-[indeterminate]:not-data-[disabled]:hover:bg-[var(--ui-checkbox-indeterminate-box-color-hover)] data-[indeterminate]:not-data-[disabled]:hover:border-[var(--ui-checkbox-indeterminate-box-border-color-hover)] data-[indeterminate]:not-data-[disabled]:hover:text-[var(--ui-checkbox-indeterminate-icon-color-hover)]",
20
+ "data-[indeterminate]:not-data-[disabled]:active:bg-[var(--ui-checkbox-indeterminate-box-color-active)] data-[indeterminate]:not-data-[disabled]:active:border-[var(--ui-checkbox-indeterminate-box-border-color-active)] data-[indeterminate]:not-data-[disabled]:active:text-[var(--ui-checkbox-indeterminate-icon-color-active)]",
21
+ // disabled (unchecked base + per-state overrides)
22
+ "data-[disabled]:cursor-not-allowed data-[disabled]:bg-[var(--ui-checkbox-unchecked-box-color-disabled)] data-[disabled]:border-[var(--ui-checkbox-unchecked-box-border-color-disabled)]",
23
+ "data-[disabled]:data-[checked]:bg-[var(--ui-checkbox-checked-box-color-disabled)] data-[disabled]:data-[checked]:border-[var(--ui-checkbox-checked-box-border-color-disabled)] data-[disabled]:data-[checked]:text-[var(--ui-checkbox-checked-icon-color-disabled)]",
24
+ "data-[disabled]:data-[indeterminate]:bg-[var(--ui-checkbox-indeterminate-box-color-disabled)] data-[disabled]:data-[indeterminate]:border-[var(--ui-checkbox-indeterminate-box-border-color-disabled)] data-[disabled]:data-[indeterminate]:text-[var(--ui-checkbox-indeterminate-icon-color-disabled)]"
25
+ ].join(" "), f = l.forwardRef(({ className: x, label: a, description: o, indeterminate: c, ...s }, k) => {
26
+ const d = l.useId(), r = a != null ? `${d}-label` : void 0, i = o != null ? `${d}-description` : void 0, t = a != null || o != null, b = /* @__PURE__ */ e(
27
+ h.Root,
28
+ {
29
+ ref: k,
30
+ indeterminate: c,
31
+ "aria-labelledby": r,
32
+ "aria-describedby": i,
33
+ className: m(
34
+ g,
35
+ t && "mt-[var(--ui-checkbox-global-box-margin-x)]",
36
+ x
37
+ ),
38
+ ...s,
39
+ children: /* @__PURE__ */ e(h.Indicator, { className: "flex items-center justify-center text-current", children: c ? /* @__PURE__ */ e(v, { size: 16 }) : /* @__PURE__ */ e(u, { size: 16 }) })
40
+ }
41
+ );
42
+ return t ? /* @__PURE__ */ n("label", { className: "inline-flex max-w-[var(--ui-checkbox-global-container-width-max)] min-w-[var(--ui-checkbox-global-container-width-min)] cursor-pointer items-start gap-[var(--ui-checkbox-global-container-gap)]", children: [
43
+ b,
44
+ /* @__PURE__ */ n("span", { className: "flex max-w-[var(--ui-checkbox-global-container-content-width-max)] flex-col gap-[var(--ui-checkbox-global-container-content-gap)]", children: [
45
+ a != null && /* @__PURE__ */ e(
46
+ "span",
47
+ {
48
+ id: r,
49
+ className: "text-sm leading-6 font-normal text-[var(--ui-checkbox-global-label-color)]",
50
+ children: a
51
+ }
52
+ ),
53
+ o != null && /* @__PURE__ */ e(
54
+ "span",
55
+ {
56
+ id: i,
57
+ className: "text-sm leading-6 font-normal text-[var(--ui-checkbox-global-description-color)]",
58
+ children: o
59
+ }
60
+ )
61
+ ] })
62
+ ] }) : b;
63
+ });
64
+ f.displayName = "Checkbox";
65
+ export {
66
+ f as Checkbox
67
+ };
68
+ //# sourceMappingURL=checkbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.js","sources":["../../../../src/components/ui/checkbox/checkbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox';\nimport {\n CheckIcon,\n MinusIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Wraps Base UI's Checkbox primitive, themed by the dedicated next-gen\n// `--ui-checkbox-*` token tier from @acronis-platform/tokens-pd. The box has three\n// logical states — `unchecked` (the base), `checked`, and `indeterminate` — each\n// with its own per-interaction (idle / hover / active / disabled) fill\n// (`*-box-color-*`), border (`*-box-border-color-*`), and glyph (`*-icon-color-*`)\n// tokens. `unchecked` is the base layer (lowest specificity); `data-[checked]` /\n// `data-[indeterminate]` override it (Base UI marks an indeterminate box with both\n// data-unchecked AND data-indeterminate, so the single-attribute overrides win on\n// specificity), and `data-[disabled]:data-[<state>]` overrides those in turn. The\n// glyph (check when checked, minus when indeterminate) inherits the Root's text\n// color via the Indicator's `text-current`. Box geometry (16px size, 2px radius)\n// comes from `--ui-checkbox-global-box-*`; the focus ring uses `--ui-focus-primary`.\n//\n// An optional `label` / `description` compose the full Figma field: the box, an\n// optional label, and an optional description stacked beside it. When either is\n// present the whole row is a `<label>` (so clicking the text toggles the box — a\n// Base UI checkbox renders a labelable <button>), the box gets a top margin of\n// `--ui-checkbox-global-box-margin-x` (4px = (line-height 24 − box 16) / 2, the\n// design's box alignment margin) to center it on the first text line, and the\n// box is wired to the text via aria-labelledby / aria-describedby. With neither,\n// the box renders on its own (name it with `aria-label`).\nconst boxClasses = [\n // geometry + focus ring\n 'inline-flex size-[var(--ui-checkbox-global-box-size)] shrink-0 cursor-pointer items-center justify-center rounded-[var(--ui-checkbox-global-box-border-radius)] border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&_svg]:shrink-0',\n // unchecked (base): idle / hover / active\n 'bg-[var(--ui-checkbox-unchecked-box-color-idle)] border-[var(--ui-checkbox-unchecked-box-border-color-idle)]',\n 'not-data-[disabled]:hover:bg-[var(--ui-checkbox-unchecked-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-checkbox-unchecked-box-border-color-hover)]',\n 'not-data-[disabled]:active:bg-[var(--ui-checkbox-unchecked-box-color-active)] not-data-[disabled]:active:border-[var(--ui-checkbox-unchecked-box-border-color-active)]',\n // checked: idle / hover / active\n 'data-[checked]:bg-[var(--ui-checkbox-checked-box-color-idle)] data-[checked]:border-[var(--ui-checkbox-checked-box-border-color-idle)] data-[checked]:text-[var(--ui-checkbox-checked-icon-color-idle)]',\n 'data-[checked]:not-data-[disabled]:hover:bg-[var(--ui-checkbox-checked-box-color-hover)] data-[checked]:not-data-[disabled]:hover:border-[var(--ui-checkbox-checked-box-border-color-hover)] data-[checked]:not-data-[disabled]:hover:text-[var(--ui-checkbox-checked-icon-color-hover)]',\n 'data-[checked]:not-data-[disabled]:active:bg-[var(--ui-checkbox-checked-box-color-active)] data-[checked]:not-data-[disabled]:active:border-[var(--ui-checkbox-checked-box-border-color-active)] data-[checked]:not-data-[disabled]:active:text-[var(--ui-checkbox-checked-icon-color-active)]',\n // indeterminate: idle / hover / active\n 'data-[indeterminate]:bg-[var(--ui-checkbox-indeterminate-box-color-idle)] data-[indeterminate]:border-[var(--ui-checkbox-indeterminate-box-border-color-idle)] data-[indeterminate]:text-[var(--ui-checkbox-indeterminate-icon-color-idle)]',\n 'data-[indeterminate]:not-data-[disabled]:hover:bg-[var(--ui-checkbox-indeterminate-box-color-hover)] data-[indeterminate]:not-data-[disabled]:hover:border-[var(--ui-checkbox-indeterminate-box-border-color-hover)] data-[indeterminate]:not-data-[disabled]:hover:text-[var(--ui-checkbox-indeterminate-icon-color-hover)]',\n 'data-[indeterminate]:not-data-[disabled]:active:bg-[var(--ui-checkbox-indeterminate-box-color-active)] data-[indeterminate]:not-data-[disabled]:active:border-[var(--ui-checkbox-indeterminate-box-border-color-active)] data-[indeterminate]:not-data-[disabled]:active:text-[var(--ui-checkbox-indeterminate-icon-color-active)]',\n // disabled (unchecked base + per-state overrides)\n 'data-[disabled]:cursor-not-allowed data-[disabled]:bg-[var(--ui-checkbox-unchecked-box-color-disabled)] data-[disabled]:border-[var(--ui-checkbox-unchecked-box-border-color-disabled)]',\n 'data-[disabled]:data-[checked]:bg-[var(--ui-checkbox-checked-box-color-disabled)] data-[disabled]:data-[checked]:border-[var(--ui-checkbox-checked-box-border-color-disabled)] data-[disabled]:data-[checked]:text-[var(--ui-checkbox-checked-icon-color-disabled)]',\n 'data-[disabled]:data-[indeterminate]:bg-[var(--ui-checkbox-indeterminate-box-color-disabled)] data-[disabled]:data-[indeterminate]:border-[var(--ui-checkbox-indeterminate-box-border-color-disabled)] data-[disabled]:data-[indeterminate]:text-[var(--ui-checkbox-indeterminate-icon-color-disabled)]',\n].join(' ');\n\nexport interface CheckboxProps\n extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {\n /** Optional label rendered beside the box; names the control. */\n label?: React.ReactNode;\n /** Optional secondary description rendered under the label. */\n description?: React.ReactNode;\n}\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n CheckboxProps\n>(({ className, label, description, indeterminate, ...props }, ref) => {\n const reactId = React.useId();\n const labelId = label != null ? `${reactId}-label` : undefined;\n const descriptionId = description != null ? `${reactId}-description` : undefined;\n const hasContent = label != null || description != null;\n\n const box = (\n <CheckboxPrimitive.Root\n ref={ref}\n indeterminate={indeterminate}\n aria-labelledby={labelId}\n aria-describedby={descriptionId}\n className={cn(\n boxClasses,\n hasContent && 'mt-[var(--ui-checkbox-global-box-margin-x)]',\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"flex items-center justify-center text-current\">\n {indeterminate ? <MinusIcon size={16} /> : <CheckIcon size={16} />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n\n if (!hasContent) return box;\n\n return (\n <label className=\"inline-flex max-w-[var(--ui-checkbox-global-container-width-max)] min-w-[var(--ui-checkbox-global-container-width-min)] cursor-pointer items-start gap-[var(--ui-checkbox-global-container-gap)]\">\n {box}\n <span className=\"flex max-w-[var(--ui-checkbox-global-container-content-width-max)] flex-col gap-[var(--ui-checkbox-global-container-content-gap)]\">\n {label != null && (\n <span\n id={labelId}\n className=\"text-sm leading-6 font-normal text-[var(--ui-checkbox-global-label-color)]\"\n >\n {label}\n </span>\n )}\n {description != null && (\n <span\n id={descriptionId}\n className=\"text-sm leading-6 font-normal text-[var(--ui-checkbox-global-description-color)]\"\n >\n {description}\n </span>\n )}\n </span>\n </label>\n );\n});\nCheckbox.displayName = 'Checkbox';\n\nexport { Checkbox };\n"],"names":["boxClasses","Checkbox","React","className","label","description","indeterminate","props","ref","reactId","labelId","descriptionId","hasContent","box","jsx","CheckboxPrimitive","cn","MinusIcon","CheckIcon","jsxs"],"mappings":";;;;;AA8BA,MAAMA,IAAa;AAAA;AAAA,EAEjB;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG,GAUJC,IAAWC,EAAM,WAGrB,CAAC,EAAE,WAAAC,GAAW,OAAAC,GAAO,aAAAC,GAAa,eAAAC,GAAe,GAAGC,EAAA,GAASC,MAAQ;AACrE,QAAMC,IAAUP,EAAM,MAAA,GAChBQ,IAAUN,KAAS,OAAO,GAAGK,CAAO,WAAW,QAC/CE,IAAgBN,KAAe,OAAO,GAAGI,CAAO,iBAAiB,QACjEG,IAAaR,KAAS,QAAQC,KAAe,MAE7CQ,IACJ,gBAAAC;AAAA,IAACC,EAAkB;AAAA,IAAlB;AAAA,MACC,KAAAP;AAAA,MACA,eAAAF;AAAA,MACA,mBAAiBI;AAAA,MACjB,oBAAkBC;AAAA,MAClB,WAAWK;AAAA,QACThB;AAAA,QACAY,KAAc;AAAA,QACdT;AAAA,MAAA;AAAA,MAED,GAAGI;AAAA,MAEJ,4BAACQ,EAAkB,WAAlB,EAA4B,WAAU,iDACpC,UAAAT,IAAgB,gBAAAQ,EAACG,GAAA,EAAU,MAAM,IAAI,IAAK,gBAAAH,EAACI,GAAA,EAAU,MAAM,IAAI,EAAA,CAClE;AAAA,IAAA;AAAA,EAAA;AAIJ,SAAKN,IAGH,gBAAAO,EAAC,SAAA,EAAM,WAAU,oMACd,UAAA;AAAA,IAAAN;AAAA,IACD,gBAAAM,EAAC,QAAA,EAAK,WAAU,qIACb,UAAA;AAAA,MAAAf,KAAS,QACR,gBAAAU;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAIJ;AAAA,UACJ,WAAU;AAAA,UAET,UAAAN;AAAA,QAAA;AAAA,MAAA;AAAA,MAGJC,KAAe,QACd,gBAAAS;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAIH;AAAA,UACJ,WAAU;AAAA,UAET,UAAAN;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,EAAA,CAEJ;AAAA,EAAA,GACF,IAvBsBQ;AAyB1B,CAAC;AACDZ,EAAS,cAAc;"}
@@ -0,0 +1,22 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import * as t from "react";
3
+ import { cn as a } from "../../../lib/utils.js";
4
+ const d = t.forwardRef(
5
+ ({ className: r, type: o = "text", ...i }, e) => /* @__PURE__ */ l(
6
+ "input",
7
+ {
8
+ ref: e,
9
+ type: o,
10
+ className: a(
11
+ "h-[var(--ui-input-text-global-box-height)] w-full min-w-0 rounded-[var(--ui-input-text-global-box-border-radius)] border bg-[var(--ui-input-text-global-box-color-idle)] border-[var(--ui-input-text-normal-box-border-color-idle)] px-[var(--ui-input-text-global-box-padding-x)] text-sm leading-6 text-[var(--ui-input-text-global-value-color-idle)] transition-colors placeholder:text-[var(--ui-input-text-global-placeholder-color-idle)] focus-visible:outline-none focus-visible:ring-[3px] enabled:not-aria-[invalid=true]:hover:border-[var(--ui-input-text-normal-box-border-color-hover)] enabled:not-aria-[invalid=true]:hover:bg-[var(--ui-input-text-global-box-color-hover)] not-aria-[invalid=true]:focus-visible:border-[var(--ui-input-text-normal-box-border-color-hover)] not-aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-primary)] aria-[invalid=true]:border-[var(--ui-input-text-error-msg-box-border-color-idle)] aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-error)] disabled:cursor-not-allowed disabled:border-[var(--ui-input-text-normal-box-border-color-disabled)] disabled:bg-[var(--ui-input-text-global-box-color-disabled)] disabled:text-[var(--ui-input-text-global-value-color-disabled)] disabled:placeholder:text-[var(--ui-input-text-global-placeholder-color-disabled)]",
12
+ r
13
+ ),
14
+ ...i
15
+ }
16
+ )
17
+ );
18
+ d.displayName = "Input";
19
+ export {
20
+ d as Input
21
+ };
22
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sources":["../../../../src/components/ui/input/input.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// A single-line text input, themed by the dedicated next-gen `--ui-input-text-*`\n// token tier from @acronis-platform/tokens-pd. The box fill (`global-box-color-*`)\n// and the normal border (`normal-box-border-color-*`) are wired per state: idle /\n// hover / focus / disabled. The `normal-box-border-color-*` tier has no `-active`,\n// so focus reuses `-hover` for the border, paired with a 3px `--ui-focus-primary`\n// ring. Value and placeholder text use `global-value-color-*` /\n// `global-placeholder-color-*`. The error state is driven by `aria-invalid` —\n// `error-msg-box-border-color-*` border and, on focus, a `--ui-focus-error` ring —\n// scoped with `not-aria-[invalid]` so it wins over the hover/focus border. Box\n// geometry (32px height, 4px radius, 12px padding-x) comes from\n// `--ui-input-text-global-box-*`. Label, description, and error message are\n// composed by the consumer (a Field component is future work).\nexport type InputProps = React.ComponentPropsWithoutRef<'input'>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type = 'text', ...props }, ref) => (\n <input\n ref={ref}\n type={type}\n className={cn(\n 'h-[var(--ui-input-text-global-box-height)] w-full min-w-0 rounded-[var(--ui-input-text-global-box-border-radius)] border bg-[var(--ui-input-text-global-box-color-idle)] border-[var(--ui-input-text-normal-box-border-color-idle)] px-[var(--ui-input-text-global-box-padding-x)] text-sm leading-6 text-[var(--ui-input-text-global-value-color-idle)] transition-colors placeholder:text-[var(--ui-input-text-global-placeholder-color-idle)] focus-visible:outline-none focus-visible:ring-[3px] enabled:not-aria-[invalid=true]:hover:border-[var(--ui-input-text-normal-box-border-color-hover)] enabled:not-aria-[invalid=true]:hover:bg-[var(--ui-input-text-global-box-color-hover)] not-aria-[invalid=true]:focus-visible:border-[var(--ui-input-text-normal-box-border-color-hover)] not-aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-primary)] aria-[invalid=true]:border-[var(--ui-input-text-error-msg-box-border-color-idle)] aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-error)] disabled:cursor-not-allowed disabled:border-[var(--ui-input-text-normal-box-border-color-disabled)] disabled:bg-[var(--ui-input-text-global-box-color-disabled)] disabled:text-[var(--ui-input-text-global-value-color-disabled)] disabled:placeholder:text-[var(--ui-input-text-global-placeholder-color-disabled)]',\n className\n )}\n {...props}\n />\n )\n);\nInput.displayName = 'Input';\n\nexport { Input };\n"],"names":["Input","React","className","type","props","ref","jsx","cn"],"mappings":";;;AAkBA,MAAMA,IAAQC,EAAM;AAAA,EAClB,CAAC,EAAE,WAAAC,GAAW,MAAAC,IAAO,QAAQ,GAAGC,EAAA,GAASC,MACvC,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,MAAAF;AAAA,MACA,WAAWI;AAAA,QACT;AAAA,QACAL;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AACAJ,EAAM,cAAc;"}
@@ -0,0 +1,21 @@
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import * as o from "react";
3
+ import { cn as t } from "../../../lib/utils.js";
4
+ const l = o.forwardRef(
5
+ ({ className: e, ...r }, a) => /* @__PURE__ */ i(
6
+ "textarea",
7
+ {
8
+ ref: a,
9
+ className: t(
10
+ "min-h-[var(--ui-input-text-area-box-height-min)] w-full min-w-0 resize-y rounded-[var(--ui-input-text-area-box-border-radius)] border bg-[var(--ui-input-text-area-box-color-idle)] border-[var(--ui-input-text-area-border-color-idle)] px-[var(--ui-input-text-area-box-padding-x)] py-[var(--ui-input-text-area-box-padding-y)] text-sm leading-6 text-[var(--ui-input-text-area-value-color-idle)] transition-colors placeholder:text-[var(--ui-input-text-area-placeholder-color-idle)] focus-visible:outline-none focus-visible:ring-[3px] enabled:hover:bg-[var(--ui-input-text-area-box-color-hover)] enabled:hover:border-[var(--ui-input-text-area-border-color-hover)] enabled:hover:text-[var(--ui-input-text-area-value-color-hover)] enabled:hover:placeholder:text-[var(--ui-input-text-area-placeholder-color-hover)] focus-visible:border-[var(--ui-input-text-area-border-color-focus)] not-aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-primary)] aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-error)] disabled:cursor-not-allowed disabled:border-[var(--ui-input-text-area-border-color-disabled)] disabled:bg-[var(--ui-input-text-area-box-color-disabled)] disabled:text-[var(--ui-input-text-area-value-color-disabled)] disabled:placeholder:text-[var(--ui-input-text-area-placeholder-color-disabled)]",
11
+ e
12
+ ),
13
+ ...r
14
+ }
15
+ )
16
+ );
17
+ l.displayName = "InputTextArea";
18
+ export {
19
+ l as InputTextArea
20
+ };
21
+ //# sourceMappingURL=input-text-area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-text-area.js","sources":["../../../../src/components/ui/input-text-area/input-text-area.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// A multiline text area, themed by the dedicated next-gen `--ui-input-text-area-*`\n// token tier from @acronis-platform/tokens-pd. The box fill (`box-color-*`) and the\n// border (`border-color-*`) are wired per state: idle / hover / focus (border\n// `border-color-focus` + a 3px `--ui-focus-primary` ring) / disabled. Value and\n// placeholder text use `value-color-*` / `placeholder-color-*`. Box geometry\n// (96px min-height, 4px radius, 12px padding-x, 8px padding-y) comes from\n// `--ui-input-text-area-box-*`; it grows with vertical resize. Unlike the\n// single-line Input tier, this tier has NO error-specific border/fill token — so\n// the error state (driven by `aria-invalid`) keeps the idle/hover/focus border and\n// only swaps the focus ring to `--ui-focus-error`. Label, description, and required\n// marker are composed by the consumer (a Field component is future work).\nexport type InputTextAreaProps = React.ComponentPropsWithoutRef<'textarea'>;\n\nconst InputTextArea = React.forwardRef<HTMLTextAreaElement, InputTextAreaProps>(\n ({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n className={cn(\n 'min-h-[var(--ui-input-text-area-box-height-min)] w-full min-w-0 resize-y rounded-[var(--ui-input-text-area-box-border-radius)] border bg-[var(--ui-input-text-area-box-color-idle)] border-[var(--ui-input-text-area-border-color-idle)] px-[var(--ui-input-text-area-box-padding-x)] py-[var(--ui-input-text-area-box-padding-y)] text-sm leading-6 text-[var(--ui-input-text-area-value-color-idle)] transition-colors placeholder:text-[var(--ui-input-text-area-placeholder-color-idle)] focus-visible:outline-none focus-visible:ring-[3px] enabled:hover:bg-[var(--ui-input-text-area-box-color-hover)] enabled:hover:border-[var(--ui-input-text-area-border-color-hover)] enabled:hover:text-[var(--ui-input-text-area-value-color-hover)] enabled:hover:placeholder:text-[var(--ui-input-text-area-placeholder-color-hover)] focus-visible:border-[var(--ui-input-text-area-border-color-focus)] not-aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-primary)] aria-[invalid=true]:focus-visible:ring-[var(--ui-focus-error)] disabled:cursor-not-allowed disabled:border-[var(--ui-input-text-area-border-color-disabled)] disabled:bg-[var(--ui-input-text-area-box-color-disabled)] disabled:text-[var(--ui-input-text-area-value-color-disabled)] disabled:placeholder:text-[var(--ui-input-text-area-placeholder-color-disabled)]',\n className\n )}\n {...props}\n />\n )\n);\nInputTextArea.displayName = 'InputTextArea';\n\nexport { InputTextArea };\n"],"names":["InputTextArea","React","className","props","ref","jsx","cn"],"mappings":";;;AAiBA,MAAMA,IAAgBC,EAAM;AAAA,EAC1B,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MACxB,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV;AACAH,EAAc,cAAc;"}