@proteos/ui 0.56.0 → 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.
- package/dist/{chunk-IKAX76MB.js → chunk-NSE4VW3Z.js} +45 -21
- package/dist/chunk-NSE4VW3Z.js.map +1 -0
- package/dist/{chunk-MWAXK66H.cjs → chunk-NWGG5WFL.cjs} +45 -21
- package/dist/chunk-NWGG5WFL.cjs.map +1 -0
- package/dist/index.cjs +336 -351
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -12
- package/dist/index.d.ts +41 -12
- package/dist/index.js +83 -98
- package/dist/index.js.map +1 -1
- package/dist/{pdf-view-MH75RVQP.js → pdf-view-RQ2OZYHJ.js} +3 -3
- package/dist/{pdf-view-MH75RVQP.js.map → pdf-view-RQ2OZYHJ.js.map} +1 -1
- package/dist/{pdf-view-K4MMVHVY.cjs → pdf-view-RRMAUK3L.cjs} +7 -7
- package/dist/{pdf-view-K4MMVHVY.cjs.map → pdf-view-RRMAUK3L.cjs.map} +1 -1
- package/package.json +2 -2
- package/src/components/avatar/avatar.stories.tsx +13 -0
- package/src/components/avatar/avatar.tsx +16 -9
- package/src/components/badge-multi-select/badge-multi-select.tsx +2 -2
- package/src/components/button/button.stories.tsx +202 -97
- package/src/components/button/button.test.tsx +40 -7
- package/src/components/button/button.tsx +71 -18
- package/src/components/combobox/combobox.tsx +2 -2
- package/src/components/currency-input/currency-input.tsx +2 -2
- package/src/components/date-picker/calendar-internals.tsx +1 -1
- package/src/components/date-picker/date-picker.tsx +3 -3
- package/src/components/date-time-picker/date-time-picker.tsx +3 -3
- package/src/components/icon-picker/icon-picker.tsx +2 -2
- package/src/components/image-lightbox/image-lightbox.tsx +2 -2
- package/src/components/menu/menu.tsx +2 -2
- package/src/components/modal/modal.tsx +4 -4
- package/src/components/multi-select/multi-select.tsx +2 -2
- package/src/components/popover/popover.tsx +2 -2
- package/src/components/record-filter/nested-group.tsx +2 -2
- package/src/components/record-filter/record-filter-builder-panel.tsx +11 -23
- package/src/components/record-filter/record-filter-chips.tsx +3 -10
- package/src/components/segmented-control/segmented-control.stories.tsx +134 -8
- package/src/components/segmented-control/segmented-control.test.tsx +81 -8
- package/src/components/segmented-control/segmented-control.tsx +38 -19
- package/src/components/select/select.tsx +2 -2
- package/src/components/time-field/time-field.tsx +1 -1
- package/src/components/toast/toast.tsx +2 -2
- package/src/components/tooltip/tooltip.tsx +2 -2
- package/src/styles.css +58 -0
- package/dist/chunk-IKAX76MB.js.map +0 -1
- package/dist/chunk-MWAXK66H.cjs.map +0 -1
|
@@ -116,8 +116,8 @@ export function Select<T extends Key>({
|
|
|
116
116
|
'z-[1300]',
|
|
117
117
|
'rounded-md border border-rule bg-surface p-1',
|
|
118
118
|
'shadow-[var(--shadow-raised)]',
|
|
119
|
-
'entering:animate-
|
|
120
|
-
'exiting:animate-
|
|
119
|
+
'entering:animate-enter-slide-down',
|
|
120
|
+
'exiting:animate-exit-slide-up',
|
|
121
121
|
popoverClassName,
|
|
122
122
|
)}
|
|
123
123
|
>
|
|
@@ -78,7 +78,7 @@ export function TimeField<T extends TimeValue = TimeValue>({
|
|
|
78
78
|
'data-[placeholder]:text-ink-4',
|
|
79
79
|
'data-[type=literal]:text-ink-4',
|
|
80
80
|
// segment focus treatment: indigo fill, paper text
|
|
81
|
-
'data-[focused]:bg-accent data-[focused]:text-
|
|
81
|
+
'data-[focused]:bg-accent data-[focused]:text-tile-fg data-[focused]:rounded-[3px]',
|
|
82
82
|
'data-[disabled]:cursor-not-allowed',
|
|
83
83
|
)}
|
|
84
84
|
/>
|
|
@@ -45,8 +45,8 @@ export const toastStyles = tv({
|
|
|
45
45
|
'rounded-lg border border-rule bg-surface shadow-float',
|
|
46
46
|
'px-3.5 py-3 outline-none',
|
|
47
47
|
'focus-visible:shadow-focus',
|
|
48
|
-
'entering:animate-
|
|
49
|
-
'exiting:animate-
|
|
48
|
+
'entering:animate-enter-slide-up',
|
|
49
|
+
'exiting:animate-exit-fade',
|
|
50
50
|
],
|
|
51
51
|
icon: 'size-4 shrink-0 mt-0.5',
|
|
52
52
|
title: 'font-sans text-[13px] font-medium leading-[1.4] text-ink',
|
|
@@ -46,8 +46,8 @@ export function Tooltip({ className, offset = 6, ...props }: TooltipProps) {
|
|
|
46
46
|
'rounded-md border border-rule bg-surface shadow-[var(--shadow-raised)]',
|
|
47
47
|
'px-2.5 py-1.5',
|
|
48
48
|
'font-mono text-[11.5px] text-ink-2',
|
|
49
|
-
'entering:animate-
|
|
50
|
-
'exiting:animate-
|
|
49
|
+
'entering:animate-enter-slide-down',
|
|
50
|
+
'exiting:animate-exit-fade',
|
|
51
51
|
typeof className === 'function' ? className(renderProps) : className,
|
|
52
52
|
)
|
|
53
53
|
}
|
package/src/styles.css
CHANGED
|
@@ -14,6 +14,18 @@
|
|
|
14
14
|
to *this* file. */
|
|
15
15
|
@source "./components/**/*.{ts,tsx}";
|
|
16
16
|
|
|
17
|
+
/* React Aria state variants. RAC exposes interaction state as data-* attributes
|
|
18
|
+
(pointer-correct: no sticky :hover on touch; press follows usePress). Same names
|
|
19
|
+
as tailwindcss-react-aria-components, without the dependency. `focus-visible:`
|
|
20
|
+
and `disabled:` stay core. Order matters: `selected` is declared after `hovered`
|
|
21
|
+
so a selected segment's fill wins over its hover fill at equal specificity. */
|
|
22
|
+
@custom-variant hovered (&[data-hovered]);
|
|
23
|
+
@custom-variant pressed (&[data-pressed]);
|
|
24
|
+
@custom-variant selected (&[data-selected]);
|
|
25
|
+
@custom-variant focused (&[data-focused]);
|
|
26
|
+
@custom-variant entering (&[data-entering]);
|
|
27
|
+
@custom-variant exiting (&[data-exiting]);
|
|
28
|
+
|
|
17
29
|
/* ==========================================================
|
|
18
30
|
PROTEOS · INDIGO — design tokens
|
|
19
31
|
Mirrors Proteos Design System v0.1 (spec: revision 2026.04.24).
|
|
@@ -37,6 +49,8 @@
|
|
|
37
49
|
--color-surface: #ffffff;
|
|
38
50
|
--color-surface-2: #f0f0f2;
|
|
39
51
|
--color-surface-3: #e5e5e9;
|
|
52
|
+
/* Deepest recessed step — hover on gray fills (muted buttons). */
|
|
53
|
+
--color-surface-4: #d9d9df;
|
|
40
54
|
|
|
41
55
|
/* Ink — indigo-tinted slate */
|
|
42
56
|
--color-ink: #1a1d2b;
|
|
@@ -124,6 +138,17 @@
|
|
|
124
138
|
status icons. Soft ease, no overshoot (nothing bounces). */
|
|
125
139
|
--animate-status-pop: status-pop var(--duration-slow) var(--ease-out-soft) both;
|
|
126
140
|
|
|
141
|
+
/* Overlay motion — own keyframes. tw-animate-css was never installed, so the
|
|
142
|
+
`animate-in fade-in-0 …` strings compiled to nothing. `both` holds the end
|
|
143
|
+
frame while RAC keeps the element in data-exiting until unmount. */
|
|
144
|
+
--animate-enter-fade: enter-fade var(--duration-fast) ease both;
|
|
145
|
+
--animate-enter-slide-down: enter-slide-down var(--duration-fast) ease both;
|
|
146
|
+
--animate-enter-slide-up: enter-slide-up var(--duration-base) ease both;
|
|
147
|
+
--animate-enter-zoom: enter-zoom var(--duration-fast) ease both;
|
|
148
|
+
--animate-exit-fade: exit-fade 100ms ease both;
|
|
149
|
+
--animate-exit-slide-up: exit-slide-up 100ms ease both;
|
|
150
|
+
--animate-exit-zoom: exit-zoom 100ms ease both;
|
|
151
|
+
|
|
127
152
|
}
|
|
128
153
|
|
|
129
154
|
@keyframes indeterminate-progress {
|
|
@@ -149,6 +174,37 @@
|
|
|
149
174
|
}
|
|
150
175
|
}
|
|
151
176
|
|
|
177
|
+
@keyframes enter-fade {
|
|
178
|
+
from { opacity: 0; }
|
|
179
|
+
}
|
|
180
|
+
@keyframes enter-slide-down {
|
|
181
|
+
from { opacity: 0; transform: translateY(-4px); }
|
|
182
|
+
}
|
|
183
|
+
@keyframes enter-slide-up {
|
|
184
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
185
|
+
}
|
|
186
|
+
@keyframes enter-zoom {
|
|
187
|
+
from { opacity: 0; transform: scale(0.95); }
|
|
188
|
+
}
|
|
189
|
+
@keyframes exit-fade {
|
|
190
|
+
to { opacity: 0; }
|
|
191
|
+
}
|
|
192
|
+
@keyframes exit-slide-up {
|
|
193
|
+
to { opacity: 0; transform: translateY(-4px); }
|
|
194
|
+
}
|
|
195
|
+
@keyframes exit-zoom {
|
|
196
|
+
to { opacity: 0; transform: scale(0.95); }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@media (prefers-reduced-motion: reduce) {
|
|
200
|
+
[data-entering],
|
|
201
|
+
[data-exiting],
|
|
202
|
+
[class*="animate-enter-"],
|
|
203
|
+
[class*="animate-exit-"] {
|
|
204
|
+
animation: none;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
152
208
|
/* Raw variables (non-color) for direct component consumption.
|
|
153
209
|
Tailwind v4 mirrors @theme into :root for colors/radii/shadows, but we
|
|
154
210
|
also expose spacing tokens here for components that need raw var() access. */
|
|
@@ -201,6 +257,7 @@
|
|
|
201
257
|
--color-surface: #f2f0ea;
|
|
202
258
|
--color-surface-2: #e7e4db;
|
|
203
259
|
--color-surface-3: #dcd8cc;
|
|
260
|
+
--color-surface-4: #d0ccbf;
|
|
204
261
|
|
|
205
262
|
--color-ink: #1a1d2b;
|
|
206
263
|
--color-ink-2: #353a4b;
|
|
@@ -240,6 +297,7 @@
|
|
|
240
297
|
--color-surface: #191c24;
|
|
241
298
|
--color-surface-2: #222633;
|
|
242
299
|
--color-surface-3: #2c3140;
|
|
300
|
+
--color-surface-4: #363b4c;
|
|
243
301
|
|
|
244
302
|
--color-ink: #e9eaf0;
|
|
245
303
|
--color-ink-2: #c5c8d4;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/cn.ts","../src/components/button/button.tsx","../src/components/skeleton/skeleton.tsx"],"names":["AriaButton","tv","jsx"],"mappings":"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","file":"chunk-IKAX76MB.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components'\nimport { tv, type VariantProps } from 'tailwind-variants'\n\nimport { cn } from '../../lib/cn'\n\nexport const buttonStyles = tv({\n base: [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap cursor-pointer',\n 'font-mono tracking-[-0.005em] border border-transparent',\n 'transition-[background-color,color,border-color,box-shadow,transform] duration-150',\n 'outline-none pressed:translate-y-px',\n 'focus-visible:shadow-[var(--shadow-focus)]',\n 'disabled:opacity-45 disabled:cursor-not-allowed disabled:pointer-events-none',\n ],\n variants: {\n variant: {\n primary: ['bg-ink text-surface border-ink', 'hover:bg-accent-ink hover:border-accent-ink'],\n // Hover uses accent-2 — the token DESIGN.md reserves for \"hover on\n // accent\". accent-ink is a text-on-tinted-surface color and flips\n // light in dark mode, so it can't double as a hover fill here.\n accent: [\n 'bg-accent text-[#f0efe8] border-accent',\n 'hover:bg-accent-2 hover:border-accent-2',\n ],\n secondary: ['bg-transparent text-ink border-ink', 'hover:bg-ink hover:text-surface'],\n ghost: [\n 'bg-bg text-ink-2 border-rule-strong',\n 'hover:bg-surface-2 hover:text-ink hover:border-ink-4',\n ],\n // Transparent at rest, paper-fill on hover. The toolbar / sidebar\n // register — pairs with `size=\"icon-md\"` for top-bar icon buttons.\n subtle: ['bg-transparent text-ink-3 border-transparent', 'hover:bg-surface-2 hover:text-ink'],\n link: [\n 'bg-transparent text-ink-2 border-transparent',\n 'px-0.5 border-b border-b-ink-4',\n 'hover:text-ink hover:border-b-ink',\n ],\n },\n size: {\n sm: 'text-xs px-3 py-1.5 [&_svg]:size-3',\n md: 'text-[13px] px-4 py-[9px] [&_svg]:size-3',\n lg: 'text-sm px-[22px] py-3 [&_svg]:size-3.5',\n // Square dimensions for icon-only buttons. Requires an `aria-label`.\n 'icon-sm': 'size-7 p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-[34px] p-0 [&_svg]:size-4',\n 'icon-lg': 'size-[42px] p-0 [&_svg]:size-[18px]',\n },\n // Corner shape. Default is rounded (soft 10px radius — the standard\n // Proteos button), `pill` is the fully-rounded legacy treatment.\n // The `link` variant overrides both to a flat underline.\n shape: {\n rounded: 'rounded-md',\n pill: 'rounded-pill',\n },\n },\n compoundVariants: [\n { variant: 'link', size: 'sm', class: 'px-0.5 py-0' },\n { variant: 'link', size: 'md', class: 'px-0.5 py-0' },\n { variant: 'link', size: 'lg', class: 'px-0.5 py-0' },\n // Link never takes a corner radius — it's an underline, not a box.\n { variant: 'link', shape: 'rounded', class: 'rounded-none' },\n { variant: 'link', shape: 'pill', class: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n shape: 'rounded',\n },\n})\n\nexport type ButtonVariants = VariantProps<typeof buttonStyles>\nexport type ButtonProps = AriaButtonProps & ButtonVariants\n\nexport function Button({ variant, size, shape, className, ...props }: ButtonProps) {\n return (\n <AriaButton\n {...props}\n className={(renderProps) =>\n cn(\n buttonStyles({ variant, size, shape }),\n typeof className === 'function' ? className(renderProps) : className,\n )\n }\n />\n )\n}\n","import type { HTMLAttributes } from 'react'\nimport { tv, type VariantProps } from 'tailwind-variants'\n\nimport { cn } from '../../lib/cn'\n\n/* =========================================================================\n Skeleton — content placeholder for loading states.\n Purely presentational, so it doesn't wrap a React Aria primitive (RAC has\n no Skeleton — interactive primitives only). Accessibility lives in props:\n - decorative skeletons get `aria-hidden` so screen readers ignore them\n - skeletons that *announce* the loading state should be wrapped in a\n `role=\"status\"` region by the consumer (e.g. AppLayoutSkeleton).\n ========================================================================= */\n\nexport const skeletonStyles = tv({\n base: ['animate-pulse', 'bg-surface-3'],\n variants: {\n shape: {\n rect: 'rounded-md',\n circle: 'rounded-full',\n // `text` matches a typical line of body text — width is up to the\n // consumer; the rounded-sm + height keep proportions sensible.\n text: 'h-4 w-full rounded-sm',\n },\n },\n defaultVariants: { shape: 'rect' },\n})\n\nexport type SkeletonVariants = VariantProps<typeof skeletonStyles>\nexport type SkeletonProps = HTMLAttributes<HTMLDivElement> & SkeletonVariants\n\nexport function Skeleton({ shape, className, ...props }: SkeletonProps) {\n return (\n <div\n // Decorative by default. Consumers that want screen readers to announce\n // the loading state should wrap a Skeleton group in `role=\"status\"`\n // and pass `aria-hidden={false}` here, or just rely on the wrapper.\n aria-hidden=\"true\"\n {...props}\n className={cn(skeletonStyles({ shape }), className)}\n />\n )\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/cn.ts","../src/components/button/button.tsx","../src/components/skeleton/skeleton.tsx"],"names":["twMerge","clsx","tv","jsx","AriaButton"],"mappings":"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","file":"chunk-MWAXK66H.cjs","sourcesContent":["import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components'\nimport { tv, type VariantProps } from 'tailwind-variants'\n\nimport { cn } from '../../lib/cn'\n\nexport const buttonStyles = tv({\n base: [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap cursor-pointer',\n 'font-mono tracking-[-0.005em] border border-transparent',\n 'transition-[background-color,color,border-color,box-shadow,transform] duration-150',\n 'outline-none pressed:translate-y-px',\n 'focus-visible:shadow-[var(--shadow-focus)]',\n 'disabled:opacity-45 disabled:cursor-not-allowed disabled:pointer-events-none',\n ],\n variants: {\n variant: {\n primary: ['bg-ink text-surface border-ink', 'hover:bg-accent-ink hover:border-accent-ink'],\n // Hover uses accent-2 — the token DESIGN.md reserves for \"hover on\n // accent\". accent-ink is a text-on-tinted-surface color and flips\n // light in dark mode, so it can't double as a hover fill here.\n accent: [\n 'bg-accent text-[#f0efe8] border-accent',\n 'hover:bg-accent-2 hover:border-accent-2',\n ],\n secondary: ['bg-transparent text-ink border-ink', 'hover:bg-ink hover:text-surface'],\n ghost: [\n 'bg-bg text-ink-2 border-rule-strong',\n 'hover:bg-surface-2 hover:text-ink hover:border-ink-4',\n ],\n // Transparent at rest, paper-fill on hover. The toolbar / sidebar\n // register — pairs with `size=\"icon-md\"` for top-bar icon buttons.\n subtle: ['bg-transparent text-ink-3 border-transparent', 'hover:bg-surface-2 hover:text-ink'],\n link: [\n 'bg-transparent text-ink-2 border-transparent',\n 'px-0.5 border-b border-b-ink-4',\n 'hover:text-ink hover:border-b-ink',\n ],\n },\n size: {\n sm: 'text-xs px-3 py-1.5 [&_svg]:size-3',\n md: 'text-[13px] px-4 py-[9px] [&_svg]:size-3',\n lg: 'text-sm px-[22px] py-3 [&_svg]:size-3.5',\n // Square dimensions for icon-only buttons. Requires an `aria-label`.\n 'icon-sm': 'size-7 p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-[34px] p-0 [&_svg]:size-4',\n 'icon-lg': 'size-[42px] p-0 [&_svg]:size-[18px]',\n },\n // Corner shape. Default is rounded (soft 10px radius — the standard\n // Proteos button), `pill` is the fully-rounded legacy treatment.\n // The `link` variant overrides both to a flat underline.\n shape: {\n rounded: 'rounded-md',\n pill: 'rounded-pill',\n },\n },\n compoundVariants: [\n { variant: 'link', size: 'sm', class: 'px-0.5 py-0' },\n { variant: 'link', size: 'md', class: 'px-0.5 py-0' },\n { variant: 'link', size: 'lg', class: 'px-0.5 py-0' },\n // Link never takes a corner radius — it's an underline, not a box.\n { variant: 'link', shape: 'rounded', class: 'rounded-none' },\n { variant: 'link', shape: 'pill', class: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n shape: 'rounded',\n },\n})\n\nexport type ButtonVariants = VariantProps<typeof buttonStyles>\nexport type ButtonProps = AriaButtonProps & ButtonVariants\n\nexport function Button({ variant, size, shape, className, ...props }: ButtonProps) {\n return (\n <AriaButton\n {...props}\n className={(renderProps) =>\n cn(\n buttonStyles({ variant, size, shape }),\n typeof className === 'function' ? className(renderProps) : className,\n )\n }\n />\n )\n}\n","import type { HTMLAttributes } from 'react'\nimport { tv, type VariantProps } from 'tailwind-variants'\n\nimport { cn } from '../../lib/cn'\n\n/* =========================================================================\n Skeleton — content placeholder for loading states.\n Purely presentational, so it doesn't wrap a React Aria primitive (RAC has\n no Skeleton — interactive primitives only). Accessibility lives in props:\n - decorative skeletons get `aria-hidden` so screen readers ignore them\n - skeletons that *announce* the loading state should be wrapped in a\n `role=\"status\"` region by the consumer (e.g. AppLayoutSkeleton).\n ========================================================================= */\n\nexport const skeletonStyles = tv({\n base: ['animate-pulse', 'bg-surface-3'],\n variants: {\n shape: {\n rect: 'rounded-md',\n circle: 'rounded-full',\n // `text` matches a typical line of body text — width is up to the\n // consumer; the rounded-sm + height keep proportions sensible.\n text: 'h-4 w-full rounded-sm',\n },\n },\n defaultVariants: { shape: 'rect' },\n})\n\nexport type SkeletonVariants = VariantProps<typeof skeletonStyles>\nexport type SkeletonProps = HTMLAttributes<HTMLDivElement> & SkeletonVariants\n\nexport function Skeleton({ shape, className, ...props }: SkeletonProps) {\n return (\n <div\n // Decorative by default. Consumers that want screen readers to announce\n // the loading state should wrap a Skeleton group in `role=\"status\"`\n // and pass `aria-hidden={false}` here, or just rely on the wrapper.\n aria-hidden=\"true\"\n {...props}\n className={cn(skeletonStyles({ shape }), className)}\n />\n )\n}\n"]}
|