atelier-ui-react 1.0.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/dist/index.cjs +909 -0
  4. package/dist/index.css +962 -0
  5. package/dist/index.mjs +876 -0
  6. package/package.json +52 -0
  7. package/src/Button/Button.css +169 -0
  8. package/src/Button/Button.tsx +57 -0
  9. package/src/Button/Button.types.ts +19 -0
  10. package/src/Button/index.ts +2 -0
  11. package/src/Card/Card.css +73 -0
  12. package/src/Card/Card.tsx +79 -0
  13. package/src/Card/Card.types.ts +25 -0
  14. package/src/Card/index.ts +2 -0
  15. package/src/Checkbox/Checkbox.css +101 -0
  16. package/src/Checkbox/Checkbox.tsx +85 -0
  17. package/src/Checkbox/Checkbox.types.ts +9 -0
  18. package/src/Checkbox/index.ts +2 -0
  19. package/src/Divider/Divider.css +47 -0
  20. package/src/Divider/Divider.tsx +53 -0
  21. package/src/Divider/Divider.types.ts +12 -0
  22. package/src/Divider/index.ts +2 -0
  23. package/src/Heading/Heading.css +30 -0
  24. package/src/Heading/Heading.tsx +50 -0
  25. package/src/Heading/Heading.types.ts +16 -0
  26. package/src/Heading/index.ts +2 -0
  27. package/src/Icon/Icon.css +26 -0
  28. package/src/Icon/Icon.tsx +79 -0
  29. package/src/Icon/Icon.types.ts +13 -0
  30. package/src/Icon/index.ts +2 -0
  31. package/src/Input/Input.css +145 -0
  32. package/src/Input/Input.tsx +86 -0
  33. package/src/Input/Input.types.ts +15 -0
  34. package/src/Input/index.ts +2 -0
  35. package/src/Link/Link.css +50 -0
  36. package/src/Link/Link.tsx +64 -0
  37. package/src/Link/Link.types.ts +13 -0
  38. package/src/Link/index.ts +2 -0
  39. package/src/Select/Select.css +115 -0
  40. package/src/Select/Select.tsx +109 -0
  41. package/src/Select/Select.types.ts +19 -0
  42. package/src/Select/index.ts +2 -0
  43. package/src/Text/Text.css +49 -0
  44. package/src/Text/Text.tsx +46 -0
  45. package/src/Text/Text.types.ts +19 -0
  46. package/src/Text/index.ts +2 -0
  47. package/src/index.ts +34 -0
  48. package/src/layout/Container/Container.css +16 -0
  49. package/src/layout/Container/Container.tsx +51 -0
  50. package/src/layout/Container/Container.types.ts +12 -0
  51. package/src/layout/Container/index.ts +2 -0
  52. package/src/layout/Flex/Flex.css +34 -0
  53. package/src/layout/Flex/Flex.tsx +56 -0
  54. package/src/layout/Flex/Flex.types.ts +18 -0
  55. package/src/layout/Flex/index.ts +2 -0
  56. package/src/layout/Grid/Grid.css +18 -0
  57. package/src/layout/Grid/Grid.tsx +61 -0
  58. package/src/layout/Grid/Grid.types.ts +17 -0
  59. package/src/layout/Grid/index.ts +2 -0
  60. package/src/layout/Stack/Stack.css +50 -0
  61. package/src/layout/Stack/Stack.tsx +70 -0
  62. package/src/layout/Stack/Stack.types.ts +17 -0
  63. package/src/layout/Stack/index.ts +2 -0
  64. package/src/styles/globals.css +28 -0
  65. package/src/styles/reset.css +44 -0
  66. package/src/theme/ThemeProvider.tsx +83 -0
  67. package/src/theme/dark.css +62 -0
  68. package/src/theme/index.ts +2 -0
  69. package/src/theme/light.css +62 -0
  70. package/src/theme/theme.types.ts +19 -0
  71. package/src/theme/tokens.css +61 -0
  72. package/src/utils/index.ts +44 -0
@@ -0,0 +1,47 @@
1
+ .ui-divider {
2
+ display: flex;
3
+ align-items: center;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ .ui-divider--horizontal {
8
+ width: 100%;
9
+ flex-direction: row;
10
+ }
11
+
12
+ .ui-divider--vertical {
13
+ height: 100%;
14
+ min-height: 1em;
15
+ flex-direction: column;
16
+ }
17
+
18
+ .ui-divider__line {
19
+ flex-grow: 1;
20
+ background-color: var(--ui-color-border);
21
+ }
22
+
23
+ .ui-divider--horizontal .ui-divider__line {
24
+ height: 1px;
25
+ }
26
+
27
+ .ui-divider--vertical .ui-divider__line {
28
+ width: 1px;
29
+ }
30
+
31
+ .ui-divider__content {
32
+ padding: 0 var(--ui-space-sm);
33
+ font-size: var(--ui-font-size-xs);
34
+ color: var(--ui-color-foreground-muted);
35
+ font-weight: var(--ui-font-weight-medium);
36
+ white-space: nowrap;
37
+ }
38
+
39
+ .ui-divider--align-left .ui-divider__line:first-child {
40
+ flex-grow: 0;
41
+ width: var(--ui-space-lg);
42
+ }
43
+
44
+ .ui-divider--align-right .ui-divider__line:last-child {
45
+ flex-grow: 0;
46
+ width: var(--ui-space-lg);
47
+ }
@@ -0,0 +1,53 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { DividerProps } from './Divider.types';
3
+ import { cx, getSpaceValue } from '../utils';
4
+ import './Divider.css';
5
+
6
+ export const Divider = forwardRef<HTMLDivElement, DividerProps>(function Divider(
7
+ {
8
+ orientation = 'horizontal',
9
+ spacing = 'md',
10
+ label,
11
+ align = 'center',
12
+ className,
13
+ style,
14
+ children,
15
+ ...rest
16
+ },
17
+ ref
18
+ ) {
19
+ const content = label || children;
20
+ const spacingVal = getSpaceValue(spacing);
21
+
22
+ const classes = cx(
23
+ 'ui-divider',
24
+ `ui-divider--${orientation}`,
25
+ content && `ui-divider--align-${align}`,
26
+ className
27
+ );
28
+
29
+ const combinedStyle: React.CSSProperties = {
30
+ marginTop: orientation === 'horizontal' ? spacingVal : undefined,
31
+ marginBottom: orientation === 'horizontal' ? spacingVal : undefined,
32
+ marginLeft: orientation === 'vertical' ? spacingVal : undefined,
33
+ marginRight: orientation === 'vertical' ? spacingVal : undefined,
34
+ ...style,
35
+ };
36
+
37
+ return (
38
+ <div
39
+ ref={ref}
40
+ role="separator"
41
+ aria-orientation={orientation}
42
+ className={classes}
43
+ style={combinedStyle}
44
+ {...rest}
45
+ >
46
+ <div className="ui-divider__line" />
47
+ {content && <span className="ui-divider__content">{content}</span>}
48
+ {content && <div className="ui-divider__line" />}
49
+ </div>
50
+ );
51
+ });
52
+
53
+ Divider.displayName = 'Divider';
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import type { SpaceToken } from '../utils';
3
+
4
+ export type DividerOrientation = 'horizontal' | 'vertical';
5
+
6
+ export interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {
7
+ orientation?: DividerOrientation;
8
+ spacing?: SpaceToken;
9
+ label?: React.ReactNode;
10
+ align?: 'left' | 'center' | 'right';
11
+ children?: React.ReactNode;
12
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Divider';
2
+ export * from './Divider.types';
@@ -0,0 +1,30 @@
1
+ .ui-heading {
2
+ margin: 0;
3
+ padding: 0;
4
+ font-family: var(--ui-font-sans);
5
+ color: var(--ui-color-foreground);
6
+ line-height: var(--ui-line-height-tight);
7
+ letter-spacing: -0.02em;
8
+ font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
9
+ }
10
+
11
+ /* Heading Sizes */
12
+ .ui-heading--size-xs { font-size: var(--ui-font-size-sm); }
13
+ .ui-heading--size-sm { font-size: var(--ui-font-size-md); }
14
+ .ui-heading--size-md { font-size: var(--ui-font-size-lg); }
15
+ .ui-heading--size-lg { font-size: var(--ui-font-size-xl); }
16
+ .ui-heading--size-xl { font-size: var(--ui-font-size-2xl); }
17
+ .ui-heading--size-2xl { font-size: var(--ui-font-size-3xl); }
18
+ .ui-heading--size-3xl { font-size: var(--ui-font-size-4xl); }
19
+ .ui-heading--size-4xl { font-size: 2.75rem; letter-spacing: -0.03em; }
20
+
21
+ /* Heading Weights */
22
+ .ui-heading--weight-normal { font-weight: var(--ui-font-weight-normal); }
23
+ .ui-heading--weight-medium { font-weight: var(--ui-font-weight-medium); }
24
+ .ui-heading--weight-semibold { font-weight: var(--ui-font-weight-semibold); }
25
+ .ui-heading--weight-bold { font-weight: var(--ui-font-weight-bold); }
26
+
27
+ /* Alignments */
28
+ .ui-heading--align-left { text-align: left; }
29
+ .ui-heading--align-center { text-align: center; }
30
+ .ui-heading--align-right { text-align: right; }
@@ -0,0 +1,50 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { HeadingProps, HeadingSize } from './Heading.types';
3
+ import { cx } from '../utils';
4
+ import './Heading.css';
5
+
6
+ const defaultLevelSizeMap: Record<number, HeadingSize> = {
7
+ 1: '3xl',
8
+ 2: '2xl',
9
+ 3: 'xl',
10
+ 4: 'lg',
11
+ 5: 'md',
12
+ 6: 'sm',
13
+ };
14
+
15
+ export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(function Heading(
16
+ {
17
+ level = 2,
18
+ as,
19
+ size,
20
+ weight = 'semibold',
21
+ align,
22
+ className,
23
+ children,
24
+ ...rest
25
+ },
26
+ ref
27
+ ) {
28
+ const Component = as || (`h${level}` as const);
29
+ const resolvedSize = size || defaultLevelSizeMap[level] || 'xl';
30
+
31
+ const classes = cx(
32
+ 'ui-heading',
33
+ `ui-heading--size-${resolvedSize}`,
34
+ `ui-heading--weight-${weight}`,
35
+ align && `ui-heading--align-${align}`,
36
+ className
37
+ );
38
+
39
+ return React.createElement(
40
+ Component,
41
+ {
42
+ ref,
43
+ className: classes,
44
+ ...rest,
45
+ },
46
+ children
47
+ );
48
+ });
49
+
50
+ Heading.displayName = 'Heading';
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+
3
+ export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
4
+ export type HeadingElement = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'div';
5
+ export type HeadingSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
6
+ export type HeadingWeight = 'normal' | 'medium' | 'semibold' | 'bold';
7
+ export type HeadingAlign = 'left' | 'center' | 'right';
8
+
9
+ export interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
10
+ level?: HeadingLevel;
11
+ as?: HeadingElement;
12
+ size?: HeadingSize;
13
+ weight?: HeadingWeight;
14
+ align?: HeadingAlign;
15
+ children?: React.ReactNode;
16
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Heading';
2
+ export * from './Heading.types';
@@ -0,0 +1,26 @@
1
+ .ui-icon {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ vertical-align: middle;
6
+ flex-shrink: 0;
7
+ line-height: 1;
8
+ }
9
+
10
+ .ui-icon svg {
11
+ width: 100%;
12
+ height: 100%;
13
+ }
14
+
15
+ .ui-icon--spin {
16
+ animation: ui-spin 1s linear infinite;
17
+ }
18
+
19
+ @keyframes ui-spin {
20
+ from {
21
+ transform: rotate(0deg);
22
+ }
23
+ to {
24
+ transform: rotate(360deg);
25
+ }
26
+ }
@@ -0,0 +1,79 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { IconProps, IconSize } from './Icon.types';
3
+ import { cx } from '../utils';
4
+ import './Icon.css';
5
+
6
+ const sizeMap: Record<string, number> = {
7
+ xs: 14,
8
+ sm: 16,
9
+ md: 20,
10
+ lg: 24,
11
+ xl: 32,
12
+ };
13
+
14
+ export const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(
15
+ {
16
+ icon: Component,
17
+ size = 'md',
18
+ color = 'inherit',
19
+ spin = false,
20
+ className,
21
+ style,
22
+ children,
23
+ ...rest
24
+ },
25
+ ref
26
+ ) {
27
+ const pixelSize = typeof size === 'number' ? size : sizeMap[size] || 20;
28
+
29
+ let resolvedColor = color;
30
+ const tokenColors: Record<string, string> = {
31
+ default: 'var(--ui-color-foreground)',
32
+ muted: 'var(--ui-color-foreground-muted)',
33
+ subtle: 'var(--ui-color-foreground-subtle)',
34
+ primary: 'var(--ui-color-primary)',
35
+ success: 'var(--ui-color-success)',
36
+ warning: 'var(--ui-color-warning)',
37
+ danger: 'var(--ui-color-danger)',
38
+ inherit: 'currentColor',
39
+ };
40
+
41
+ if (tokenColors[color]) {
42
+ resolvedColor = tokenColors[color];
43
+ }
44
+
45
+ const classes = cx(
46
+ 'ui-icon',
47
+ spin && 'ui-icon--spin',
48
+ className
49
+ );
50
+
51
+ const combinedStyle: React.CSSProperties = {
52
+ width: `${pixelSize}px`,
53
+ height: `${pixelSize}px`,
54
+ color: resolvedColor,
55
+ ...style,
56
+ };
57
+
58
+ if (Component) {
59
+ return (
60
+ <span className={classes} style={combinedStyle}>
61
+ <Component
62
+ ref={ref}
63
+ width={pixelSize}
64
+ height={pixelSize}
65
+ aria-hidden="true"
66
+ {...rest}
67
+ />
68
+ </span>
69
+ );
70
+ }
71
+
72
+ return (
73
+ <span className={classes} style={combinedStyle} aria-hidden="true">
74
+ {children}
75
+ </span>
76
+ );
77
+ });
78
+
79
+ Icon.displayName = 'Icon';
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ export type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
4
+ export type IconColor = 'default' | 'muted' | 'subtle' | 'primary' | 'success' | 'warning' | 'danger' | 'inherit' | string;
5
+
6
+ export interface IconProps extends React.SVGAttributes<SVGElement> {
7
+ icon?: React.ElementType;
8
+ size?: IconSize;
9
+ color?: IconColor;
10
+ spin?: boolean;
11
+ className?: string;
12
+ children?: React.ReactNode;
13
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Icon';
2
+ export * from './Icon.types';
@@ -0,0 +1,145 @@
1
+ .ui-input-wrapper {
2
+ display: inline-flex;
3
+ flex-direction: column;
4
+ gap: var(--ui-space-2xs);
5
+ box-sizing: border-box;
6
+ font-family: var(--ui-font-sans);
7
+ }
8
+
9
+ .ui-input-wrapper--full-width {
10
+ width: 100%;
11
+ }
12
+
13
+ /* Label */
14
+ .ui-input-label {
15
+ font-size: var(--ui-font-size-xs);
16
+ font-weight: var(--ui-font-weight-medium);
17
+ color: var(--ui-color-foreground);
18
+ user-select: none;
19
+ }
20
+
21
+ .ui-input-label--disabled {
22
+ color: var(--ui-color-foreground-muted);
23
+ }
24
+
25
+ /* Inner input container (with icons) */
26
+ .ui-input-container {
27
+ position: relative;
28
+ display: flex;
29
+ align-items: center;
30
+ width: 100%;
31
+ border-radius: var(--ui-radius-md);
32
+ transition: border-color var(--ui-transition-fast), box-shadow var(--ui-transition-fast);
33
+ }
34
+
35
+ /* Base input field */
36
+ .ui-input {
37
+ width: 100%;
38
+ font-family: var(--ui-font-sans);
39
+ color: var(--ui-color-foreground);
40
+ background-color: var(--ui-color-surface);
41
+ border: 1px solid var(--ui-color-border);
42
+ border-radius: var(--ui-radius-md);
43
+ outline: none;
44
+ transition:
45
+ border-color var(--ui-transition-fast),
46
+ box-shadow var(--ui-transition-fast),
47
+ background-color var(--ui-transition-fast);
48
+ }
49
+
50
+ .ui-input::placeholder {
51
+ color: var(--ui-color-foreground-subtle);
52
+ }
53
+
54
+ /* Focus state */
55
+ .ui-input:focus {
56
+ border-color: var(--ui-color-focus-border);
57
+ box-shadow: 0 0 0 var(--ui-focus-ring-width) var(--ui-color-focus-ring);
58
+ }
59
+
60
+ /* Sizes */
61
+ .ui-input--size-sm {
62
+ height: 32px;
63
+ padding: 0 10px;
64
+ font-size: var(--ui-font-size-xs);
65
+ border-radius: var(--ui-radius-sm);
66
+ }
67
+
68
+ .ui-input--size-md {
69
+ height: 40px;
70
+ padding: 0 12px;
71
+ font-size: var(--ui-font-size-sm);
72
+ border-radius: var(--ui-radius-md);
73
+ }
74
+
75
+ .ui-input--size-lg {
76
+ height: 48px;
77
+ padding: 0 16px;
78
+ font-size: var(--ui-font-size-md);
79
+ border-radius: var(--ui-radius-md);
80
+ }
81
+
82
+ /* Variants */
83
+ .ui-input--variant-filled {
84
+ background-color: var(--ui-color-surface-inset);
85
+ border-color: transparent;
86
+ }
87
+
88
+ .ui-input--variant-filled:focus {
89
+ background-color: var(--ui-color-surface);
90
+ border-color: var(--ui-color-focus-border);
91
+ }
92
+
93
+ /* Padding adjustments for icons */
94
+ .ui-input--has-left-icon.ui-input--size-sm { padding-left: 30px; }
95
+ .ui-input--has-left-icon.ui-input--size-md { padding-left: 36px; }
96
+ .ui-input--has-left-icon.ui-input--size-lg { padding-left: 42px; }
97
+
98
+ .ui-input--has-right-icon.ui-input--size-sm { padding-right: 30px; }
99
+ .ui-input--has-right-icon.ui-input--size-md { padding-right: 36px; }
100
+ .ui-input--has-right-icon.ui-input--size-lg { padding-right: 42px; }
101
+
102
+ /* Icons */
103
+ .ui-input__icon {
104
+ position: absolute;
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ color: var(--ui-color-foreground-muted);
109
+ pointer-events: none;
110
+ }
111
+
112
+ .ui-input__icon--left {
113
+ left: 10px;
114
+ }
115
+
116
+ .ui-input__icon--right {
117
+ right: 10px;
118
+ }
119
+
120
+ /* States */
121
+ .ui-input:disabled {
122
+ background-color: var(--ui-color-surface-inset);
123
+ color: var(--ui-color-foreground-muted);
124
+ border-color: var(--ui-color-border-subtle);
125
+ cursor: not-allowed;
126
+ opacity: 0.7;
127
+ }
128
+
129
+ .ui-input--error,
130
+ .ui-input--error:focus {
131
+ border-color: var(--ui-color-danger);
132
+ box-shadow: 0 0 0 var(--ui-focus-ring-width) rgba(220, 38, 38, 0.2);
133
+ }
134
+
135
+ /* Helper / Error text */
136
+ .ui-input-helper {
137
+ font-size: var(--ui-font-size-xs);
138
+ color: var(--ui-color-foreground-muted);
139
+ line-height: 1.4;
140
+ }
141
+
142
+ .ui-input-helper--error {
143
+ color: var(--ui-color-danger);
144
+ font-weight: var(--ui-font-weight-medium);
145
+ }
@@ -0,0 +1,86 @@
1
+ import React, { forwardRef, useId } from 'react';
2
+ import type { InputProps } from './Input.types';
3
+ import { cx } from '../utils';
4
+ import './Input.css';
5
+
6
+ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
7
+ {
8
+ size = 'md',
9
+ variant = 'default',
10
+ label,
11
+ helperText,
12
+ error,
13
+ leftIcon,
14
+ rightIcon,
15
+ fullWidth = false,
16
+ disabled = false,
17
+ id: explicitId,
18
+ className,
19
+ ...rest
20
+ },
21
+ ref
22
+ ) {
23
+ const generatedId = useId();
24
+ const id = explicitId || generatedId;
25
+ const helperId = `${id}-helper`;
26
+ const hasError = Boolean(error);
27
+ const errorMessage = typeof error === 'string' ? error : undefined;
28
+
29
+ const isReadOnly = rest.readOnly !== undefined ? rest.readOnly : (rest.value !== undefined && !rest.onChange ? true : undefined);
30
+
31
+ const wrapperClasses = cx(
32
+ 'ui-input-wrapper',
33
+ fullWidth && 'ui-input-wrapper--full-width'
34
+ );
35
+
36
+ const inputClasses = cx(
37
+ 'ui-input',
38
+ `ui-input--size-${size}`,
39
+ `ui-input--variant-${variant}`,
40
+ leftIcon && 'ui-input--has-left-icon',
41
+ rightIcon && 'ui-input--has-right-icon',
42
+ hasError && 'ui-input--error',
43
+ className
44
+ );
45
+
46
+ return (
47
+ <div className={wrapperClasses}>
48
+ {label && (
49
+ <label
50
+ htmlFor={id}
51
+ className={cx('ui-input-label', disabled && 'ui-input-label--disabled')}
52
+ >
53
+ {label}
54
+ </label>
55
+ )}
56
+
57
+ <div className="ui-input-container">
58
+ {leftIcon && <span className="ui-input__icon ui-input__icon--left">{leftIcon}</span>}
59
+
60
+ <input
61
+ ref={ref}
62
+ id={id}
63
+ disabled={disabled}
64
+ readOnly={isReadOnly}
65
+ aria-invalid={hasError}
66
+ aria-describedby={helperText || errorMessage ? helperId : undefined}
67
+ className={inputClasses}
68
+ {...rest}
69
+ />
70
+
71
+ {rightIcon && <span className="ui-input__icon ui-input__icon--right">{rightIcon}</span>}
72
+ </div>
73
+
74
+ {(errorMessage || helperText) && (
75
+ <span
76
+ id={helperId}
77
+ className={cx('ui-input-helper', hasError && 'ui-input-helper--error')}
78
+ >
79
+ {errorMessage || helperText}
80
+ </span>
81
+ )}
82
+ </div>
83
+ );
84
+ });
85
+
86
+ Input.displayName = 'Input';
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+
3
+ export type InputSize = 'sm' | 'md' | 'lg';
4
+ export type InputVariant = 'default' | 'filled';
5
+
6
+ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
7
+ size?: InputSize;
8
+ variant?: InputVariant;
9
+ label?: React.ReactNode;
10
+ helperText?: React.ReactNode;
11
+ error?: string | boolean;
12
+ leftIcon?: React.ReactNode;
13
+ rightIcon?: React.ReactNode;
14
+ fullWidth?: boolean;
15
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Input';
2
+ export * from './Input.types';
@@ -0,0 +1,50 @@
1
+ .ui-link {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 4px;
5
+ font-family: var(--ui-font-sans);
6
+ font-weight: var(--ui-font-weight-medium);
7
+ cursor: pointer;
8
+ text-decoration: none;
9
+ transition: color var(--ui-transition-fast), text-decoration-color var(--ui-transition-fast);
10
+ border-radius: var(--ui-radius-sm);
11
+ }
12
+
13
+ .ui-link:focus-visible {
14
+ outline: var(--ui-focus-ring-width) solid var(--ui-color-focus-ring);
15
+ outline-offset: var(--ui-focus-ring-offset);
16
+ }
17
+
18
+ /* Sizes */
19
+ .ui-link--size-sm { font-size: var(--ui-font-size-xs); }
20
+ .ui-link--size-md { font-size: var(--ui-font-size-sm); }
21
+ .ui-link--size-lg { font-size: var(--ui-font-size-md); }
22
+
23
+ /* Variants */
24
+ .ui-link--variant-default {
25
+ color: var(--ui-color-accent);
26
+ }
27
+
28
+ .ui-link--variant-default:hover {
29
+ color: var(--ui-color-accent-hover);
30
+ text-decoration: underline;
31
+ text-underline-offset: 3px;
32
+ }
33
+
34
+ .ui-link--variant-subtle {
35
+ color: var(--ui-color-foreground-muted);
36
+ }
37
+
38
+ .ui-link--variant-subtle:hover {
39
+ color: var(--ui-color-foreground);
40
+ }
41
+
42
+ .ui-link--variant-underline {
43
+ color: var(--ui-color-foreground);
44
+ text-decoration: underline;
45
+ text-underline-offset: 3px;
46
+ }
47
+
48
+ .ui-link--variant-underline:hover {
49
+ color: var(--ui-color-accent);
50
+ }