@xjur-ui/react 1.0.2 → 1.0.3

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.
@@ -1,8 +1,8 @@
1
1
 
2
- > @xjur-ui/react@1.0.1 build
2
+ > @xjur-ui/react@1.0.2 build
3
3
  > tsup
4
4
 
5
- CLI Building entry: src/index.ts, src/components/avatar.tsx, src/components/badge.tsx, src/components/button.tsx, src/components/calendar.tsx, src/components/checkbox.tsx, src/components/chip.tsx, src/components/collapsible.tsx, src/components/date-picker.tsx, src/components/divider.tsx, src/components/dropdown-menu.tsx, src/components/icon.tsx, src/components/input.tsx, src/components/list.tsx, src/components/logo.tsx, src/components/otp-input.tsx, src/components/radio.tsx, src/components/search-input.tsx, src/components/select.tsx, src/components/sheet.tsx, src/components/switch.tsx, src/components/tabs.tsx, src/components/tag.tsx, src/components/typography.tsx
5
+ CLI Building entry: src/index.ts, src/components/avatar-group.tsx, src/components/avatar.tsx, src/components/badge.tsx, src/components/button.tsx, src/components/calendar.tsx, src/components/checkbox.tsx, src/components/chip.tsx, src/components/collapsible.tsx, src/components/date-picker.tsx, src/components/divider.tsx, src/components/dropdown-menu.tsx, src/components/icon.tsx, src/components/input.tsx, src/components/list.tsx, src/components/logo.tsx, src/components/otp-input.tsx, src/components/radio.tsx, src/components/search-input.tsx, src/components/select.tsx, src/components/sheet.tsx, src/components/switch.tsx, src/components/table.tsx, src/components/tabs.tsx, src/components/tag.tsx, src/components/typography.tsx
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  CLI Using tsup config: /home/vsts/work/1/s/packages/react/tsup.config.ts
@@ -11,13 +11,14 @@ CLI Cleaning output folder
11
11
  ESM Build start
12
12
  DTS Build start
13
13
  ESM dist/index.js 0 B
14
- ESM dist/components/avatar.js 1.23 KB
15
- ESM dist/index.css 54.65 KB
14
+ ESM dist/components/avatar-group.js 4.98 KB
15
+ ESM dist/index.css 58.59 KB
16
+ ESM dist/components/avatar.js 1.38 KB
16
17
  ESM dist/components/badge.js 3.08 KB
17
18
  ESM dist/components/button.js 2.73 KB
18
19
  ESM dist/components/calendar.js 19.27 KB
19
20
  ESM dist/components/checkbox.js 4.64 KB
20
- ESM dist/components/chip.js 6.34 KB
21
+ ESM dist/components/chip.js 6.49 KB
21
22
  ESM dist/components/collapsible.js 998.00 B
22
23
  ESM dist/components/date-picker.js 6.90 KB
23
24
  ESM dist/components/divider.js 697.00 B
@@ -32,12 +33,14 @@ ESM dist/components/search-input.js 7.70 KB
32
33
  ESM dist/components/select.js 15.44 KB
33
34
  ESM dist/components/sheet.js 6.89 KB
34
35
  ESM dist/components/switch.js 1.13 KB
36
+ ESM dist/components/table.js 4.35 KB
35
37
  ESM dist/components/tabs.js 1.43 KB
36
38
  ESM dist/components/tag.js 4.77 KB
37
39
  ESM dist/components/typography.js 2.21 KB
38
- ESM ⚡️ Build success in 1286ms
39
- DTS ⚡️ Build success in 5617ms
40
+ ESM ⚡️ Build success in 1185ms
41
+ DTS ⚡️ Build success in 5286ms
40
42
  DTS dist/index.d.ts 13.00 B
43
+ DTS dist/components/avatar-group.d.ts 815.00 B
41
44
  DTS dist/components/badge.d.ts 607.00 B
42
45
  DTS dist/components/calendar.d.ts 448.00 B
43
46
  DTS dist/components/checkbox.d.ts 305.00 B
@@ -56,6 +59,7 @@ DTS dist/components/search-input.d.ts 1.10 KB
56
59
  DTS dist/components/button.d.ts 872.00 B
57
60
  DTS dist/components/sheet.d.ts 1.62 KB
58
61
  DTS dist/components/switch.d.ts 300.00 B
62
+ DTS dist/components/table.d.ts 1.28 KB
59
63
  DTS dist/components/tabs.d.ts 737.00 B
60
64
  DTS dist/components/tag.d.ts 1.07 KB
61
65
  DTS dist/components/typography.d.ts 993.00 B
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @xjur-ui/react
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - fb1a2db: Create avatar group component
8
+ - 31a7409: Adiciona componente de tabela
9
+
3
10
  ## 1.0.2
4
11
 
5
12
  ### Patch Changes
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface AvatarGroupProps {
4
+ /**
5
+ * Lista de avatares para exibir
6
+ */
7
+ avatars: Array<{
8
+ src?: string;
9
+ alt?: string;
10
+ fallback?: string;
11
+ }>;
12
+ /**
13
+ * Número máximo de avatares a exibir antes de mostrar o indicador de overflow
14
+ * @default 3
15
+ */
16
+ max?: number;
17
+ /**
18
+ * Tamanho dos avatares
19
+ * @default 'md'
20
+ */
21
+ size?: 'xs' | 'sm' | 'md' | 'lg';
22
+ /**
23
+ * Classe CSS adicional
24
+ */
25
+ className?: string;
26
+ /**
27
+ * Espaçamento entre os avatares (em pixels)
28
+ * @default -8
29
+ */
30
+ spacing?: number;
31
+ }
32
+ declare function AvatarGroup({ avatars, max, size, className }: AvatarGroupProps): react_jsx_runtime.JSX.Element;
33
+
34
+ export { AvatarGroup, type AvatarGroupProps };
@@ -0,0 +1,179 @@
1
+ // src/components/avatar-group.tsx
2
+ import { cx as cx2 } from "@xjur-ui/util";
3
+
4
+ // src/components/avatar.tsx
5
+ import "react";
6
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
7
+ import { cx } from "@xjur-ui/util";
8
+ import { jsx } from "react/jsx-runtime";
9
+ function AvatarRoot({
10
+ className,
11
+ size = "md",
12
+ ...props
13
+ }) {
14
+ return /* @__PURE__ */ jsx(
15
+ AvatarPrimitive.Root,
16
+ {
17
+ className: cx(
18
+ "rounded-circle relative flex shrink-0 overflow-hidden",
19
+ "data-[size=lg]:size-large-8x data-[size=md]:size-large-4x data-[size=sm]:size-large-2x data-[size=xs]:size-large-1x",
20
+ "data-[size=lg]:text-size-headline-md data-[size=md]:text-size-label-lg data-[size=sm]:text-size-label-sm data-[size=xs]:text-size-label-sm",
21
+ className
22
+ ),
23
+ "data-size": size,
24
+ "data-slot": "avatar",
25
+ ...props
26
+ }
27
+ );
28
+ }
29
+ function AvatarImage({
30
+ className,
31
+ ...props
32
+ }) {
33
+ return /* @__PURE__ */ jsx(
34
+ AvatarPrimitive.Image,
35
+ {
36
+ className: cx("aspect-square size-full", className),
37
+ "data-slot": "avatar-image",
38
+ ...props
39
+ }
40
+ );
41
+ }
42
+ function AvatarFallback({
43
+ className,
44
+ ...props
45
+ }) {
46
+ return /* @__PURE__ */ jsx(
47
+ AvatarPrimitive.Fallback,
48
+ {
49
+ className: cx(
50
+ "bg-alt-1 rounded-circle flex size-full items-center justify-center font-medium text-white",
51
+ className
52
+ ),
53
+ "data-slot": "avatar-fallback",
54
+ ...props
55
+ }
56
+ );
57
+ }
58
+
59
+ // src/components/typography.tsx
60
+ import { Slot } from "@radix-ui/react-slot";
61
+ import { cva } from "@xjur-ui/util";
62
+ import { memo } from "react";
63
+ import { jsx as jsx2 } from "react/jsx-runtime";
64
+ var typographyVariants = cva("", {
65
+ variants: {
66
+ variant: {
67
+ body: "",
68
+ label: "",
69
+ title: "",
70
+ headline: ""
71
+ },
72
+ size: {
73
+ "sm-2x": "",
74
+ "sm-1x": "",
75
+ sm: "",
76
+ md: "",
77
+ lg: ""
78
+ },
79
+ weight: {
80
+ thin: "font-thin",
81
+ extraLight: "font-extralight",
82
+ light: "font-light",
83
+ normal: "font-normal",
84
+ medium: "font-medium",
85
+ semibold: "font-semibold",
86
+ bold: "font-bold",
87
+ extraBold: "font-extrabold",
88
+ black: "font-black"
89
+ }
90
+ },
91
+ compoundVariants: [
92
+ { variant: "body", size: "sm-1x", class: "text-size-body-sm-1x" },
93
+ { variant: "body", size: "sm", class: "text-size-body-sm" },
94
+ { variant: "body", size: "md", class: "text-size-body-md" },
95
+ { variant: "body", size: "lg", class: "text-size-body-lg" },
96
+ { variant: "label", size: "sm-2x", class: "text-size-label-sm-2x" },
97
+ { variant: "label", size: "sm-1x", class: "text-size-label-sm-1x" },
98
+ { variant: "label", size: "sm", class: "text-size-label-sm" },
99
+ { variant: "label", size: "md", class: "text-size-label-md" },
100
+ { variant: "label", size: "lg", class: "text-size-label-lg" },
101
+ { variant: "title", size: "sm", class: "text-size-title-sm" },
102
+ { variant: "title", size: "md", class: "text-size-title-md" },
103
+ { variant: "title", size: "lg", class: "text-size-title-lg" },
104
+ { variant: "headline", size: "sm", class: "text-size-headline-sm" },
105
+ { variant: "headline", size: "md", class: "text-size-headline-md" },
106
+ { variant: "headline", size: "lg", class: "text-size-headline-lg" }
107
+ ],
108
+ defaultVariants: {
109
+ variant: "body",
110
+ size: "md",
111
+ weight: "normal"
112
+ }
113
+ });
114
+ var Typography = memo(
115
+ ({
116
+ variant,
117
+ size,
118
+ weight,
119
+ asChild,
120
+ className,
121
+ ...props
122
+ }) => {
123
+ const Component = asChild ? Slot : "span";
124
+ return /* @__PURE__ */ jsx2(
125
+ Component,
126
+ {
127
+ className: typographyVariants({ variant, size, weight, className }),
128
+ ...props
129
+ }
130
+ );
131
+ }
132
+ );
133
+ Typography.displayName = "Typography";
134
+
135
+ // src/components/avatar-group.tsx
136
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
137
+ function AvatarGroup({
138
+ avatars,
139
+ max = 3,
140
+ size = "md",
141
+ className
142
+ }) {
143
+ const visibleAvatars = avatars.slice(0, max);
144
+ const remainingCount = avatars.length - max;
145
+ return /* @__PURE__ */ jsxs(
146
+ "div",
147
+ {
148
+ className: cx2("-space-x-small-1x flex items-center", className),
149
+ "data-slot": "avatar-group",
150
+ children: [
151
+ visibleAvatars.map((avatar, index) => /* @__PURE__ */ jsxs(
152
+ AvatarRoot,
153
+ {
154
+ className: "border-icon-neutral-5 border-2",
155
+ size,
156
+ children: [
157
+ avatar.src && /* @__PURE__ */ jsx3(
158
+ AvatarImage,
159
+ {
160
+ alt: avatar.alt || `Avatar ${index + 1}`,
161
+ src: avatar.src
162
+ }
163
+ ),
164
+ /* @__PURE__ */ jsx3(AvatarFallback, { children: avatar.fallback || `A${index + 1}` })
165
+ ]
166
+ },
167
+ index
168
+ )),
169
+ remainingCount > 0 && /* @__PURE__ */ jsx3(AvatarRoot, { className: "bg-layer-1-hover", size, children: /* @__PURE__ */ jsx3(AvatarFallback, { className: "bg-layer-1-hover font-medium", children: /* @__PURE__ */ jsxs(Typography, { className: "text-neutral-dark", weight: "medium", children: [
170
+ "+",
171
+ remainingCount
172
+ ] }) }) })
173
+ ]
174
+ }
175
+ );
176
+ }
177
+ export {
178
+ AvatarGroup
179
+ };
@@ -14,6 +14,7 @@ function AvatarRoot({
14
14
  className: cx(
15
15
  "rounded-circle relative flex shrink-0 overflow-hidden",
16
16
  "data-[size=lg]:size-large-8x data-[size=md]:size-large-4x data-[size=sm]:size-large-2x data-[size=xs]:size-large-1x",
17
+ "data-[size=lg]:text-size-headline-md data-[size=md]:text-size-label-lg data-[size=sm]:text-size-label-sm data-[size=xs]:text-size-label-sm",
17
18
  className
18
19
  ),
19
20
  "data-size": size,
@@ -116,6 +116,7 @@ function AvatarRoot({
116
116
  className: cx2(
117
117
  "rounded-circle relative flex shrink-0 overflow-hidden",
118
118
  "data-[size=lg]:size-large-8x data-[size=md]:size-large-4x data-[size=sm]:size-large-2x data-[size=xs]:size-large-1x",
119
+ "data-[size=lg]:text-size-headline-md data-[size=md]:text-size-label-lg data-[size=sm]:text-size-label-sm data-[size=xs]:text-size-label-sm",
119
120
  className
120
121
  ),
121
122
  "data-size": size,
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ declare function Table({ className, ...props }: React.ComponentProps<'table'>): react_jsx_runtime.JSX.Element;
4
+ declare function TableHeader({ className, ...props }: React.ComponentProps<'thead'>): react_jsx_runtime.JSX.Element;
5
+ declare function TableBody({ className, ...props }: React.ComponentProps<'tbody'>): react_jsx_runtime.JSX.Element;
6
+ declare function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>): react_jsx_runtime.JSX.Element;
7
+ declare function TableRow({ className, isSelected, ...props }: React.ComponentProps<'tr'> & {
8
+ isSelected?: boolean;
9
+ }): react_jsx_runtime.JSX.Element;
10
+ declare function TableHead({ className, ...props }: React.ComponentProps<'th'>): react_jsx_runtime.JSX.Element;
11
+ declare function TableHeadContent({ className, ...props }: React.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
12
+ declare function TableSort({ className, sortedDirection, ...props }: React.ComponentProps<'button'> & {
13
+ sortedDirection?: 'asc' | 'desc';
14
+ }): react_jsx_runtime.JSX.Element;
15
+ declare function TableCell({ className, ...props }: React.ComponentProps<'td'>): react_jsx_runtime.JSX.Element;
16
+
17
+ export { Table, TableBody, TableCell, TableFooter, TableHead, TableHeadContent, TableHeader, TableRow, TableSort };
@@ -0,0 +1,196 @@
1
+ // src/components/table.tsx
2
+ import { cx as cx2 } from "@xjur-ui/util";
3
+
4
+ // src/components/icon.tsx
5
+ import { cx } from "@xjur-ui/util";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function Icon({ className, filled = false, name, ...props }) {
8
+ return /* @__PURE__ */ jsx(
9
+ "span",
10
+ {
11
+ ...props,
12
+ className: cx(
13
+ "material-symbols-outlined",
14
+ "text-size-body-lg",
15
+ className
16
+ ),
17
+ style: {
18
+ fontVariationSettings: `'FILL' ${filled ? 1 : 0}, 'wght' 600, 'GRAD' 0, 'opsz' 20`,
19
+ ...props.style
20
+ },
21
+ children: name
22
+ }
23
+ );
24
+ }
25
+
26
+ // src/components/table.tsx
27
+ import { jsx as jsx2 } from "react/jsx-runtime";
28
+ function Table({ className, ...props }) {
29
+ return /* @__PURE__ */ jsx2(
30
+ "div",
31
+ {
32
+ className: "text-size-body-md scrollbar-thin relative w-full overflow-hidden transition-all hover:overflow-x-auto",
33
+ "data-slot": "table-container",
34
+ children: /* @__PURE__ */ jsx2(
35
+ "table",
36
+ {
37
+ className: cx2("w-full caption-bottom", className),
38
+ "data-slot": "table",
39
+ ...props
40
+ }
41
+ )
42
+ }
43
+ );
44
+ }
45
+ function TableHeader({
46
+ className,
47
+ ...props
48
+ }) {
49
+ return /* @__PURE__ */ jsx2(
50
+ "thead",
51
+ {
52
+ className: cx2(
53
+ "group/table-header [&_tr]:border-border-layer-2 hover:bg-layer-2-hover [&_tr]:border-b",
54
+ className
55
+ ),
56
+ "data-slot": "table-header",
57
+ ...props
58
+ }
59
+ );
60
+ }
61
+ function TableBody({
62
+ className,
63
+ ...props
64
+ }) {
65
+ return /* @__PURE__ */ jsx2(
66
+ "tbody",
67
+ {
68
+ className: cx2(
69
+ "[&_tr]:border-border-layer-2 [&_tr]:border-b [&_tr:last-child]:border-0",
70
+ className
71
+ ),
72
+ "data-slot": "table-body",
73
+ ...props
74
+ }
75
+ );
76
+ }
77
+ function TableFooter({
78
+ className,
79
+ ...props
80
+ }) {
81
+ return /* @__PURE__ */ jsx2(
82
+ "tfoot",
83
+ {
84
+ className: cx2(
85
+ "border-border-layer-2 border-t font-medium [&>tr]:last:border-b-0",
86
+ className
87
+ ),
88
+ "data-slot": "table-footer",
89
+ ...props
90
+ }
91
+ );
92
+ }
93
+ function TableRow({
94
+ className,
95
+ isSelected = false,
96
+ ...props
97
+ }) {
98
+ return /* @__PURE__ */ jsx2(
99
+ "tr",
100
+ {
101
+ className: cx2(
102
+ "bg-layer-2-idle hover:bg-layer-2-hover ease border-b transition-colors duration-100",
103
+ "active:bg-layer-2-pressed",
104
+ "data-[selected=true]:bg-primary-alt-active",
105
+ className
106
+ ),
107
+ "data-selected": isSelected,
108
+ "data-slot": "table-row",
109
+ ...props
110
+ }
111
+ );
112
+ }
113
+ function TableHead({ className, ...props }) {
114
+ return /* @__PURE__ */ jsx2(
115
+ "th",
116
+ {
117
+ className: cx2(
118
+ "group/th text-neutral-placeholder text-size-label-sm h-large-4x py-small-1x px-small text-left align-middle font-medium whitespace-nowrap",
119
+ "pr-large-2x relative",
120
+ "animate-in fade-in duration-200 ease-in",
121
+ className
122
+ ),
123
+ "data-slot": "table-head",
124
+ ...props
125
+ }
126
+ );
127
+ }
128
+ function TableHeadContent({
129
+ className,
130
+ ...props
131
+ }) {
132
+ return /* @__PURE__ */ jsx2(
133
+ "div",
134
+ {
135
+ className: cx2(
136
+ "gap-small pr-large-3x relative flex w-fit items-center",
137
+ className
138
+ ),
139
+ ...props
140
+ }
141
+ );
142
+ }
143
+ function TableSort({
144
+ className,
145
+ sortedDirection,
146
+ ...props
147
+ }) {
148
+ return /* @__PURE__ */ jsx2(
149
+ "button",
150
+ {
151
+ className: cx2(
152
+ "size-large-1x rounded-small-1x",
153
+ "flex cursor-pointer items-center justify-center",
154
+ "hidden group-hover/th:flex",
155
+ "data-[sorted=true]:flex",
156
+ "transition-all duration-200 ease-out",
157
+ "data-[sorted=true]:bg-primary-alt-active data-[sorted=true]:text-primary-label-active",
158
+ "absolute top-1/2 right-0 -translate-y-1/2",
159
+ className
160
+ ),
161
+ "data-sorted": sortedDirection !== void 0,
162
+ type: "button",
163
+ ...props,
164
+ children: sortedDirection !== void 0 ? /* @__PURE__ */ jsx2(
165
+ Icon,
166
+ {
167
+ name: sortedDirection === "asc" ? "arrow_downward" : "arrow_upward"
168
+ }
169
+ ) : /* @__PURE__ */ jsx2(Icon, { name: "swap_vert" })
170
+ }
171
+ );
172
+ }
173
+ function TableCell({ className, ...props }) {
174
+ return /* @__PURE__ */ jsx2(
175
+ "td",
176
+ {
177
+ className: cx2(
178
+ "px-small py-none h-large-8x text-left align-middle whitespace-nowrap",
179
+ className
180
+ ),
181
+ "data-slot": "table-cell",
182
+ ...props
183
+ }
184
+ );
185
+ }
186
+ export {
187
+ Table,
188
+ TableBody,
189
+ TableCell,
190
+ TableFooter,
191
+ TableHead,
192
+ TableHeadContent,
193
+ TableHeader,
194
+ TableRow,
195
+ TableSort
196
+ };
@@ -5,7 +5,7 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
5
5
  import { ClassVariantProps } from '@xjur-ui/util';
6
6
 
7
7
  declare const typographyVariants: (props?: ({
8
- variant?: "body" | "label" | "title" | "headline" | null | undefined;
8
+ variant?: "label" | "body" | "title" | "headline" | null | undefined;
9
9
  size?: "sm" | "md" | "lg" | "sm-2x" | "sm-1x" | null | undefined;
10
10
  weight?: "bold" | "thin" | "extraLight" | "light" | "normal" | "medium" | "semibold" | "extraBold" | "black" | null | undefined;
11
11
  } & class_variance_authority_types.ClassProp) | undefined) => string;
package/dist/index.css CHANGED
@@ -34,6 +34,7 @@
34
34
  --font-weight-bold: 700;
35
35
  --font-weight-extrabold: 800;
36
36
  --font-weight-black: 900;
37
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
37
38
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
38
39
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
39
40
  --default-transition-duration: 150ms;
@@ -78,6 +79,7 @@
78
79
  --color-neutral-placeholder: #9C9CAD;
79
80
  --color-neutral-label: #FFFFFF;
80
81
  --color-icon-neutral-3: #69697A;
82
+ --color-icon-neutral-5: #FFFFFF;
81
83
  --color-layer-1-idle: #F7F7FA;
82
84
  --color-layer-1-hover: #F0F0F2;
83
85
  --color-layer-1-pressed: #E7E7EB;
@@ -392,6 +394,27 @@
392
394
  .ml-small-1x {
393
395
  margin-left: var(--spacing-small-1x);
394
396
  }
397
+ .scrollbar-thin {
398
+ &::-webkit-scrollbar-track {
399
+ background-color: var(--scrollbar-track);
400
+ border-radius: var(--scrollbar-track-radius);
401
+ }
402
+ &::-webkit-scrollbar-thumb {
403
+ background-color: var(--scrollbar-thumb);
404
+ border-radius: var(--scrollbar-thumb-radius);
405
+ }
406
+ &::-webkit-scrollbar-corner {
407
+ background-color: var(--scrollbar-corner);
408
+ border-radius: var(--scrollbar-corner-radius);
409
+ }
410
+ scrollbar-width: thin;
411
+ scrollbar-color: var(--scrollbar-thumb, initial) var(--scrollbar-track, initial);
412
+ &::-webkit-scrollbar {
413
+ display: block;
414
+ width: 8px;
415
+ height: 8px;
416
+ }
417
+ }
395
418
  .scrollbar-hide {
396
419
  -ms-overflow-style: none;
397
420
  scrollbar-width: none;
@@ -411,6 +434,15 @@
411
434
  .inline-flex {
412
435
  display: inline-flex;
413
436
  }
437
+ .table {
438
+ display: table;
439
+ }
440
+ .table-cell {
441
+ display: table-cell;
442
+ }
443
+ .table-row {
444
+ display: table-row;
445
+ }
414
446
  .aspect-square {
415
447
  aspect-ratio: 1 / 1;
416
448
  }
@@ -422,6 +454,10 @@
422
454
  width: var(--spacing-large);
423
455
  height: var(--spacing-large);
424
456
  }
457
+ .size-large-1x {
458
+ width: var(--spacing-large-1x);
459
+ height: var(--spacing-large-1x);
460
+ }
425
461
  .size-large-alt {
426
462
  width: var(--spacing-large-alt);
427
463
  height: var(--spacing-large-alt);
@@ -451,6 +487,9 @@
451
487
  .h-large-7x {
452
488
  height: var(--spacing-large-7x);
453
489
  }
490
+ .h-large-8x {
491
+ height: var(--spacing-large-8x);
492
+ }
454
493
  .max-h-\[400px\] {
455
494
  max-height: 400px;
456
495
  }
@@ -496,6 +535,9 @@
496
535
  .shrink-0 {
497
536
  flex-shrink: 0;
498
537
  }
538
+ .caption-bottom {
539
+ caption-side: bottom;
540
+ }
499
541
  .-translate-y-1\/2 {
500
542
  --tw-translate-y: calc(calc(1/2 * 100%) * -1);
501
543
  translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -533,6 +575,13 @@
533
575
  .gap-small_1x-alt {
534
576
  gap: var(--spacing-small_1x-alt);
535
577
  }
578
+ .-space-x-small-1x {
579
+ :where(& > :not(:last-child)) {
580
+ --tw-space-x-reverse: 0;
581
+ margin-inline-start: calc(calc(var(--spacing-small-1x) * -1) * var(--tw-space-x-reverse));
582
+ margin-inline-end: calc(calc(var(--spacing-small-1x) * -1) * calc(1 - var(--tw-space-x-reverse)));
583
+ }
584
+ }
536
585
  .truncate {
537
586
  overflow: hidden;
538
587
  text-overflow: ellipsis;
@@ -632,6 +681,9 @@
632
681
  .border-border-layer-2 {
633
682
  border-color: var(--color-border-layer-2);
634
683
  }
684
+ .border-icon-neutral-5 {
685
+ border-color: var(--color-icon-neutral-5);
686
+ }
635
687
  .border-transparent {
636
688
  border-color: transparent;
637
689
  }
@@ -740,12 +792,21 @@
740
792
  .pt-small-1x {
741
793
  padding-top: var(--spacing-small-1x);
742
794
  }
795
+ .pr-large-2x {
796
+ padding-right: var(--spacing-large-2x);
797
+ }
798
+ .pr-large-3x {
799
+ padding-right: var(--spacing-large-3x);
800
+ }
743
801
  .text-center {
744
802
  text-align: center;
745
803
  }
746
804
  .text-left {
747
805
  text-align: left;
748
806
  }
807
+ .align-middle {
808
+ vertical-align: middle;
809
+ }
749
810
  .font-inter {
750
811
  font-family: var(--font-inter);
751
812
  }
@@ -845,6 +906,9 @@
845
906
  --tw-font-weight: var(--font-weight-thin);
846
907
  font-weight: var(--font-weight-thin);
847
908
  }
909
+ .whitespace-nowrap {
910
+ white-space: nowrap;
911
+ }
848
912
  .\!text-primary-label-active {
849
913
  color: var(--color-primary-label-active) !important;
850
914
  }
@@ -998,6 +1062,10 @@
998
1062
  --tw-duration: 250ms;
999
1063
  transition-duration: 250ms;
1000
1064
  }
1065
+ .ease-in {
1066
+ --tw-ease: var(--ease-in);
1067
+ transition-timing-function: var(--ease-in);
1068
+ }
1001
1069
  .ease-in-out {
1002
1070
  --tw-ease: var(--ease-in-out);
1003
1071
  transition-timing-function: var(--ease-in-out);
@@ -1010,6 +1078,9 @@
1010
1078
  --tw-outline-style: none;
1011
1079
  outline-style: none;
1012
1080
  }
1081
+ .fade-in {
1082
+ --tw-enter-opacity: 0;
1083
+ }
1013
1084
  .group-focus-within\:-top-\[3px\] {
1014
1085
  &:is(:where(.group):focus-within *) {
1015
1086
  top: calc(3px * -1);
@@ -1073,6 +1144,13 @@
1073
1144
  }
1074
1145
  }
1075
1146
  }
1147
+ .group-hover\/th\:flex {
1148
+ &:is(:where(.group\/th):hover *) {
1149
+ @media (hover: hover) {
1150
+ display: flex;
1151
+ }
1152
+ }
1153
+ }
1076
1154
  .group-has-\[div\[data-slot\=date-picker-left-slot\]\]\:left-large-4x {
1077
1155
  &:is(:where(.group):has(*:is(div[data-slot=date-picker-left-slot])) *) {
1078
1156
  left: var(--spacing-large-4x);
@@ -1353,6 +1431,13 @@
1353
1431
  var(--tw-shadow);
1354
1432
  }
1355
1433
  }
1434
+ .hover\:overflow-x-auto {
1435
+ &:hover {
1436
+ @media (hover: hover) {
1437
+ overflow-x: auto;
1438
+ }
1439
+ }
1440
+ }
1356
1441
  .hover\:border-border-layer-3 {
1357
1442
  &:hover {
1358
1443
  @media (hover: hover) {
@@ -1606,30 +1691,74 @@
1606
1691
  flex-direction: column;
1607
1692
  }
1608
1693
  }
1694
+ .data-\[selected\=true\]\:bg-primary-alt-active {
1695
+ &[data-selected=true] {
1696
+ background-color: var(--color-primary-alt-active);
1697
+ }
1698
+ }
1609
1699
  .data-\[size\=lg\]\:size-large-8x {
1610
1700
  &[data-size=lg] {
1611
1701
  width: var(--spacing-large-8x);
1612
1702
  height: var(--spacing-large-8x);
1613
1703
  }
1614
1704
  }
1705
+ .data-\[size\=lg\]\:text-size-headline-md {
1706
+ &[data-size=lg] {
1707
+ font-size: var(--text-size-headline-md);
1708
+ line-height: var(--tw-leading, var(--text-size-headline-md--line-height));
1709
+ }
1710
+ }
1615
1711
  .data-\[size\=md\]\:size-large-4x {
1616
1712
  &[data-size=md] {
1617
1713
  width: var(--spacing-large-4x);
1618
1714
  height: var(--spacing-large-4x);
1619
1715
  }
1620
1716
  }
1717
+ .data-\[size\=md\]\:text-size-label-lg {
1718
+ &[data-size=md] {
1719
+ font-size: var(--text-size-label-lg);
1720
+ line-height: var(--tw-leading, var(--text-size-label-lg--line-height));
1721
+ }
1722
+ }
1621
1723
  .data-\[size\=sm\]\:size-large-2x {
1622
1724
  &[data-size=sm] {
1623
1725
  width: var(--spacing-large-2x);
1624
1726
  height: var(--spacing-large-2x);
1625
1727
  }
1626
1728
  }
1729
+ .data-\[size\=sm\]\:text-size-label-sm {
1730
+ &[data-size=sm] {
1731
+ font-size: var(--text-size-label-sm);
1732
+ line-height: var(--tw-leading, var(--text-size-label-sm--line-height));
1733
+ }
1734
+ }
1627
1735
  .data-\[size\=xs\]\:size-large-1x {
1628
1736
  &[data-size=xs] {
1629
1737
  width: var(--spacing-large-1x);
1630
1738
  height: var(--spacing-large-1x);
1631
1739
  }
1632
1740
  }
1741
+ .data-\[size\=xs\]\:text-size-label-sm {
1742
+ &[data-size=xs] {
1743
+ font-size: var(--text-size-label-sm);
1744
+ line-height: var(--tw-leading, var(--text-size-label-sm--line-height));
1745
+ }
1746
+ }
1747
+ .data-\[sorted\=true\]\:flex {
1748
+ &[data-sorted=true] {
1749
+ display: flex;
1750
+ }
1751
+ }
1752
+ .data-\[sorted\=true\]\:bg-primary-alt-active {
1753
+ &[data-sorted=true] {
1754
+ background-color: var(--color-primary-alt-active);
1755
+ }
1756
+ }
1757
+ .data-\[sorted\=true\]\:text-primary-label-active {
1758
+ &[data-sorted=true] {
1759
+ color: var(--color-primary-label-active);
1760
+ }
1761
+ }
1633
1762
  .data-\[state\=active\]\:rounded-none {
1634
1763
  &[data-state=active] {
1635
1764
  border-radius: 0;
@@ -1814,6 +1943,31 @@
1814
1943
  max-width: var(--container-sm);
1815
1944
  }
1816
1945
  }
1946
+ .\[\&_tr\]\:border-b {
1947
+ & tr {
1948
+ border-bottom-style: var(--tw-border-style);
1949
+ border-bottom-width: 1px;
1950
+ }
1951
+ }
1952
+ .\[\&_tr\]\:border-border-layer-2 {
1953
+ & tr {
1954
+ border-color: var(--color-border-layer-2);
1955
+ }
1956
+ }
1957
+ .\[\&_tr\:last-child\]\:border-0 {
1958
+ & tr:last-child {
1959
+ border-style: var(--tw-border-style);
1960
+ border-width: 0px;
1961
+ }
1962
+ }
1963
+ .\[\&\>tr\]\:last\:border-b-0 {
1964
+ & > tr {
1965
+ &:last-child {
1966
+ border-bottom-style: var(--tw-border-style);
1967
+ border-bottom-width: 0px;
1968
+ }
1969
+ }
1970
+ }
1817
1971
  }
1818
1972
  @property --tw-animation-delay { syntax: "*"; inherits: false; initial-value: 0s; }
1819
1973
  @property --tw-animation-direction { syntax: "*"; inherits: false; initial-value: normal; }
@@ -1841,6 +1995,7 @@
1841
1995
  @property --tw-translate-x { syntax: "*"; inherits: false; initial-value: 0; }
1842
1996
  @property --tw-translate-y { syntax: "*"; inherits: false; initial-value: 0; }
1843
1997
  @property --tw-translate-z { syntax: "*"; inherits: false; initial-value: 0; }
1998
+ @property --tw-space-x-reverse { syntax: "*"; inherits: false; initial-value: 0; }
1844
1999
  @property --tw-border-style { syntax: "*"; inherits: false; initial-value: solid; }
1845
2000
  @property --tw-font-weight { syntax: "*"; inherits: false; }
1846
2001
  @property --tw-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }
@@ -1899,6 +2054,7 @@
1899
2054
  --tw-translate-x: 0;
1900
2055
  --tw-translate-y: 0;
1901
2056
  --tw-translate-z: 0;
2057
+ --tw-space-x-reverse: 0;
1902
2058
  --tw-border-style: solid;
1903
2059
  --tw-font-weight: initial;
1904
2060
  --tw-shadow: 0 0 #0000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xjur-ui/react",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "description": "React components for XJur Design System",
6
6
  "main": "dist/index.js",
@@ -30,7 +30,9 @@
30
30
  "./dropdown-menu": "./dist/components/dropdown-menu.js",
31
31
  "./divider": "./dist/components/divider.js",
32
32
  "./sheet": "./dist/components/sheet.js",
33
- "./badge": "./dist/components/badge.js"
33
+ "./badge": "./dist/components/badge.js",
34
+ "./table": "./dist/components/table.js",
35
+ "./avatar-group": "./dist/components/avatar-group.js"
34
36
  },
35
37
  "dependencies": {
36
38
  "@radix-ui/react-avatar": "^1.1.10",
@@ -0,0 +1,76 @@
1
+ import { cx } from '@xjur-ui/util'
2
+ import { AvatarRoot, AvatarImage, AvatarFallback } from './avatar'
3
+ import { Typography } from './typography'
4
+
5
+ export interface AvatarGroupProps {
6
+ /**
7
+ * Lista de avatares para exibir
8
+ */
9
+ avatars: Array<{
10
+ src?: string
11
+ alt?: string
12
+ fallback?: string
13
+ }>
14
+ /**
15
+ * Número máximo de avatares a exibir antes de mostrar o indicador de overflow
16
+ * @default 3
17
+ */
18
+ max?: number
19
+ /**
20
+ * Tamanho dos avatares
21
+ * @default 'md'
22
+ */
23
+ size?: 'xs' | 'sm' | 'md' | 'lg'
24
+ /**
25
+ * Classe CSS adicional
26
+ */
27
+ className?: string
28
+ /**
29
+ * Espaçamento entre os avatares (em pixels)
30
+ * @default -8
31
+ */
32
+ spacing?: number
33
+ }
34
+
35
+ export function AvatarGroup({
36
+ avatars,
37
+ max = 3,
38
+ size = 'md',
39
+ className
40
+ }: AvatarGroupProps) {
41
+ const visibleAvatars = avatars.slice(0, max)
42
+ const remainingCount = avatars.length - max
43
+
44
+ return (
45
+ <div
46
+ className={cx('-space-x-small-1x flex items-center', className)}
47
+ data-slot="avatar-group"
48
+ >
49
+ {visibleAvatars.map((avatar, index) => (
50
+ <AvatarRoot
51
+ className="border-icon-neutral-5 border-2"
52
+ key={index}
53
+ size={size}
54
+ >
55
+ {avatar.src && (
56
+ <AvatarImage
57
+ alt={avatar.alt || `Avatar ${index + 1}`}
58
+ src={avatar.src}
59
+ />
60
+ )}
61
+ <AvatarFallback>{avatar.fallback || `A${index + 1}`}</AvatarFallback>
62
+ </AvatarRoot>
63
+ ))}
64
+
65
+ {remainingCount > 0 && (
66
+ <AvatarRoot className="bg-layer-1-hover" size={size}>
67
+ <AvatarFallback className="bg-layer-1-hover font-medium">
68
+ <Typography className="text-neutral-dark" weight="medium">
69
+ +{remainingCount}
70
+ </Typography>
71
+ </AvatarFallback>
72
+ </AvatarRoot>
73
+ )}
74
+ </div>
75
+ )
76
+ }
@@ -14,6 +14,7 @@ export function AvatarRoot({
14
14
  className={cx(
15
15
  'rounded-circle relative flex shrink-0 overflow-hidden',
16
16
  'data-[size=lg]:size-large-8x data-[size=md]:size-large-4x data-[size=sm]:size-large-2x data-[size=xs]:size-large-1x',
17
+ 'data-[size=lg]:text-size-headline-md data-[size=md]:text-size-label-lg data-[size=sm]:text-size-label-sm data-[size=xs]:text-size-label-sm',
17
18
  className
18
19
  )}
19
20
  data-size={size}
@@ -0,0 +1,160 @@
1
+ import { cx } from '@xjur-ui/util'
2
+ import { Icon } from './icon'
3
+
4
+ export function Table({ className, ...props }: React.ComponentProps<'table'>) {
5
+ return (
6
+ <div
7
+ className="text-size-body-md scrollbar-thin relative w-full overflow-hidden transition-all hover:overflow-x-auto"
8
+ data-slot="table-container"
9
+ >
10
+ <table
11
+ className={cx('w-full caption-bottom', className)}
12
+ data-slot="table"
13
+ {...props}
14
+ />
15
+ </div>
16
+ )
17
+ }
18
+
19
+ export function TableHeader({
20
+ className,
21
+ ...props
22
+ }: React.ComponentProps<'thead'>) {
23
+ return (
24
+ <thead
25
+ className={cx(
26
+ 'group/table-header [&_tr]:border-border-layer-2 hover:bg-layer-2-hover [&_tr]:border-b',
27
+ className
28
+ )}
29
+ data-slot="table-header"
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ export function TableBody({
36
+ className,
37
+ ...props
38
+ }: React.ComponentProps<'tbody'>) {
39
+ return (
40
+ <tbody
41
+ className={cx(
42
+ '[&_tr]:border-border-layer-2 [&_tr]:border-b [&_tr:last-child]:border-0',
43
+ className
44
+ )}
45
+ data-slot="table-body"
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ export function TableFooter({
52
+ className,
53
+ ...props
54
+ }: React.ComponentProps<'tfoot'>) {
55
+ return (
56
+ <tfoot
57
+ className={cx(
58
+ 'border-border-layer-2 border-t font-medium [&>tr]:last:border-b-0',
59
+ className
60
+ )}
61
+ data-slot="table-footer"
62
+ {...props}
63
+ />
64
+ )
65
+ }
66
+
67
+ export function TableRow({
68
+ className,
69
+ isSelected = false,
70
+ ...props
71
+ }: React.ComponentProps<'tr'> & { isSelected?: boolean }) {
72
+ return (
73
+ <tr
74
+ className={cx(
75
+ 'bg-layer-2-idle hover:bg-layer-2-hover ease border-b transition-colors duration-100',
76
+ 'active:bg-layer-2-pressed',
77
+ 'data-[selected=true]:bg-primary-alt-active',
78
+ className
79
+ )}
80
+ data-selected={isSelected}
81
+ data-slot="table-row"
82
+ {...props}
83
+ />
84
+ )
85
+ }
86
+
87
+ export function TableHead({ className, ...props }: React.ComponentProps<'th'>) {
88
+ return (
89
+ <th
90
+ className={cx(
91
+ 'group/th text-neutral-placeholder text-size-label-sm h-large-4x py-small-1x px-small text-left align-middle font-medium whitespace-nowrap',
92
+ 'pr-large-2x relative',
93
+ 'animate-in fade-in duration-200 ease-in',
94
+ className
95
+ )}
96
+ data-slot="table-head"
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ export function TableHeadContent({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<'div'>) {
106
+ return (
107
+ <div
108
+ className={cx(
109
+ 'gap-small pr-large-3x relative flex w-fit items-center',
110
+ className
111
+ )}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ export function TableSort({
118
+ className,
119
+ sortedDirection,
120
+ ...props
121
+ }: React.ComponentProps<'button'> & { sortedDirection?: 'asc' | 'desc' }) {
122
+ return (
123
+ <button
124
+ className={cx(
125
+ 'size-large-1x rounded-small-1x',
126
+ 'flex cursor-pointer items-center justify-center',
127
+ 'hidden group-hover/th:flex',
128
+ 'data-[sorted=true]:flex',
129
+ 'transition-all duration-200 ease-out',
130
+ 'data-[sorted=true]:bg-primary-alt-active data-[sorted=true]:text-primary-label-active',
131
+ 'absolute top-1/2 right-0 -translate-y-1/2',
132
+ className
133
+ )}
134
+ data-sorted={sortedDirection !== undefined}
135
+ type="button"
136
+ {...props}
137
+ >
138
+ {sortedDirection !== undefined ? (
139
+ <Icon
140
+ name={sortedDirection === 'asc' ? 'arrow_downward' : 'arrow_upward'}
141
+ />
142
+ ) : (
143
+ <Icon name="swap_vert" />
144
+ )}
145
+ </button>
146
+ )
147
+ }
148
+
149
+ export function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
150
+ return (
151
+ <td
152
+ className={cx(
153
+ 'px-small py-none h-large-8x text-left align-middle whitespace-nowrap',
154
+ className
155
+ )}
156
+ data-slot="table-cell"
157
+ {...props}
158
+ />
159
+ )
160
+ }