@a-type/ui 1.5.0 → 1.5.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 (75) hide show
  1. package/dist/cjs/components/avatar/Avatar.js +3 -3
  2. package/dist/cjs/components/avatar/Avatar.js.map +1 -1
  3. package/dist/cjs/components/box/Box.d.ts +14 -7
  4. package/dist/cjs/components/box/Box.js +51 -13
  5. package/dist/cjs/components/box/Box.js.map +1 -1
  6. package/dist/cjs/components/box/Box.stories.d.ts +3 -0
  7. package/dist/cjs/components/box/Box.stories.js +3 -0
  8. package/dist/cjs/components/box/Box.stories.js.map +1 -1
  9. package/dist/cjs/components/button/classes.d.ts +11 -0
  10. package/dist/cjs/components/button/classes.js +2 -0
  11. package/dist/cjs/components/button/classes.js.map +1 -1
  12. package/dist/cjs/components/card/Card.d.ts +2 -2
  13. package/dist/cjs/components/dropdownMenu/DropdownMenu.js +2 -2
  14. package/dist/cjs/components/dropdownMenu/DropdownMenu.js.map +1 -1
  15. package/dist/cjs/components/note/Note.js +1 -1
  16. package/dist/cjs/components/note/Note.js.map +1 -1
  17. package/dist/cjs/components/note/Note.stories.d.ts +17 -0
  18. package/dist/cjs/components/note/Note.stories.js +18 -0
  19. package/dist/cjs/components/note/Note.stories.js.map +1 -0
  20. package/dist/cjs/components/tabs/tabs.d.ts +6 -2
  21. package/dist/cjs/components/tabs/tabs.js +27 -2
  22. package/dist/cjs/components/tabs/tabs.js.map +1 -1
  23. package/dist/cjs/components/tabs/tabs.stories.d.ts +8 -3
  24. package/dist/cjs/components/tabs/tabs.stories.js +9 -4
  25. package/dist/cjs/components/tabs/tabs.stories.js.map +1 -1
  26. package/dist/cjs/hooks/index.d.ts +5 -4
  27. package/dist/cjs/hooks/index.js +5 -4
  28. package/dist/cjs/hooks/index.js.map +1 -1
  29. package/dist/cjs/hooks/withProps.d.ts +2 -0
  30. package/dist/cjs/hooks/withProps.js +12 -0
  31. package/dist/cjs/hooks/withProps.js.map +1 -0
  32. package/dist/css/main.css +2 -2
  33. package/dist/esm/components/avatar/Avatar.js +3 -3
  34. package/dist/esm/components/avatar/Avatar.js.map +1 -1
  35. package/dist/esm/components/box/Box.d.ts +14 -7
  36. package/dist/esm/components/box/Box.js +51 -13
  37. package/dist/esm/components/box/Box.js.map +1 -1
  38. package/dist/esm/components/box/Box.stories.d.ts +3 -0
  39. package/dist/esm/components/box/Box.stories.js +3 -0
  40. package/dist/esm/components/box/Box.stories.js.map +1 -1
  41. package/dist/esm/components/button/classes.d.ts +11 -0
  42. package/dist/esm/components/button/classes.js +1 -0
  43. package/dist/esm/components/button/classes.js.map +1 -1
  44. package/dist/esm/components/card/Card.d.ts +2 -2
  45. package/dist/esm/components/dropdownMenu/DropdownMenu.js +2 -2
  46. package/dist/esm/components/dropdownMenu/DropdownMenu.js.map +1 -1
  47. package/dist/esm/components/note/Note.js +1 -1
  48. package/dist/esm/components/note/Note.js.map +1 -1
  49. package/dist/esm/components/note/Note.stories.d.ts +17 -0
  50. package/dist/esm/components/note/Note.stories.js +15 -0
  51. package/dist/esm/components/note/Note.stories.js.map +1 -0
  52. package/dist/esm/components/tabs/tabs.d.ts +6 -2
  53. package/dist/esm/components/tabs/tabs.js +22 -1
  54. package/dist/esm/components/tabs/tabs.js.map +1 -1
  55. package/dist/esm/components/tabs/tabs.stories.d.ts +8 -3
  56. package/dist/esm/components/tabs/tabs.stories.js +9 -4
  57. package/dist/esm/components/tabs/tabs.stories.js.map +1 -1
  58. package/dist/esm/hooks/index.d.ts +5 -4
  59. package/dist/esm/hooks/index.js +5 -4
  60. package/dist/esm/hooks/index.js.map +1 -1
  61. package/dist/esm/hooks/withProps.d.ts +2 -0
  62. package/dist/esm/hooks/withProps.js +8 -0
  63. package/dist/esm/hooks/withProps.js.map +1 -0
  64. package/package.json +1 -1
  65. package/src/components/avatar/Avatar.tsx +3 -3
  66. package/src/components/box/Box.stories.tsx +3 -0
  67. package/src/components/box/Box.tsx +90 -20
  68. package/src/components/button/classes.tsx +1 -0
  69. package/src/components/dropdownMenu/DropdownMenu.tsx +2 -2
  70. package/src/components/note/Note.stories.tsx +20 -0
  71. package/src/components/note/Note.tsx +16 -7
  72. package/src/components/tabs/tabs.stories.tsx +18 -7
  73. package/src/components/tabs/tabs.tsx +29 -3
  74. package/src/hooks/index.ts +5 -4
  75. package/src/hooks/withProps.tsx +10 -0
@@ -12,21 +12,40 @@ export type BoxJustification =
12
12
  | 'around'
13
13
  | 'end';
14
14
  export type BoxSpacingSize = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
15
+ export type BoxResponsive<T> =
16
+ | T
17
+ | {
18
+ default?: T;
19
+ sm?: T;
20
+ md?: T;
21
+ lg?: T;
22
+ };
23
+
24
+ function isResponsive<T>(
25
+ value: BoxResponsive<T>,
26
+ ): value is { sm?: T; md?: T; lg?: T } {
27
+ return typeof value === 'object';
28
+ }
29
+
30
+ function hasDefault<T>(value: BoxResponsive<T>, val: T) {
31
+ return value === val || (isResponsive(value) && value.default === val);
32
+ }
15
33
 
16
34
  export interface BoxProps extends Omit<SlotDivProps, 'wrap'> {
17
35
  className?: string;
18
- direction?: 'row' | 'col' | 'row-reverse' | 'col-reverse';
19
- d?: 'row' | 'col' | 'row-reverse' | 'col-reverse';
36
+ direction?: BoxResponsive<'row' | 'col' | 'row-reverse' | 'col-reverse'>;
37
+ d?: BoxResponsive<'row' | 'col' | 'row-reverse' | 'col-reverse'>;
20
38
  items?: BoxAlignment;
21
39
  justify?: BoxJustification;
22
- align?: `${BoxAlignment} ${BoxJustification}`;
23
- gap?: BoxSpacingSize;
24
- wrap?: boolean;
25
- p?: BoxSpacingSize;
40
+ layout?: `${BoxAlignment} ${BoxJustification}`;
41
+ gap?: BoxSpacingSize | boolean;
42
+ wrap?: BoxResponsive<boolean>;
43
+ p?: BoxResponsive<BoxSpacingSize | boolean>;
26
44
  container?: boolean;
27
45
  surface?: boolean | 'primary' | 'secondary';
28
46
  theme?: ThemeName;
29
47
  border?: boolean;
48
+ full?: boolean | 'width' | 'height';
30
49
  ref?: Ref<HTMLDivElement>;
31
50
  }
32
51
 
@@ -34,8 +53,8 @@ export function Box({
34
53
  className,
35
54
  items: itemsSolo,
36
55
  justify: justifySolo,
37
- align,
38
- gap = 'md',
56
+ layout: align,
57
+ gap = 'none',
39
58
  wrap,
40
59
  p = 'none',
41
60
  d = 'row',
@@ -45,6 +64,7 @@ export function Box({
45
64
  surface,
46
65
  theme,
47
66
  border,
67
+ full,
48
68
  ref,
49
69
  ...rest
50
70
  }: BoxProps) {
@@ -67,16 +87,49 @@ export function Box({
67
87
  {...rest}
68
88
  style={style}
69
89
  className={clsx(
70
- 'flex',
90
+ 'layer-components:flex layer-components:relative',
71
91
  {
72
- 'layer-components:flex-row': direction === 'row',
73
- 'layer-components:flex-col': direction === 'col',
74
- 'layer-components:flex-row-reverse': direction === 'row-reverse',
75
- 'layer-components:flex-col-reverse': direction === 'col-reverse',
76
- 'layer-components:flex-wrap': wrap,
92
+ 'layer-components:flex-row': hasDefault(direction, 'row'),
93
+ 'layer-components:flex-col': hasDefault(direction, 'col'),
94
+ 'layer-components:flex-row-reverse': hasDefault(
95
+ direction,
96
+ 'row-reverse',
97
+ ),
98
+ 'layer-components:flex-col-reverse': hasDefault(
99
+ direction,
100
+ 'col-reverse',
101
+ ),
102
+ 'layer-components:sm:flex-row':
103
+ isResponsive(direction) && direction.sm === 'row',
104
+ 'layer-components:sm:flex-col':
105
+ isResponsive(direction) && direction.sm === 'col',
106
+ 'layer-components:sm:flex-row-reverse':
107
+ isResponsive(direction) && direction.sm === 'row-reverse',
108
+ 'layer-components:sm:flex-col-reverse':
109
+ isResponsive(direction) && direction.sm === 'col-reverse',
110
+ 'layer-components:md:flex-row':
111
+ isResponsive(direction) && direction.md === 'row',
112
+ 'layer-components:md:flex-col':
113
+ isResponsive(direction) && direction.md === 'col',
114
+ 'layer-components:md:flex-row-reverse':
115
+ isResponsive(direction) && direction.md === 'row-reverse',
116
+ 'layer-components:md:flex-col-reverse':
117
+ isResponsive(direction) && direction.md === 'col-reverse',
118
+ 'layer-components:lg:flex-row':
119
+ isResponsive(direction) && direction.lg === 'row',
120
+ 'layer-components:lg:flex-col':
121
+ isResponsive(direction) && direction.lg === 'col',
122
+ 'layer-components:lg:flex-row-reverse':
123
+ isResponsive(direction) && direction.lg === 'row-reverse',
124
+ 'layer-components:lg:flex-col-reverse':
125
+ isResponsive(direction) && direction.lg === 'col-reverse',
126
+ 'layer-components:flex-wrap': hasDefault(wrap, true),
127
+ 'layer-components:sm:flex-wrap': isResponsive(wrap) && wrap.sm,
128
+ 'layer-components:md:flex-wrap': isResponsive(wrap) && wrap.md,
129
+ 'layer-components:lg:flex-wrap': isResponsive(wrap) && wrap.lg,
77
130
  'layer-components:gap-xs': gap === 'xs',
78
131
  'layer-components:gap-sm': gap === 'sm',
79
- 'layer-components:gap-md': gap === 'md',
132
+ 'layer-components:gap-md': gap === 'md' || gap === true,
80
133
  'layer-components:gap-lg': gap === 'lg',
81
134
  'layer-components:gap-xl': gap === 'xl',
82
135
  'layer-components:items-center': items === 'center',
@@ -89,11 +142,26 @@ export function Box({
89
142
  'layer-components:justify-end': justify === 'end',
90
143
  'layer-components:justify-between': justify === 'between',
91
144
  'layer-components:justify-around': justify === 'around',
92
- 'layer-components:p-xs': p === 'xs',
93
- 'layer-components:p-sm': p === 'sm',
94
- 'layer-components:p-md': p === 'md',
95
- 'layer-components:p-lg': p === 'lg',
96
- 'layer-components:p-xl': p === 'xl',
145
+ 'layer-components:p-xs': hasDefault(p, 'xs'),
146
+ 'layer-components:p-sm': hasDefault(p, 'sm'),
147
+ 'layer-components:p-md': hasDefault(p, 'md') || hasDefault(p, true),
148
+ 'layer-components:p-lg': hasDefault(p, 'lg'),
149
+ 'layer-components:p-xl': hasDefault(p, 'xl'),
150
+ 'layer-components:sm:p-xs': isResponsive(p) && p.sm === 'xs',
151
+ 'layer-components:sm:p-sm': isResponsive(p) && p.sm === 'sm',
152
+ 'layer-components:sm:p-md': isResponsive(p) && p.sm === 'md',
153
+ 'layer-components:sm:p-lg': isResponsive(p) && p.sm === 'lg',
154
+ 'layer-components:sm:p-xl': isResponsive(p) && p.sm === 'xl',
155
+ 'layer-components:md:p-xs': isResponsive(p) && p.md === 'xs',
156
+ 'layer-components:md:p-sm': isResponsive(p) && p.md === 'sm',
157
+ 'layer-components:md:p-md': isResponsive(p) && p.md === 'md',
158
+ 'layer-components:md:p-lg': isResponsive(p) && p.md === 'lg',
159
+ 'layer-components:md:p-xl': isResponsive(p) && p.md === 'xl',
160
+ 'layer-components:lg:p-xs': isResponsive(p) && p.lg === 'xs',
161
+ 'layer-components:lg:p-sm': isResponsive(p) && p.lg === 'sm',
162
+ 'layer-components:lg:p-md': isResponsive(p) && p.lg === 'md',
163
+ 'layer-components:lg:p-lg': isResponsive(p) && p.lg === 'lg',
164
+ 'layer-components:lg:p-xl': isResponsive(p) && p.lg === 'xl',
97
165
  'layer-components:rounded-lg': !!surface,
98
166
  'layer-components:(bg-white border-black)': surface === true,
99
167
  'layer-components:(bg-primary-wash border-primary-dark)':
@@ -101,6 +169,8 @@ export function Box({
101
169
  'layer-components:(bg-secondary-wash border-secondary-dark)':
102
170
  surface === 'secondary',
103
171
  'layer-components:(border border-solid rounded-lg)': border,
172
+ 'layer-components:w-full': full === true || full === 'width',
173
+ 'layer-components:h-full': full === true || full === 'height',
104
174
  },
105
175
  theme && `theme-${theme}`,
106
176
  className,
@@ -45,6 +45,7 @@ const colors = {
45
45
  contrast: `layer-variants:[&.btn-color-contrast]:([--bg:var(--color-black)] [--hover:var(--color-gray-7)] [--focus:var(--color-gray-7)] [--active:var(--color-gray-6)] color-white border-black)`,
46
46
  unstyled: `layer-variants:(bg-transparent hover:(bg-transparent) focus:(bg-transparent) active:(bg-transparent) color-inherit border-none shadow-none hover:(shadow-none) focus:(shadow-none) active:(shadow-none) p-0 items-start font-inherit font-normal rounded-none text-size-inherit transition-none)`,
47
47
  };
48
+ export const buttonColorClasses = colors;
48
49
 
49
50
  const sizes = {
50
51
  default: '',
@@ -6,7 +6,7 @@ import { withClassName } from '../../hooks/withClassName.js';
6
6
 
7
7
  const StyledContent = withClassName(
8
8
  DropdownMenuPrimitive.Content,
9
- 'min-w-220px bg-white z-menu shadow-lg rounded-xl border-default',
9
+ 'min-w-220px bg-white z-menu shadow-lg rounded-lg border-default',
10
10
  'layer-components:transform-origin-[var(--radix-dropdown-menu-transform-origin)]',
11
11
  'layer-components:[&[data-state=open]]:animate-popover-in',
12
12
  'layer-components:[&[data-state=closed]]:animate-popover-out',
@@ -15,7 +15,7 @@ const StyledContent = withClassName(
15
15
  'will-change-transform',
16
16
  );
17
17
  const itemClassName = classNames(
18
- 'layer-components:(text-md leading-4 color-black rounded-sm flex items-center pr-4 pl-8 py-3 relative text-left select-none cursor-pointer)',
18
+ 'layer-components:(text-md leading-4 color-black flex items-center pr-4 pl-8 py-2 relative text-left select-none cursor-pointer)',
19
19
  'layer-components:[&[data-disabled]]:(color-gray9 pointer-events-none)',
20
20
  'layer-components:focus-visible:(bg-gray2 color-gray9)',
21
21
  'layer-components:focus:outline-none',
@@ -0,0 +1,20 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Note } from './Note.js';
3
+
4
+ const meta = {
5
+ title: 'Note',
6
+ component: Note,
7
+
8
+ args: {
9
+ children: 'This is a note',
10
+ },
11
+ parameters: {
12
+ controls: { expanded: true },
13
+ },
14
+ } satisfies Meta<typeof Note>;
15
+
16
+ export default meta;
17
+
18
+ type Story = StoryObj<typeof Note>;
19
+
20
+ export const Default: Story = {};
@@ -7,13 +7,22 @@ export interface NoteProps extends HTMLAttributes<HTMLDivElement> {
7
7
 
8
8
  export function Note({ className, children, ...rest }: NoteProps) {
9
9
  return (
10
- <div className={classNames('pr-20px', className)} {...rest}>
11
- <div className="flex flex-col p-2 border border-solid border-primary-dark bg-primary-wash color-black relative text-sm italic border-r-0">
12
- {children}
13
- <div className="w-20px h-[calc(100%-18px)] absolute bottom--0.5px right--20px border-0 border-solid border-primary-dark border-r border-b bg-primary-wash">
14
- <div
15
- className={`absolute top--20px left-0 border0px border-0 border-solid border-transparent border-b-primary-dark border-l-primary-dark after:(content-[""] absolute top--7px left--9px border-8px border-solid border-transparent border-b-primary-wash border-l-primary-wash)`}
16
- />
10
+ <div className={classNames(className)} {...rest}>
11
+ <div className="flex flex-row ">
12
+ <div className="flex-1 p-2 border border-solid border-primary-dark bg-primary-wash color-black relative text-sm italic border-r-0">
13
+ {children}
14
+ </div>
15
+ <div
16
+ className="flex flex-col items-stretch justify-stretch flex-[0_0_20px]"
17
+ aria-hidden
18
+ >
19
+ <div className="border-0 border-solid border-primary-dark border-b-1px border-l-1px flex-[0_0_20px] w-[20px] h-[20px] relative">
20
+ <div className="absolute w-1px bg-primary-dark h-26px rotate--45 left-9px top--4px transform-origin-cc" />
21
+ <div
22
+ className={`border-solid box-content border-transparent border-r-primary-wash border-13px w-0 h-0 rotate--45 translate--7px transform-origin-br`}
23
+ />
24
+ </div>
25
+ <div className="bg-primary-wash flex-1 border-0 border-solid border-primary-dark border-r-1px border-b-1px" />
17
26
  </div>
18
27
  </div>
19
28
  </div>
@@ -1,10 +1,15 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
- import { TabsRoot, TabsList, TabsContent, TabsTrigger } from './tabs.js';
3
2
  import { useState } from 'react';
3
+ import { TabsContent, TabsList, TabsRoot, TabsTrigger } from './tabs.js';
4
4
 
5
5
  const meta = {
6
6
  title: 'Tabs',
7
- argTypes: {},
7
+ argTypes: {
8
+ color: {
9
+ control: 'select',
10
+ options: ['default', 'primary'],
11
+ },
12
+ },
8
13
  parameters: {
9
14
  controls: { expanded: true },
10
15
  },
@@ -12,17 +17,23 @@ const meta = {
12
17
 
13
18
  export default meta;
14
19
 
15
- type Story = StoryObj;
20
+ type Story = StoryObj<Meta>;
16
21
 
17
22
  export const Default: Story = {
18
- render: () => {
23
+ render: (args) => {
19
24
  const [value, setValue] = useState('tab1');
20
25
  return (
21
26
  <TabsRoot value={value} onValueChange={setValue}>
22
27
  <TabsList>
23
- <TabsTrigger value="tab1">Tab 1</TabsTrigger>
24
- <TabsTrigger value="tab2">Tab 2 (long)</TabsTrigger>
25
- <TabsTrigger value="tab3">Tab 3</TabsTrigger>
28
+ <TabsTrigger value="tab1" color={args.color}>
29
+ Tab 1
30
+ </TabsTrigger>
31
+ <TabsTrigger value="tab2" color={args.color}>
32
+ Tab 2 (long)
33
+ </TabsTrigger>
34
+ <TabsTrigger value="tab3" color={args.color}>
35
+ Tab 3
36
+ </TabsTrigger>
26
37
  </TabsList>
27
38
  <TabsContent value="tab1">
28
39
  <div>Tab 1 content</div>
@@ -1,4 +1,5 @@
1
1
  import * as TabsPrimitive from '@radix-ui/react-tabs';
2
+ import clsx from 'clsx';
2
3
  import { withClassName } from '../../hooks/withClassName.js';
3
4
 
4
5
  export const TabsRoot = withClassName(TabsPrimitive.Root, '');
@@ -8,10 +9,35 @@ export const TabsList = withClassName(
8
9
  'flex flex-row flex-wrap py-2 px-2 items-start gap-2',
9
10
  );
10
11
 
11
- export const TabsTrigger = withClassName(
12
+ export const TabsTriggerBase = withClassName(
12
13
  TabsPrimitive.Trigger,
13
- 'layer-components:(flex flex-row items-center justify-center gap-2 color-black py-1 px-5 bg-wash text-md min-w-100px rounded-lg border border font-semibold text-gray-7 border-gray-7 border-solid transition-colors cursor-pointer select-none font-sans flex-shrink-0)',
14
- 'hover:bg-primary-light focus-visible:(focus-ring focus-ring-primary-dark outline-off bg-primary-light border-primary-dark) [&[data-state=active]]:(font-semibold bg-primary-light border-primary-light text-black cursor-default hover:bg-primary-light relative z-1)',
14
+ 'layer-components:(flex flex-row items-center justify-center gap-2 color-black py-1 px-5 bg-wash text-md min-w-100px rounded-lg border-default font-semibold text-gray-8 border-gray-8 transition-colors cursor-pointer select-none font-sans flex-shrink-0 shadow-sm)',
15
+ 'layer-components:hover:bg-[var(--hover)]',
16
+ 'layer-components:focus-visible:(focus-ring focus-ring-[var(--focus)] outline-off)',
17
+ '[&[data-state=active]]:(font-semibold bg-[var(--focus,var(--hover))] text-black cursor-default hover:bg-[var(--hover)] relative z-1)',
18
+ );
19
+
20
+ const colorClasses = {
21
+ default:
22
+ 'layer-variants:([--bg:var(--color-white)] [--hover:var(--color-gray-3)] [--focus:var(--color-gray-4)] [--active:var(--color-gray-4)])',
23
+ primary:
24
+ 'layer-variants:([--bg:var(--color-primary-light)] [--hover:var(--color-primary)] [--focus:var(--color-primary)] [--active:var(--color-primary)])',
25
+ };
26
+
27
+ export interface TabsTriggerProps
28
+ extends Omit<TabsPrimitive.TabsTriggerProps, 'color'> {
29
+ color?: 'default' | 'primary';
30
+ }
31
+
32
+ export const TabsTrigger = ({
33
+ className,
34
+ color = 'primary',
35
+ ...props
36
+ }: TabsTriggerProps) => (
37
+ <TabsTriggerBase
38
+ className={clsx(colorClasses[color], `btn-color-${color}`, className)}
39
+ {...props}
40
+ />
15
41
  );
16
42
 
17
43
  export const TabsContent = withClassName(TabsPrimitive.Content, '');
@@ -1,10 +1,11 @@
1
+ export * from './useAnimationFrame.js';
2
+ export * from './useLongPress.js';
1
3
  export * from './useMergedRef.js';
4
+ export * from './useOnUnmount.js';
2
5
  export * from './useSize.js';
3
6
  export * from './useStableCallback.js';
7
+ export * from './useTitleBarColor.js';
4
8
  export * from './useToggle.js';
5
9
  export * from './useVisualViewportOffset.js';
6
- export * from './useOnUnmount.js';
7
10
  export * from './withClassName.js';
8
- export * from './useAnimationFrame.js';
9
- export * from './useLongPress.js';
10
- export * from './useTitleBarColor.js';
11
+ export * from './withProps.js';
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+
3
+ export const withProps = <T extends {}, Extras extends {}>(
4
+ Component: React.ComponentType<T & Extras>,
5
+ extras: Extras,
6
+ ) => {
7
+ return (props: T & Extras) => {
8
+ return <Component {...props} {...extras} />;
9
+ };
10
+ };