@neasg/design-system 0.3.0 → 0.4.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 (92) hide show
  1. package/README.md +37 -1
  2. package/dist/alert.d.ts +15 -0
  3. package/dist/alert.js +24 -0
  4. package/dist/avatar.d.ts +5 -2
  5. package/dist/avatar.js +8 -4
  6. package/dist/back-button.d.ts +6 -0
  7. package/dist/back-button.js +8 -0
  8. package/dist/badge.d.ts +1 -1
  9. package/dist/breadcrumb.js +2 -2
  10. package/dist/button.d.ts +2 -2
  11. package/dist/button.js +3 -4
  12. package/dist/card.d.ts +3 -0
  13. package/dist/card.js +9 -2
  14. package/dist/checkbox.d.ts +13 -0
  15. package/dist/checkbox.js +29 -0
  16. package/dist/collapsible.d.ts +19 -0
  17. package/dist/collapsible.js +20 -0
  18. package/dist/command-search.js +2 -2
  19. package/dist/copy-button.d.ts +19 -0
  20. package/dist/copy-button.js +31 -0
  21. package/dist/date-input.js +2 -2
  22. package/dist/dialog-primitive.js +1 -1
  23. package/dist/draggable-tabs.js +1 -1
  24. package/dist/drawer.js +1 -1
  25. package/dist/editable-table.js +2 -2
  26. package/dist/empty-state.js +1 -1
  27. package/dist/field.d.ts +4 -1
  28. package/dist/field.js +3 -3
  29. package/dist/file-upload.d.ts +12 -0
  30. package/dist/file-upload.js +106 -0
  31. package/dist/index.d.ts +47 -6
  32. package/dist/index.js +25 -4
  33. package/dist/input-control.d.ts +1 -1
  34. package/dist/input-control.js +1 -1
  35. package/dist/input.js +2 -2
  36. package/dist/label-value-grid.d.ts +3 -1
  37. package/dist/label-value-grid.js +15 -2
  38. package/dist/label-value.d.ts +4 -1
  39. package/dist/label-value.js +4 -3
  40. package/dist/layout.d.ts +7 -1
  41. package/dist/layout.js +3 -3
  42. package/dist/lib/date-utils.d.ts +9 -0
  43. package/dist/lib/date-utils.js +34 -0
  44. package/dist/link.d.ts +9 -0
  45. package/dist/link.js +19 -0
  46. package/dist/multi-select.d.ts +3 -1
  47. package/dist/multi-select.js +12 -11
  48. package/dist/page-section.d.ts +14 -0
  49. package/dist/page-section.js +13 -0
  50. package/dist/pagination.js +1 -1
  51. package/dist/popover-menu.d.ts +35 -0
  52. package/dist/popover-menu.js +36 -0
  53. package/dist/popover-primitive.d.ts +7 -0
  54. package/dist/popover-primitive.js +11 -0
  55. package/dist/popover.d.ts +10 -5
  56. package/dist/popover.js +6 -9
  57. package/dist/progress.d.ts +10 -0
  58. package/dist/progress.js +17 -0
  59. package/dist/search-input.js +1 -1
  60. package/dist/section-nav.d.ts +22 -0
  61. package/dist/section-nav.js +25 -0
  62. package/dist/select-primitive.js +2 -2
  63. package/dist/select.js +2 -2
  64. package/dist/separator.d.ts +6 -0
  65. package/dist/separator.js +6 -0
  66. package/dist/skeleton.d.ts +4 -0
  67. package/dist/skeleton.js +6 -0
  68. package/dist/spinner.d.ts +22 -0
  69. package/dist/spinner.js +24 -0
  70. package/dist/styles.css +42 -0
  71. package/dist/switch.d.ts +12 -0
  72. package/dist/switch.js +16 -0
  73. package/dist/table.d.ts +7 -1
  74. package/dist/table.js +26 -12
  75. package/dist/tabs.d.ts +24 -1
  76. package/dist/tabs.js +61 -3
  77. package/dist/tailwind-preset.js +9 -0
  78. package/dist/textarea.js +1 -1
  79. package/dist/toaster.js +19 -10
  80. package/dist/use-error-shake.d.ts +7 -0
  81. package/dist/use-error-shake.js +36 -0
  82. package/dist/use-file-upload.d.ts +34 -0
  83. package/dist/use-file-upload.js +133 -0
  84. package/dist/use-sticky-sentinel.d.ts +16 -0
  85. package/dist/use-sticky-sentinel.js +62 -0
  86. package/dist/use-table-sort.d.ts +28 -0
  87. package/dist/use-table-sort.js +53 -0
  88. package/dist/use-viewport-threshold.d.ts +12 -0
  89. package/dist/use-viewport-threshold.js +43 -0
  90. package/package.json +32 -6
  91. package/dist/tab-with-dropdown.d.ts +0 -18
  92. package/dist/tab-with-dropdown.js +0 -70
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neasg/design-system",
3
- "version": "0.3.0",
3
+ "version": "0.4.2",
4
4
  "description": "NEA shared design system primitives, theme tokens, and Storybook docs.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -35,10 +35,12 @@
35
35
  "@dnd-kit/utilities": "^3.2.2",
36
36
  "@govtechsg/sgds-web-component": "^3.8.1",
37
37
  "@radix-ui/react-avatar": "^1.1.11",
38
+ "@radix-ui/react-collapsible": "^1.1.12",
38
39
  "@radix-ui/react-dialog": "^1.1.15",
39
40
  "@radix-ui/react-popover": "^1.1.15",
40
41
  "@radix-ui/react-select": "^2.2.6",
41
42
  "@radix-ui/react-slot": "^1.2.4",
43
+ "@radix-ui/react-switch": "^1.2.6",
42
44
  "@radix-ui/react-tabs": "^1.1.13",
43
45
  "@radix-ui/react-tooltip": "^1.2.8",
44
46
  "class-variance-authority": "^0.7.0",
@@ -56,10 +58,10 @@
56
58
  },
57
59
  "devDependencies": {
58
60
  "@fontsource/inter": "^5.2.8",
59
- "@storybook/addon-docs": "10.2.19",
60
- "@storybook/addon-themes": "10.2.19",
61
- "@storybook/react": "10.2.19",
62
- "@storybook/react-vite": "10.2.19",
61
+ "@storybook/addon-docs": "10.3.5",
62
+ "@storybook/addon-mcp": "^0.5.0",
63
+ "@storybook/addon-themes": "10.3.5",
64
+ "@storybook/react-vite": "10.3.5",
63
65
  "@testing-library/jest-dom": "^6.9.1",
64
66
  "@types/node": "^20.10.5",
65
67
  "@types/react": "^18.2.45",
@@ -70,7 +72,7 @@
70
72
  "postcss": "^8.4.31",
71
73
  "react": "^18.2.0",
72
74
  "react-dom": "^18.2.0",
73
- "storybook": "10.2.19",
75
+ "storybook": "10.3.5",
74
76
  "tailwindcss": "^3.4.1",
75
77
  "typescript": "^5.3.3",
76
78
  "vitest": "^4.1.0"
@@ -92,6 +94,10 @@
92
94
  "types": "./dist/badge.d.ts",
93
95
  "import": "./dist/badge.js"
94
96
  },
97
+ "./back-button": {
98
+ "types": "./dist/back-button.d.ts",
99
+ "import": "./dist/back-button.js"
100
+ },
95
101
  "./button": {
96
102
  "types": "./dist/button.d.ts",
97
103
  "import": "./dist/button.js"
@@ -172,6 +178,14 @@
172
178
  "types": "./dist/page-header.d.ts",
173
179
  "import": "./dist/page-header.js"
174
180
  },
181
+ "./page-section": {
182
+ "types": "./dist/page-section.d.ts",
183
+ "import": "./dist/page-section.js"
184
+ },
185
+ "./popover": {
186
+ "types": "./dist/popover.d.ts",
187
+ "import": "./dist/popover.js"
188
+ },
175
189
  "./pagination": {
176
190
  "types": "./dist/pagination.d.ts",
177
191
  "import": "./dist/pagination.js"
@@ -180,6 +194,10 @@
180
194
  "types": "./dist/search-input.d.ts",
181
195
  "import": "./dist/search-input.js"
182
196
  },
197
+ "./section-nav": {
198
+ "types": "./dist/section-nav.d.ts",
199
+ "import": "./dist/section-nav.js"
200
+ },
183
201
  "./styles.css": "./dist/styles.css",
184
202
  "./table": {
185
203
  "types": "./dist/table.d.ts",
@@ -213,6 +231,14 @@
213
231
  "types": "./dist/tooltip.d.ts",
214
232
  "import": "./dist/tooltip.js"
215
233
  },
234
+ "./separator": {
235
+ "types": "./dist/separator.d.ts",
236
+ "import": "./dist/separator.js"
237
+ },
238
+ "./collapsible-section": {
239
+ "types": "./dist/collapsible-section.d.ts",
240
+ "import": "./dist/collapsible-section.js"
241
+ },
216
242
  "./lib/utils": {
217
243
  "types": "./dist/lib/utils.d.ts",
218
244
  "import": "./dist/lib/utils.js"
@@ -1,18 +0,0 @@
1
- export interface TabDropdownSection {
2
- id: string;
3
- label: string;
4
- }
5
- export interface TabWithDropdownProps {
6
- /** Tab value — must match a TabsContent value. */
7
- value: string;
8
- /** Tab label shown in the trigger. */
9
- label: string;
10
- /** Dropdown sections shown on hover. */
11
- sections: TabDropdownSection[];
12
- /** Called when a section is selected. Receives the section id. */
13
- onSectionSelect?: (sectionId: string) => void;
14
- /** Scroll offset in pixels when scrolling to a section. */
15
- scrollOffset?: number;
16
- }
17
- declare function TabWithDropdown({ value, label, sections, onSectionSelect, scrollOffset, }: TabWithDropdownProps): import("react/jsx-runtime").JSX.Element;
18
- export { TabWithDropdown };
@@ -1,70 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import * as ReactDOM from "react-dom";
5
- import { ChevronDownIcon } from "./animated-icons/chevron-down";
6
- import { cn } from "./lib/utils";
7
- import { TabsTrigger, useTabsContext } from "./tabs";
8
- function TabWithDropdown({ value, label, sections, onSectionSelect, scrollOffset = 200, }) {
9
- const [isOpen, setIsOpen] = React.useState(false);
10
- const [dropdownPosition, setDropdownPosition] = React.useState({
11
- top: 0,
12
- left: 0,
13
- });
14
- const triggerRef = React.useRef(null);
15
- const timeoutRef = React.useRef(null);
16
- const tabsContext = useTabsContext();
17
- const updatePosition = React.useCallback(() => {
18
- if (triggerRef.current) {
19
- const rect = triggerRef.current.getBoundingClientRect();
20
- setDropdownPosition({
21
- top: rect.bottom + 8,
22
- left: rect.left,
23
- });
24
- }
25
- }, []);
26
- const handleMouseEnter = () => {
27
- if (timeoutRef.current)
28
- clearTimeout(timeoutRef.current);
29
- updatePosition();
30
- setIsOpen(true);
31
- };
32
- const handleMouseLeave = () => {
33
- timeoutRef.current = setTimeout(() => setIsOpen(false), 150);
34
- };
35
- const handleDropdownMouseEnter = () => {
36
- if (timeoutRef.current)
37
- clearTimeout(timeoutRef.current);
38
- };
39
- const handleDropdownMouseLeave = () => {
40
- timeoutRef.current = setTimeout(() => setIsOpen(false), 150);
41
- };
42
- const handleSectionClick = (sectionId) => {
43
- if (onSectionSelect) {
44
- onSectionSelect(sectionId);
45
- }
46
- else {
47
- // Default: switch tab and scroll to the section element
48
- const doScroll = () => {
49
- const element = document.getElementById(sectionId);
50
- if (!element)
51
- return;
52
- const top = element.getBoundingClientRect().top + window.scrollY - scrollOffset;
53
- window.scrollTo({ top, behavior: "smooth" });
54
- };
55
- if (tabsContext && tabsContext.value !== value) {
56
- tabsContext.setValue(value);
57
- setTimeout(doScroll, 50);
58
- }
59
- else {
60
- doScroll();
61
- }
62
- }
63
- setIsOpen(false);
64
- };
65
- return (_jsxs(_Fragment, { children: [_jsx("div", { ref: triggerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: _jsxs(TabsTrigger, { value: value, className: "flex items-center gap-1", children: [label, sections.length > 0 ? (_jsx(ChevronDownIcon, { className: cn("transition-transform duration-200", isOpen && "rotate-180"), size: 12 })) : null] }) }), isOpen &&
66
- sections.length > 0 &&
67
- typeof document !== "undefined" &&
68
- ReactDOM.createPortal(_jsx("div", { className: "fixed z-[100] rounded-md border bg-popover p-1 shadow-lg animate-in fade-in-0 zoom-in-95", style: { top: dropdownPosition.top, left: dropdownPosition.left }, onMouseEnter: handleDropdownMouseEnter, onMouseLeave: handleDropdownMouseLeave, children: sections.map((section) => (_jsx("button", { type: "button", onClick: () => handleSectionClick(section.id), className: "block w-full rounded-sm px-3 py-2 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground", children: section.label }, section.id))) }), document.body)] }));
69
- }
70
- export { TabWithDropdown };