@attrus-ds/core 0.1.1 → 0.2.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.
Files changed (55) hide show
  1. package/README.md +63 -9
  2. package/dist/css/components/buttons.css +1 -1
  3. package/dist/css/components/combobox.css +17 -1
  4. package/dist/css/components/inputs.css +3 -55
  5. package/dist/css/components/overlays.css +28 -59
  6. package/dist/css/components/primitives.css +10 -1
  7. package/dist/css/components/sidebar.css +3 -3
  8. package/dist/css/components/smart-search.css +91 -0
  9. package/dist/css/components/table.css +10 -8
  10. package/dist/css/components/tabs.css +2 -2
  11. package/dist/css/components/toast.css +4 -0
  12. package/dist/css/components/tooltip.css +5 -0
  13. package/dist/css/index.css +1 -0
  14. package/dist/react/AppSidebar/AppSidebar.d.ts +50 -0
  15. package/dist/react/AppSidebar/AppSidebar.tsx +197 -0
  16. package/dist/react/AppTopbar/AppTopbar.d.ts +58 -0
  17. package/dist/react/AppTopbar/AppTopbar.tsx +203 -0
  18. package/dist/react/Atoms/Atoms.d.ts +149 -0
  19. package/dist/react/Atoms/Atoms.tsx +407 -0
  20. package/dist/react/Button/Button.d.ts +25 -0
  21. package/dist/react/Button/Button.tsx +83 -0
  22. package/dist/react/Callout/Callout.d.ts +29 -0
  23. package/dist/react/Callout/Callout.tsx +98 -0
  24. package/dist/react/Card/Card.d.ts +38 -0
  25. package/dist/react/Card/Card.tsx +93 -0
  26. package/dist/react/Combobox/Combobox.d.ts +52 -0
  27. package/dist/react/Combobox/Combobox.tsx +254 -0
  28. package/dist/react/DataTable/DataTable.d.ts +81 -0
  29. package/dist/react/DataTable/DataTable.tsx +308 -0
  30. package/dist/react/Drawer/Drawer.d.ts +35 -0
  31. package/dist/react/Drawer/Drawer.tsx +226 -0
  32. package/dist/react/Input/Input.d.ts +155 -0
  33. package/dist/react/Input/Input.tsx +478 -0
  34. package/dist/react/Modal/Modal.d.ts +27 -0
  35. package/dist/react/Modal/Modal.tsx +173 -0
  36. package/dist/react/NumberInput/NumberInput.d.ts +25 -0
  37. package/dist/react/NumberInput/NumberInput.tsx +117 -0
  38. package/dist/react/Pill/Pill.d.ts +31 -0
  39. package/dist/react/Pill/Pill.tsx +104 -0
  40. package/dist/react/SearchPill/SearchPill.d.ts +14 -0
  41. package/dist/react/SearchPill/SearchPill.tsx +40 -0
  42. package/dist/react/SmartSearch/SmartSearch.d.ts +65 -0
  43. package/dist/react/SmartSearch/SmartSearch.tsx +271 -0
  44. package/dist/react/Stepper/Stepper.d.ts +25 -0
  45. package/dist/react/Stepper/Stepper.tsx +94 -0
  46. package/dist/react/Tabs/Tabs.d.ts +32 -0
  47. package/dist/react/Tabs/Tabs.tsx +147 -0
  48. package/dist/react/Toast/Toast.d.ts +30 -0
  49. package/dist/react/Toast/Toast.tsx +94 -0
  50. package/dist/react/Tooltip/Tooltip.d.ts +23 -0
  51. package/dist/react/Tooltip/Tooltip.tsx +80 -0
  52. package/dist/react/ZeroState/ZeroState.d.ts +17 -0
  53. package/dist/react/ZeroState/ZeroState.tsx +45 -0
  54. package/dist/react/index.ts +35 -0
  55. package/package.json +12 -2
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * ATTRUS Toast — typed wrapper over the canonical `.toast` system
5
+ * (preview/components/toast.css). Ephemeral feedback: glassy surface,
6
+ * tone accent rule, optional action link, close button and auto-dismiss
7
+ * progress hairline. Compose inside a <ToastStack/> for positioning.
8
+ */
9
+
10
+ export type ToastTone = 'success' | 'warning' | 'danger' | 'info' | 'brand' | 'inverse';
11
+ export type ToastStackPosition = 'tr' | 'tl' | 'tc' | 'br' | 'bl' | 'bc';
12
+
13
+ export interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {
14
+ tone?: ToastTone;
15
+ /** Leading icon slot (.toast-icon). */
16
+ icon?: React.ReactNode;
17
+ /** Bold first line. */
18
+ title?: React.ReactNode;
19
+ /** Inline action link (.toast-action). */
20
+ action?: React.ReactNode;
21
+ onActionClick?: () => void;
22
+ /** Renders the × and calls back. */
23
+ onClose?: () => void;
24
+ /** Auto-dismiss countdown hairline (.toast-progress). */
25
+ progress?: boolean;
26
+ /** Exit animation hook (.is-leaving) — set just before removal. */
27
+ leaving?: boolean;
28
+ }
29
+
30
+ const XGlyph: React.FC = () => (
31
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" aria-hidden="true">
32
+ <line x1="18" y1="6" x2="6" y2="18" />
33
+ <line x1="6" y1="6" x2="18" y2="18" />
34
+ </svg>
35
+ );
36
+
37
+ export const Toast: React.FC<ToastProps> = ({
38
+ tone,
39
+ icon,
40
+ title,
41
+ action,
42
+ onActionClick,
43
+ onClose,
44
+ progress = false,
45
+ leaving = false,
46
+ className,
47
+ children,
48
+ ...rest
49
+ }) => {
50
+ const cls = ['toast', tone ? `toast-${tone}` : '', leaving ? 'is-leaving' : '', className || '']
51
+ .filter(Boolean)
52
+ .join(' ');
53
+ return (
54
+ <div className={cls} role={tone === 'danger' ? 'alert' : 'status'} {...rest}>
55
+ {icon != null ? <span className="toast-icon">{icon}</span> : <span />}
56
+ <div className="toast-body">
57
+ {title != null ? <div className="toast-title">{title}</div> : null}
58
+ {children != null ? <div className="toast-desc">{children}</div> : null}
59
+ {action != null ? (
60
+ <a
61
+ className="toast-action"
62
+ role="button"
63
+ tabIndex={0}
64
+ onClick={onActionClick}
65
+ style={{ cursor: 'pointer' }}
66
+ >
67
+ {action}
68
+ </a>
69
+ ) : null}
70
+ </div>
71
+ {onClose ? (
72
+ <button type="button" className="toast-close" aria-label="Dismiss" onClick={onClose}>
73
+ <XGlyph />
74
+ </button>
75
+ ) : (
76
+ <span />
77
+ )}
78
+ {progress ? <span className="toast-progress" /> : null}
79
+ </div>
80
+ );
81
+ };
82
+
83
+ export interface ToastStackProps extends React.HTMLAttributes<HTMLDivElement> {
84
+ /** Corner: tr (default) · tl · tc · br · bl · bc. */
85
+ position?: ToastStackPosition;
86
+ }
87
+
88
+ export const ToastStack: React.FC<ToastStackProps> = ({ position = 'tr', className, children, ...rest }) => (
89
+ <div className={['toast-stack', `toast-stack-${position}`, className || ''].filter(Boolean).join(' ')} {...rest}>
90
+ {children}
91
+ </div>
92
+ );
93
+
94
+ export default Toast;
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+
3
+ export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
4
+
5
+ export interface TooltipProps extends React.HTMLAttributes<HTMLSpanElement> {
6
+ /** Tooltip content — plain label, or rich blocks when rich=true. */
7
+ content: React.ReactNode;
8
+ placement?: TooltipPlacement;
9
+ /** Larger interactive panel (.tooltip-rich) that stays open on hover. */
10
+ rich?: boolean;
11
+ /** Force-show (testing / controlled cases) — .is-open. */
12
+ open?: boolean;
13
+ /** Keyboard hint — renders a trailing <kbd> (`.tooltip-kbd`). */
14
+ shortcut?: string;
15
+ /** The trigger element(s). */
16
+ children: React.ReactNode;
17
+ }
18
+
19
+ export declare const Tooltip: React.FC<TooltipProps>;
20
+ export declare const TooltipTitle: React.FC<React.HTMLAttributes<HTMLDivElement>>;
21
+ export declare const TooltipDesc: React.FC<React.HTMLAttributes<HTMLParagraphElement>>;
22
+ export declare const TooltipRow: React.FC<{ k: React.ReactNode; v: React.ReactNode } & React.HTMLAttributes<HTMLDivElement>>;
23
+ export default Tooltip;
@@ -0,0 +1,80 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * ATTRUS Tooltip — typed wrapper over the canonical `.tooltip` system
5
+ * (preview/components/tooltip.css). Wraps the trigger in .tooltip-target;
6
+ * visibility is pure CSS (:hover / :focus-within) — no JS listeners.
7
+ * `rich` enables the larger interactive panel (title/desc/rows blocks).
8
+ */
9
+
10
+ export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
11
+
12
+ export interface TooltipProps extends React.HTMLAttributes<HTMLSpanElement> {
13
+ /** Tooltip content — plain label, or rich blocks when rich=true. */
14
+ content: React.ReactNode;
15
+ placement?: TooltipPlacement;
16
+ /** Larger interactive panel (.tooltip-rich) that stays open on hover. */
17
+ rich?: boolean;
18
+ /** Force-show (testing / controlled cases) — .is-open. */
19
+ open?: boolean;
20
+ /** Keyboard hint — renders a trailing <kbd> (`.tooltip-kbd`). */
21
+ shortcut?: string;
22
+ /** The trigger element(s). */
23
+ children: React.ReactNode;
24
+ }
25
+
26
+ export const Tooltip: React.FC<TooltipProps> = ({
27
+ content,
28
+ placement = 'top',
29
+ rich = false,
30
+ open = false,
31
+ shortcut,
32
+ className,
33
+ children,
34
+ ...rest
35
+ }) => {
36
+ const tipCls = [
37
+ 'tooltip',
38
+ `tooltip-${placement}`,
39
+ rich ? 'tooltip-rich' : '',
40
+ shortcut ? 'tooltip-kbd' : '',
41
+ open ? 'is-open' : '',
42
+ ]
43
+ .filter(Boolean)
44
+ .join(' ');
45
+ // Escape hides the tooltip while focus stays on the target (doc a11y
46
+ // contract); suppression clears on blur or when the pointer re-enters.
47
+ const [suppressed, setSuppressed] = React.useState(false);
48
+ return (
49
+ <span
50
+ className={['tooltip-target', suppressed ? 'is-suppressed' : '', className || ''].filter(Boolean).join(' ')}
51
+ tabIndex={0}
52
+ onKeyDown={(e) => { if (e.key === 'Escape') setSuppressed(true); }}
53
+ onBlur={() => setSuppressed(false)}
54
+ onMouseEnter={() => setSuppressed(false)}
55
+ {...rest}
56
+ >
57
+ {children}
58
+ <span className={tipCls} role="tooltip">
59
+ {content}
60
+ {shortcut ? <kbd>{shortcut}</kbd> : null}
61
+ </span>
62
+ </span>
63
+ );
64
+ };
65
+
66
+ /* Rich-panel slots — compose inside `content` with rich=true. */
67
+ export const TooltipTitle: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ className, ...rest }) => (
68
+ <div className={['tooltip-title', className || ''].filter(Boolean).join(' ')} {...rest} />
69
+ );
70
+ export const TooltipDesc: React.FC<React.HTMLAttributes<HTMLParagraphElement>> = ({ className, ...rest }) => (
71
+ <p className={['tooltip-desc', className || ''].filter(Boolean).join(' ')} {...rest} />
72
+ );
73
+ export const TooltipRow: React.FC<{ k: React.ReactNode; v: React.ReactNode } & React.HTMLAttributes<HTMLDivElement>> = ({ k, v, className, ...rest }) => (
74
+ <div className={['tooltip-row', className || ''].filter(Boolean).join(' ')} {...rest}>
75
+ <span className="k">{k}</span>
76
+ <span className="v">{v}</span>
77
+ </div>
78
+ );
79
+
80
+ export default Tooltip;
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+
3
+ export interface ZeroStateProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ /** Illustration slot (.empty-illo) — SVG or image. */
5
+ illo?: React.ReactNode;
6
+ /** Heading (h4). */
7
+ title: React.ReactNode;
8
+ /** Action row (.empty-actions) — canonical Buttons. */
9
+ actions?: React.ReactNode;
10
+ /** Dense variant for cards/panels (.empty-compact). */
11
+ compact?: boolean;
12
+ /** Warning tone — tinted panel (.empty-warning). */
13
+ warning?: boolean;
14
+ }
15
+
16
+ export declare const ZeroState: React.FC<ZeroStateProps>;
17
+ export default ZeroState;
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * ATTRUS ZeroState — typed wrapper over the canonical `.empty` block
5
+ * (preview/components/empty-states.css): centered illustration + title +
6
+ * body + actions for zero-data surfaces.
7
+ * (Module named ZeroState — "EmptyState" collides with the legacy
8
+ * ui_kits/dashboard/EmptyState.jsx still consumed by the app.)
9
+ */
10
+
11
+ export interface ZeroStateProps extends React.HTMLAttributes<HTMLDivElement> {
12
+ /** Illustration slot (.empty-illo) — SVG or image. */
13
+ illo?: React.ReactNode;
14
+ /** Heading (h4). */
15
+ title: React.ReactNode;
16
+ /** Action row (.empty-actions) — canonical Buttons. */
17
+ actions?: React.ReactNode;
18
+ /** Dense variant for cards/panels (.empty-compact). */
19
+ compact?: boolean;
20
+ /** Warning tone — tinted panel (.empty-warning). */
21
+ warning?: boolean;
22
+ }
23
+
24
+ export const ZeroState: React.FC<ZeroStateProps> = ({
25
+ illo,
26
+ title,
27
+ actions,
28
+ compact = false,
29
+ warning = false,
30
+ className,
31
+ children,
32
+ ...rest
33
+ }) => (
34
+ <div
35
+ className={['empty', compact ? 'empty-compact' : 'empty-default', warning ? 'empty-warning' : '', className || ''].filter(Boolean).join(' ')}
36
+ {...rest}
37
+ >
38
+ {illo != null ? <span className="empty-illo">{illo}</span> : null}
39
+ <h4>{title}</h4>
40
+ {children != null ? <p>{children}</p> : null}
41
+ {actions != null ? <div className="empty-actions">{actions}</div> : null}
42
+ </div>
43
+ );
44
+
45
+ export default ZeroState;
@@ -0,0 +1,35 @@
1
+ /* ============================================================
2
+ @attrus-ds/core/react — typed React component layer.
3
+
4
+ These components are thin, typed wrappers over the canonical
5
+ ATTRUS / Cabiros CSS (the CSS stays the single visual source of
6
+ truth — see ../components). They only compose class names and add
7
+ a typed API on top, so the markup-only consumer path stays valid.
8
+
9
+ Shipped as TSX source + .d.ts contracts (no bundler): your app's
10
+ toolchain compiles them. `react` is a peer dependency.
11
+
12
+ Styles are NOT imported here — load them once at your app root:
13
+ import "@attrus-ds/core/css";
14
+ ============================================================ */
15
+
16
+ export * from "./AppSidebar/AppSidebar";
17
+ export * from "./AppTopbar/AppTopbar";
18
+ export * from "./Atoms/Atoms";
19
+ export * from "./Button/Button";
20
+ export * from "./Callout/Callout";
21
+ export * from "./Card/Card";
22
+ export * from "./Combobox/Combobox";
23
+ export * from "./DataTable/DataTable";
24
+ export * from "./Drawer/Drawer";
25
+ export * from "./Input/Input";
26
+ export * from "./Modal/Modal";
27
+ export * from "./NumberInput/NumberInput";
28
+ export * from "./Pill/Pill";
29
+ export * from "./SearchPill/SearchPill";
30
+ export * from "./SmartSearch/SmartSearch";
31
+ export * from "./Stepper/Stepper";
32
+ export * from "./Tabs/Tabs";
33
+ export * from "./Toast/Toast";
34
+ export * from "./Tooltip/Tooltip";
35
+ export * from "./ZeroState/ZeroState";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@attrus-ds/core",
3
- "version": "0.1.1",
4
- "description": "ATTRUS / Cabiros design system — design tokens, component styles, brand assets and fonts. Visual layer only (no framework components).",
3
+ "version": "0.2.0",
4
+ "description": "ATTRUS / Cabiros design system — design tokens, component styles, brand assets, fonts and an optional typed React component layer.",
5
5
  "keywords": [
6
6
  "design-system",
7
7
  "design-tokens",
@@ -39,6 +39,8 @@
39
39
  "./tokens.json": "./dist/tokens/attrus-tokens.json",
40
40
  "./tokens.flat.json": "./dist/tokens/attrus-tokens.flat.json",
41
41
  "./components/*": "./dist/css/components/*",
42
+ "./react": "./dist/react/index.ts",
43
+ "./react/*": "./dist/react/*",
42
44
  "./assets/*": "./dist/assets/*",
43
45
  "./fonts/*": "./dist/fonts/*",
44
46
  "./package.json": "./package.json"
@@ -47,6 +49,14 @@
47
49
  "build": "node scripts/build.mjs",
48
50
  "prepublishOnly": "npm run build"
49
51
  },
52
+ "peerDependencies": {
53
+ "react": ">=18"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "react": {
57
+ "optional": true
58
+ }
59
+ },
50
60
  "devDependencies": {
51
61
  "@fontsource/jetbrains-mono": "^5.0.0",
52
62
  "@fontsource/lato": "^5.0.0"