@dreamtree-org/twreact-ui 1.3.8 → 1.3.10

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 (109) hide show
  1. package/DESIGN.md +11 -3
  2. package/README.md +9 -1
  3. package/ai-skills/dreamtree-ui.md +2 -2
  4. package/dist/ai-schema.json +19 -8
  5. package/dist/charts/index.js +69 -24
  6. package/dist/components/blocks/AppShell.d.ts.map +1 -1
  7. package/dist/components/charts/chartTheme.d.ts +2 -5
  8. package/dist/components/charts/chartTheme.d.ts.map +1 -1
  9. package/dist/components/core/Accordion.d.ts.map +1 -1
  10. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  11. package/dist/components/core/DatePicker.d.ts.map +1 -1
  12. package/dist/components/core/Form.d.ts.map +1 -1
  13. package/dist/components/core/Input.d.ts.map +1 -1
  14. package/dist/components/core/PriceRangePicker.d.ts +0 -29
  15. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  16. package/dist/components/core/Radio.d.ts.map +1 -1
  17. package/dist/components/core/Rate.d.ts.map +1 -1
  18. package/dist/components/core/RoundedTag.d.ts.map +1 -1
  19. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  20. package/dist/components/core/Table/Pagination.d.ts.map +1 -1
  21. package/dist/components/core/Table/Table.d.ts.map +1 -1
  22. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  23. package/dist/components/core/Table/helpers.d.ts +2 -0
  24. package/dist/components/core/Table/helpers.d.ts.map +1 -1
  25. package/dist/components/core/Table/useClickOutside.d.ts +5 -2
  26. package/dist/components/core/Table/useClickOutside.d.ts.map +1 -1
  27. package/dist/components/core/Tabs.d.ts.map +1 -1
  28. package/dist/components/core/TextToSpeech.d.ts +2 -7
  29. package/dist/components/core/TextToSpeech.d.ts.map +1 -1
  30. package/dist/components/core/Tooltip.d.ts.map +1 -1
  31. package/dist/components/feedback/Alert.d.ts.map +1 -1
  32. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  33. package/dist/components/feedback/Toast.d.ts.map +1 -1
  34. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  35. package/dist/components/utility/Avatar.d.ts.map +1 -1
  36. package/dist/components/utility/Carousel.d.ts.map +1 -1
  37. package/dist/components/utility/Portal.d.ts +6 -0
  38. package/dist/components/utility/Portal.d.ts.map +1 -0
  39. package/dist/esm/components/blocks/AppShell.js +24 -18
  40. package/dist/esm/components/charts/CartesianChart.js +2 -1
  41. package/dist/esm/components/charts/DonutChart.js +2 -1
  42. package/dist/esm/components/charts/Sparkline.js +2 -1
  43. package/dist/esm/components/charts/chartTheme.js +1 -22
  44. package/dist/esm/components/core/Accordion.js +40 -9
  45. package/dist/esm/components/core/Button.js +8 -8
  46. package/dist/esm/components/core/ColorPicker.js +19 -7
  47. package/dist/esm/components/core/DatePicker.js +97 -58
  48. package/dist/esm/components/core/Form.js +35 -8
  49. package/dist/esm/components/core/Input.js +3 -1
  50. package/dist/esm/components/core/PriceRangePicker.js +205 -218
  51. package/dist/esm/components/core/Radio.js +36 -6
  52. package/dist/esm/components/core/Rate.js +41 -50
  53. package/dist/esm/components/core/RoundedTag.js +25 -8
  54. package/dist/esm/components/core/Table/ColumnMenu.js +2 -4
  55. package/dist/esm/components/core/Table/Pagination.js +15 -18
  56. package/dist/esm/components/core/Table/Table.js +11 -5
  57. package/dist/esm/components/core/Table/TableRow.js +2 -2
  58. package/dist/esm/components/core/Table/helpers.js +33 -1
  59. package/dist/esm/components/core/Tabs.js +6 -5
  60. package/dist/esm/components/core/TextToSpeech.js +121 -28
  61. package/dist/esm/components/core/Tooltip.js +100 -28
  62. package/dist/esm/components/feedback/Alert.js +21 -11
  63. package/dist/esm/components/feedback/Dialog.js +44 -100
  64. package/dist/esm/components/feedback/Toast.js +24 -5
  65. package/dist/esm/components/navigation/Sidebar.js +13 -61
  66. package/dist/esm/components/utility/Avatar.js +23 -10
  67. package/dist/esm/components/utility/Carousel.js +34 -17
  68. package/dist/esm/components/utility/Pagination.js +2 -2
  69. package/dist/esm/hooks/useClickOutside.js +51 -0
  70. package/dist/esm/hooks/useFocusTrap.js +10 -2
  71. package/dist/esm/hooks/useMediaQuery.js +61 -0
  72. package/dist/esm/hooks/useReducedMotion.js +17 -0
  73. package/dist/esm/hooks/useScrollLock.js +76 -9
  74. package/dist/esm/hooks/useTheme.js +6 -1
  75. package/dist/esm/utils/position.js +6 -0
  76. package/dist/hooks/useClickOutside.d.ts +14 -0
  77. package/dist/hooks/useClickOutside.d.ts.map +1 -0
  78. package/dist/hooks/useFloatingPosition.d.ts +37 -0
  79. package/dist/hooks/useFloatingPosition.d.ts.map +1 -0
  80. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  81. package/dist/hooks/useMediaQuery.d.ts +22 -0
  82. package/dist/hooks/useMediaQuery.d.ts.map +1 -0
  83. package/dist/hooks/usePresence.d.ts +16 -0
  84. package/dist/hooks/usePresence.d.ts.map +1 -0
  85. package/dist/hooks/usePresentation.d.ts +9 -0
  86. package/dist/hooks/usePresentation.d.ts.map +1 -0
  87. package/dist/hooks/useReducedMotion.d.ts +10 -0
  88. package/dist/hooks/useReducedMotion.d.ts.map +1 -0
  89. package/dist/hooks/useScrollLock.d.ts +11 -1
  90. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  91. package/dist/hooks/useTheme.d.ts.map +1 -1
  92. package/dist/index.css +1 -1
  93. package/dist/index.esm.css +1 -1
  94. package/dist/index.esm.js +1719 -1201
  95. package/dist/index.js +1718 -1200
  96. package/dist/tokens/tailwind3-preset.cjs +101 -8
  97. package/dist/tokens/theme.css +27 -0
  98. package/dist/tokens/tokens.json +175 -0
  99. package/dist/tokens/vars.css +2 -0
  100. package/dist/types/index.d.ts +8 -2
  101. package/dist/types/index.d.ts.map +1 -1
  102. package/dist/utils/position.d.ts.map +1 -1
  103. package/dist/utils/touchTarget.d.ts +1 -0
  104. package/dist/utils/touchTarget.d.ts.map +1 -1
  105. package/mcp/catalog.snapshot.json +83 -53
  106. package/package.json +2 -1
  107. package/tokens/lib.cjs +35 -0
  108. package/tokens/tokens.json +58 -2
  109. package/dist/esm/components/core/Table/useClickOutside.js +0 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dreamtree-org/twreact-ui",
3
- "version": "1.3.8",
3
+ "version": "1.3.10",
4
4
  "description": "A comprehensive React + Tailwind components library for building modern web apps",
5
5
  "author": {
6
6
  "name": "Partha Preetham Krishna",
@@ -134,6 +134,7 @@
134
134
  }
135
135
  },
136
136
  "dependencies": {
137
+ "@floating-ui/react-dom": "^2.1.9",
137
138
  "@hookform/resolvers": "^3.10.0",
138
139
  "@modelcontextprotocol/sdk": "^1.29.0",
139
140
  "@reduxjs/toolkit": "^2.11.2",
package/tokens/lib.cjs CHANGED
@@ -226,11 +226,45 @@ function cssVariables(tokens, { includeScales = true } = {}) {
226
226
  light[varName(name)] = hexToChannels(r.light);
227
227
  dark[varName(name)] = hexToChannels(r.dark);
228
228
  }
229
+ if (tokens.shadow) {
230
+ light['--dt-shadow-strength'] = SHADOW_STRENGTH.light;
231
+ dark['--dt-shadow-strength'] = SHADOW_STRENGTH.dark;
232
+ }
229
233
  return { light, dark };
230
234
  }
231
235
 
232
236
  const DARK_SELECTOR = '.dark, [data-theme="dark"]';
233
237
 
238
+ /** Multiplier for shadow alpha: dark surfaces need deeper shadows to show elevation. */
239
+ const SHADOW_STRENGTH = { light: '1', dark: '2.5' };
240
+
241
+ const dim = (v) => `${v.value}${v.unit}`;
242
+ const groupEntries = (group) => Object.entries(group || {}).filter(([k]) => !k.startsWith('$'));
243
+
244
+ /**
245
+ * Non-colour theme scales for Tailwind `theme.extend`: type roles, radius, fonts,
246
+ * elevation, z-layers and motion. Works for Tailwind 3 configs and the generated preset.
247
+ */
248
+ function tailwindTheme(tokens) {
249
+ const fontSize = {};
250
+ for (const [name, t] of groupEntries(tokens.font.size)) {
251
+ const ext = t.$extensions || {};
252
+ const opts = { lineHeight: ext['org.dreamtree.lineHeight'] };
253
+ if (ext['org.dreamtree.fontWeight']) opts.fontWeight = ext['org.dreamtree.fontWeight'];
254
+ fontSize[name] = [dim(t.$value), opts];
255
+ }
256
+ const map = (group, fn) => Object.fromEntries(groupEntries(group).map(([k, t]) => [k, fn(t.$value)]));
257
+ return {
258
+ fontSize,
259
+ fontFamily: { sans: tokens.font.family.sans.$value, mono: tokens.font.family.mono.$value },
260
+ borderRadius: map(tokens.radius, dim),
261
+ boxShadow: map(tokens.shadow, (v) => v),
262
+ zIndex: map(tokens.zIndex, String),
263
+ transitionDuration: map(tokens.duration, dim),
264
+ transitionTimingFunction: map(tokens.easing, (v) => `cubic-bezier(${v.join(', ')})`),
265
+ };
266
+ }
267
+
234
268
  module.exports = {
235
269
  SCALE_STEPS,
236
270
  DARK_SELECTOR,
@@ -247,6 +281,7 @@ module.exports = {
247
281
  scales,
248
282
  roles,
249
283
  tailwindColors,
284
+ tailwindTheme,
250
285
  cssVariables,
251
286
  varName,
252
287
  };
@@ -122,12 +122,68 @@
122
122
  "size": {
123
123
  "$type": "dimension",
124
124
  "$description": "Type scale. micro replaces the 1,445 hand-written text-[10px]/text-[11px] found across products.",
125
- "micro": { "$value": { "value": 0.6875, "unit": "rem" }, "$extensions": { "org.dreamtree.lineHeight": "1rem" } }
125
+ "micro": { "$value": { "value": 0.6875, "unit": "rem" }, "$extensions": { "org.dreamtree.lineHeight": "1rem" } },
126
+ "page-title": {
127
+ "$value": { "value": 1.5, "unit": "rem" },
128
+ "$extensions": { "org.dreamtree.lineHeight": "2rem", "org.dreamtree.fontWeight": "600" },
129
+ "$description": "The page h1, inside PageHeader."
130
+ },
131
+ "section-title": {
132
+ "$value": { "value": 1, "unit": "rem" },
133
+ "$extensions": { "org.dreamtree.lineHeight": "1.5rem", "org.dreamtree.fontWeight": "600" },
134
+ "$description": "Card and section headings."
135
+ },
136
+ "body": { "$value": { "value": 0.875, "unit": "rem" }, "$extensions": { "org.dreamtree.lineHeight": "1.25rem" }, "$description": "Default UI text." },
137
+ "caption": { "$value": { "value": 0.75, "unit": "rem" }, "$extensions": { "org.dreamtree.lineHeight": "1rem" }, "$description": "Secondary text, with text-muted." },
138
+ "kpi": {
139
+ "$value": { "value": 1.875, "unit": "rem" },
140
+ "$extensions": { "org.dreamtree.lineHeight": "2.25rem", "org.dreamtree.fontWeight": "600" },
141
+ "$description": "StatCard values; pair with tabular-nums."
142
+ }
126
143
  }
127
144
  },
128
145
  "radius": {
129
146
  "$type": "dimension",
130
147
  "control": { "$value": { "value": 0.5, "unit": "rem" }, "$description": "Buttons, inputs, menus." },
131
- "card": { "$value": { "value": 0.75, "unit": "rem" }, "$description": "Cards and dialogs." }
148
+ "card": { "$value": { "value": 0.75, "unit": "rem" }, "$description": "Cards and dialogs." },
149
+ "sheet": { "$value": { "value": 1, "unit": "rem" }, "$description": "Top corners of bottom sheets." },
150
+ "pill": { "$value": { "value": 9999, "unit": "px" }, "$description": "Pills, badges, segmented controls." }
151
+ },
152
+ "shadow": {
153
+ "$type": "shadow",
154
+ "$description": "Elevation, as CSS box-shadow. Light values equal Tailwind's defaults; --dt-shadow-strength deepens them in dark mode, where a 10% black shadow disappears.",
155
+ "xs": { "$value": "0 1px 2px 0 rgb(0 0 0 / calc(0.04 * var(--dt-shadow-strength, 1)))" },
156
+ "sm": { "$value": "0 1px 2px 0 rgb(0 0 0 / calc(0.05 * var(--dt-shadow-strength, 1)))" },
157
+ "DEFAULT": { "$value": "0 1px 3px 0 rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1))), 0 1px 2px -1px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1)))" },
158
+ "md": { "$value": "0 4px 6px -1px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1))), 0 2px 4px -2px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1)))" },
159
+ "lg": { "$value": "0 10px 15px -3px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1))), 0 4px 6px -4px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1)))" },
160
+ "xl": {
161
+ "$value": "0 20px 25px -5px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1))), 0 8px 10px -6px rgb(0 0 0 / calc(0.1 * var(--dt-shadow-strength, 1)))"
162
+ },
163
+ "overlay": { "$value": "0 24px 48px -12px rgb(0 0 0 / calc(0.25 * var(--dt-shadow-strength, 1)))", "$description": "Dialogs, sheets, popovers and menus." }
164
+ },
165
+ "zIndex": {
166
+ "$type": "number",
167
+ "$description": "Stacking layers, lowest to highest. Use z-<layer>, never z-50 or an inline zIndex.",
168
+ "base": { "$value": 0 },
169
+ "sticky": { "$value": 20 },
170
+ "dropdown": { "$value": 30 },
171
+ "overlay": { "$value": 40 },
172
+ "modal": { "$value": 50 },
173
+ "popover": { "$value": 60 },
174
+ "toast": { "$value": 70 },
175
+ "tooltip": { "$value": 80 }
176
+ },
177
+ "duration": {
178
+ "$type": "duration",
179
+ "fast": { "$value": { "value": 120, "unit": "ms" }, "$description": "Hover, press, small fades." },
180
+ "base": { "$value": { "value": 200, "unit": "ms" }, "$description": "Most enter transitions." },
181
+ "slow": { "$value": { "value": 320, "unit": "ms" }, "$description": "Sheets, drawers, large surfaces." }
182
+ },
183
+ "easing": {
184
+ "$type": "cubicBezier",
185
+ "standard": { "$value": [0.2, 0, 0, 1], "$description": "Default for moving and resizing." },
186
+ "emphasized": { "$value": [0.05, 0.7, 0.1, 1], "$description": "Entering surfaces (decelerate)." },
187
+ "spring-out": { "$value": [0.34, 1.56, 0.64, 1], "$description": "Small overshoot for sheets settling and toggles." }
132
188
  }
133
189
  }
@@ -1,26 +0,0 @@
1
- 'use client';
2
- import { useEffect } from 'react';
3
-
4
- /**
5
- * Custom hook to detect clicks outside of specified refs
6
- * @param {Array} refs - Array of React refs to check
7
- * @param {boolean} isActive - Whether the hook should be active
8
- * @param {Function} onClickOutside - Callback when click is detected outside
9
- */
10
- function useClickOutside(refs, isActive, onClickOutside) {
11
- useEffect(function () {
12
- if (!isActive) return;
13
- var handler = function handler(e) {
14
- var isOutside = refs.every(function (ref) {
15
- return !ref.current || !ref.current.contains(e.target);
16
- });
17
- if (isOutside) onClickOutside();
18
- };
19
- document.addEventListener("mousedown", handler, true);
20
- return function () {
21
- return document.removeEventListener("mousedown", handler, true);
22
- };
23
- }, [refs, isActive, onClickOutside]);
24
- }
25
-
26
- export { useClickOutside };