@granularjs/ui 0.1.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 (220) hide show
  1. package/README.md +116 -0
  2. package/dist/fonts/Arimo-400.ttf +0 -0
  3. package/dist/fonts/Arimo-500.ttf +1449 -0
  4. package/dist/fonts/Arimo-600.ttf +1449 -0
  5. package/dist/fonts/Arimo-700.ttf +0 -0
  6. package/dist/fonts/Inter-400.woff2 +0 -0
  7. package/dist/fonts/Inter-500.woff2 +0 -0
  8. package/dist/fonts/Inter-600.woff2 +0 -0
  9. package/dist/fonts/Inter-700.woff2 +0 -0
  10. package/dist/fonts/Poppins-400.ttf +0 -0
  11. package/dist/fonts/Poppins-500.ttf +0 -0
  12. package/dist/fonts/Poppins-600.ttf +0 -0
  13. package/dist/fonts/Poppins-700.ttf +0 -0
  14. package/dist/granular-ui.min.js +3605 -0
  15. package/dist/granular-ui.min.js.map +7 -0
  16. package/package.json +55 -0
  17. package/src/components/Accordion.js +25 -0
  18. package/src/components/ActionIcon.js +20 -0
  19. package/src/components/Affix.js +11 -0
  20. package/src/components/Alert.js +33 -0
  21. package/src/components/Anchor.js +8 -0
  22. package/src/components/AppBar.js +14 -0
  23. package/src/components/Avatar.js +13 -0
  24. package/src/components/AvatarGroup.js +8 -0
  25. package/src/components/Badge.js +22 -0
  26. package/src/components/BadgeGroup.js +8 -0
  27. package/src/components/Blockquote.js +8 -0
  28. package/src/components/BottomBar.js +43 -0
  29. package/src/components/Breadcrumbs.js +19 -0
  30. package/src/components/Burger.js +13 -0
  31. package/src/components/Button.js +37 -0
  32. package/src/components/Calendar.js +109 -0
  33. package/src/components/Card.js +40 -0
  34. package/src/components/Center.js +8 -0
  35. package/src/components/Checkbox.js +46 -0
  36. package/src/components/CheckboxGroup.js +8 -0
  37. package/src/components/Chip.js +35 -0
  38. package/src/components/Code.js +8 -0
  39. package/src/components/Col.js +8 -0
  40. package/src/components/Collapse.js +8 -0
  41. package/src/components/Container.js +19 -0
  42. package/src/components/CopyButton.js +30 -0
  43. package/src/components/DateInput.js +123 -0
  44. package/src/components/DatePicker.js +7 -0
  45. package/src/components/Divider.js +22 -0
  46. package/src/components/Drawer.js +32 -0
  47. package/src/components/EventCalendar.js +972 -0
  48. package/src/components/Fieldset.js +12 -0
  49. package/src/components/Flex.js +25 -0
  50. package/src/components/Grid.js +8 -0
  51. package/src/components/GridTable.js +99 -0
  52. package/src/components/Group.js +29 -0
  53. package/src/components/HoverCard.js +24 -0
  54. package/src/components/Icon.js +19 -0
  55. package/src/components/Image.js +8 -0
  56. package/src/components/Indicator.js +21 -0
  57. package/src/components/Kbd.js +8 -0
  58. package/src/components/List.js +77 -0
  59. package/src/components/Loading.js +29 -0
  60. package/src/components/LoadingOverlay.js +9 -0
  61. package/src/components/Menu.js +129 -0
  62. package/src/components/Modal.js +61 -0
  63. package/src/components/MultiSelect.js +153 -0
  64. package/src/components/NavLink.js +72 -0
  65. package/src/components/Notification.js +42 -0
  66. package/src/components/Notifications.js +59 -0
  67. package/src/components/NumberField.js +389 -0
  68. package/src/components/NumberInput.js +5 -0
  69. package/src/components/Pagination.js +56 -0
  70. package/src/components/Paper.js +20 -0
  71. package/src/components/PasswordInput.js +29 -0
  72. package/src/components/PinInput.js +218 -0
  73. package/src/components/Popover.js +38 -0
  74. package/src/components/Popper.js +25 -0
  75. package/src/components/Progress.js +27 -0
  76. package/src/components/ProgressRing.js +11 -0
  77. package/src/components/Radio.js +22 -0
  78. package/src/components/RadioGroup.js +8 -0
  79. package/src/components/RangePicker.js +45 -0
  80. package/src/components/RangeSlider.js +143 -0
  81. package/src/components/Rating.js +42 -0
  82. package/src/components/ScrollArea.js +11 -0
  83. package/src/components/SearchInput.js +17 -0
  84. package/src/components/SegmentedControl.js +39 -0
  85. package/src/components/Select.js +71 -0
  86. package/src/components/SelectSearch.js +37 -0
  87. package/src/components/Sidebar.js +136 -0
  88. package/src/components/SimpleGrid.js +11 -0
  89. package/src/components/Skeleton.js +24 -0
  90. package/src/components/Slider.js +126 -0
  91. package/src/components/Space.js +8 -0
  92. package/src/components/Stack.js +27 -0
  93. package/src/components/Stepper.js +20 -0
  94. package/src/components/Switch.js +16 -0
  95. package/src/components/SwitchGroup.js +8 -0
  96. package/src/components/Table.js +42 -0
  97. package/src/components/Tabs.js +194 -0
  98. package/src/components/Tag.js +8 -0
  99. package/src/components/Text.js +42 -0
  100. package/src/components/TextInput.js +74 -0
  101. package/src/components/Textarea.js +15 -0
  102. package/src/components/Timeline.js +22 -0
  103. package/src/components/Title.js +18 -0
  104. package/src/components/Toast.js +16 -0
  105. package/src/components/ToastStack.js +21 -0
  106. package/src/components/Tooltip.js +12 -0
  107. package/src/hooks/useDisclosure.js +13 -0
  108. package/src/index.js +98 -0
  109. package/src/theme/fonts/Arimo-400.ttf +0 -0
  110. package/src/theme/fonts/Arimo-500.ttf +1449 -0
  111. package/src/theme/fonts/Arimo-600.ttf +1449 -0
  112. package/src/theme/fonts/Arimo-700.ttf +0 -0
  113. package/src/theme/fonts/Inter-400.woff2 +0 -0
  114. package/src/theme/fonts/Inter-500.woff2 +0 -0
  115. package/src/theme/fonts/Inter-600.woff2 +0 -0
  116. package/src/theme/fonts/Inter-700.woff2 +0 -0
  117. package/src/theme/fonts/Poppins-400.ttf +0 -0
  118. package/src/theme/fonts/Poppins-500.ttf +0 -0
  119. package/src/theme/fonts/Poppins-600.ttf +0 -0
  120. package/src/theme/fonts/Poppins-700.ttf +0 -0
  121. package/src/theme/icons.js +10 -0
  122. package/src/theme/styles.js +3630 -0
  123. package/src/theme/theme.js +71 -0
  124. package/src/utils.js +75 -0
  125. package/types/components/Accordion.d.ts +1 -0
  126. package/types/components/ActionIcon.d.ts +1 -0
  127. package/types/components/Affix.d.ts +1 -0
  128. package/types/components/Alert.d.ts +1 -0
  129. package/types/components/Anchor.d.ts +1 -0
  130. package/types/components/AppBar.d.ts +1 -0
  131. package/types/components/Avatar.d.ts +1 -0
  132. package/types/components/AvatarGroup.d.ts +1 -0
  133. package/types/components/Badge.d.ts +1 -0
  134. package/types/components/BadgeGroup.d.ts +1 -0
  135. package/types/components/Blockquote.d.ts +1 -0
  136. package/types/components/BottomBar.d.ts +4 -0
  137. package/types/components/Breadcrumbs.d.ts +1 -0
  138. package/types/components/Burger.d.ts +1 -0
  139. package/types/components/Button.d.ts +1 -0
  140. package/types/components/Calendar.d.ts +1 -0
  141. package/types/components/Card.d.ts +1 -0
  142. package/types/components/Center.d.ts +1 -0
  143. package/types/components/Checkbox.d.ts +1 -0
  144. package/types/components/CheckboxGroup.d.ts +1 -0
  145. package/types/components/Chip.d.ts +1 -0
  146. package/types/components/Code.d.ts +1 -0
  147. package/types/components/Col.d.ts +1 -0
  148. package/types/components/Collapse.d.ts +1 -0
  149. package/types/components/Container.d.ts +1 -0
  150. package/types/components/CopyButton.d.ts +1 -0
  151. package/types/components/DateInput.d.ts +1 -0
  152. package/types/components/DatePicker.d.ts +1 -0
  153. package/types/components/Divider.d.ts +1 -0
  154. package/types/components/Drawer.d.ts +1 -0
  155. package/types/components/EventCalendar.d.ts +1 -0
  156. package/types/components/Fieldset.d.ts +1 -0
  157. package/types/components/Flex.d.ts +1 -0
  158. package/types/components/Grid.d.ts +1 -0
  159. package/types/components/GridTable.d.ts +5 -0
  160. package/types/components/Group.d.ts +1 -0
  161. package/types/components/HoverCard.d.ts +1 -0
  162. package/types/components/Icon.d.ts +1 -0
  163. package/types/components/Image.d.ts +1 -0
  164. package/types/components/Indicator.d.ts +1 -0
  165. package/types/components/Kbd.d.ts +1 -0
  166. package/types/components/List.d.ts +5 -0
  167. package/types/components/Loading.d.ts +1 -0
  168. package/types/components/LoadingOverlay.d.ts +1 -0
  169. package/types/components/Menu.d.ts +2 -0
  170. package/types/components/Modal.d.ts +1 -0
  171. package/types/components/MultiSelect.d.ts +1 -0
  172. package/types/components/NavLink.d.ts +1 -0
  173. package/types/components/Notification.d.ts +1 -0
  174. package/types/components/Notifications.d.ts +1 -0
  175. package/types/components/NumberField.d.ts +1 -0
  176. package/types/components/NumberInput.d.ts +1 -0
  177. package/types/components/Pagination.d.ts +1 -0
  178. package/types/components/Paper.d.ts +1 -0
  179. package/types/components/PasswordInput.d.ts +1 -0
  180. package/types/components/PinInput.d.ts +1 -0
  181. package/types/components/Popover.d.ts +1 -0
  182. package/types/components/Popper.d.ts +1 -0
  183. package/types/components/Progress.d.ts +1 -0
  184. package/types/components/ProgressRing.d.ts +1 -0
  185. package/types/components/Radio.d.ts +1 -0
  186. package/types/components/RadioGroup.d.ts +1 -0
  187. package/types/components/RangePicker.d.ts +1 -0
  188. package/types/components/RangeSlider.d.ts +1 -0
  189. package/types/components/Rating.d.ts +1 -0
  190. package/types/components/ScrollArea.d.ts +1 -0
  191. package/types/components/SearchInput.d.ts +1 -0
  192. package/types/components/SegmentedControl.d.ts +1 -0
  193. package/types/components/Select.d.ts +1 -0
  194. package/types/components/SelectSearch.d.ts +1 -0
  195. package/types/components/Sidebar.d.ts +1 -0
  196. package/types/components/SimpleGrid.d.ts +1 -0
  197. package/types/components/Skeleton.d.ts +1 -0
  198. package/types/components/Slider.d.ts +5 -0
  199. package/types/components/Space.d.ts +1 -0
  200. package/types/components/Stack.d.ts +1 -0
  201. package/types/components/Stepper.d.ts +1 -0
  202. package/types/components/Switch.d.ts +1 -0
  203. package/types/components/SwitchGroup.d.ts +1 -0
  204. package/types/components/Table.d.ts +1 -0
  205. package/types/components/Tabs.d.ts +1 -0
  206. package/types/components/Tag.d.ts +1 -0
  207. package/types/components/Text.d.ts +1 -0
  208. package/types/components/TextInput.d.ts +1 -0
  209. package/types/components/Textarea.d.ts +1 -0
  210. package/types/components/Timeline.d.ts +1 -0
  211. package/types/components/Title.d.ts +1 -0
  212. package/types/components/Toast.d.ts +1 -0
  213. package/types/components/ToastStack.d.ts +1 -0
  214. package/types/components/Tooltip.d.ts +1 -0
  215. package/types/hooks/useDisclosure.d.ts +1 -0
  216. package/types/index.d.ts +93 -0
  217. package/types/theme/icons.d.ts +10 -0
  218. package/types/theme/styles.d.ts +1 -0
  219. package/types/theme/theme.d.ts +2 -0
  220. package/types/utils.d.ts +12 -0
@@ -0,0 +1,194 @@
1
+ import { Button, Div, state, after, list, when } from '@granularjs/core';
2
+ import { cx, splitPropsChildren, classMap, classVar, resolveValue, resolveBool } from '../utils.js';
3
+
4
+ export function Tabs(...args) {
5
+ const { props, rawProps } = splitPropsChildren(args, {
6
+ tabs: [],
7
+ orientation: 'horizontal',
8
+ variant: 'default',
9
+ sticky: true,
10
+ });
11
+ const { value, tabs, orientation, variant, sticky, className, style } = props;
12
+ const { onChange } = rawProps;
13
+
14
+ const currentState = state(resolveValue(value) ?? resolveValue(tabs)?.[0]?.value ?? '');
15
+ const sentinelNode = state();
16
+ const listNode = state();
17
+ const spacerHeight = state(0);
18
+ const stickyLeft = state(0);
19
+ const stickyWidth = state(0);
20
+ const stickyTop = state(0);
21
+ const isSticky = state(false);
22
+ const lastScrollTop = state(0);
23
+ let listening = false;
24
+ let rafId = null;
25
+ let initScheduled = false;
26
+ const listenerTargets = new Set();
27
+
28
+ after(value).change((next) => {
29
+ const resolved = resolveValue(next);
30
+ if (resolved == null) return;
31
+ currentState.set(resolved);
32
+ });
33
+
34
+ const setValue = (next) => {
35
+ currentState.set(next);
36
+ onChange?.(next);
37
+ };
38
+
39
+ const getScrollParents = (node) => {
40
+ const parents = [];
41
+ let current = node?.parentElement;
42
+ while (current) {
43
+ const style = getComputedStyle(current);
44
+ const overflow = `${style.overflow}${style.overflowY}${style.overflowX}`;
45
+ if (/(auto|scroll)/.test(overflow)) {
46
+ parents.push(current);
47
+ }
48
+ current = current.parentElement;
49
+ }
50
+ return parents;
51
+ };
52
+
53
+ const getScrollRoot = (node) => getScrollParents(node)[0] ?? null;
54
+
55
+ const getRootTop = (root) => (root ? root.getBoundingClientRect().top : 0);
56
+
57
+ const getScrollTop = (root) => (root ? root.scrollTop : (window.scrollY || window.pageYOffset || 0));
58
+
59
+ const getScrollDirection = (current, last) => {
60
+ if (current > last) return 'down';
61
+ if (current < last) return 'up';
62
+ return 'none';
63
+ };
64
+
65
+ const getNextSticky = (direction, sentinelTop, rootTop, currentSticky) => {
66
+ if (direction === 'down' && sentinelTop < rootTop) return true;
67
+ if (direction === 'up' && sentinelTop >= rootTop) return false;
68
+ return currentSticky;
69
+ };
70
+
71
+ const updateSticky = () => {
72
+ const sentinelEl = sentinelNode.get();
73
+ const listEl = listNode.get();
74
+ if (!sentinelEl || !listEl) return;
75
+ if (!resolveBool(sticky)) {
76
+ isSticky.set(false);
77
+ spacerHeight.set(0);
78
+ return;
79
+ }
80
+ if (typeof window === 'undefined') return;
81
+
82
+ const sentinelRect = sentinelEl.getBoundingClientRect();
83
+ const listRect = listEl.getBoundingClientRect();
84
+ const root = getScrollRoot(sentinelEl);
85
+ const rootTop = getRootTop(root);
86
+ const currentScrollTop = getScrollTop(root);
87
+ const direction = getScrollDirection(currentScrollTop, lastScrollTop.get());
88
+ lastScrollTop.set(currentScrollTop);
89
+
90
+ const nextSticky = getNextSticky(direction, sentinelRect.top, rootTop, isSticky.get());
91
+
92
+ spacerHeight.set(listRect.height);
93
+ stickyLeft.set(sentinelRect.left);
94
+ stickyWidth.set(sentinelRect.width);
95
+ stickyTop.set(rootTop);
96
+ if (nextSticky !== isSticky.get()) {
97
+ isSticky.set(nextSticky);
98
+ }
99
+ };
100
+
101
+ const scheduleUpdate = () => {
102
+ if (rafId != null) return;
103
+ rafId = requestAnimationFrame(() => {
104
+ rafId = null;
105
+ updateSticky();
106
+ });
107
+ };
108
+
109
+ const addListenerTarget = (target) => {
110
+ if (!target || listenerTargets.has(target)) return;
111
+ listenerTargets.add(target);
112
+ target.addEventListener('scroll', scheduleUpdate, { passive: true });
113
+ };
114
+
115
+ const initListeners = () => {
116
+ if (listening) return;
117
+ const sentinelEl = sentinelNode.get();
118
+ const listEl = listNode.get();
119
+ if (!sentinelEl || !listEl) return;
120
+ if (typeof window === 'undefined') return;
121
+ listening = true;
122
+ updateSticky();
123
+ addListenerTarget(window);
124
+ window.addEventListener('resize', scheduleUpdate);
125
+ getScrollParents(sentinelEl).forEach(addListenerTarget);
126
+ };
127
+
128
+ after(listNode, sentinelNode, sticky).change(initListeners);
129
+
130
+ if (!initScheduled && typeof window !== 'undefined') {
131
+ initScheduled = true;
132
+ setTimeout(() => initListeners(), 0);
133
+ }
134
+
135
+ const stickyStyle = after(isSticky, stickyLeft, stickyWidth, stickyTop).compute((values) => {
136
+ const [active, left, width, top] = values;
137
+ if (!active) {
138
+ return {
139
+ position: 'static',
140
+ top: 'auto',
141
+ left: 'auto',
142
+ width: 'auto',
143
+ zIndex: 'auto',
144
+ background: 'transparent',
145
+ };
146
+ }
147
+ return {
148
+ position: 'fixed',
149
+ top: `${top}px`,
150
+ left: `${left}px`,
151
+ width: `${width}px`,
152
+ background: 'var(--g-ui-surface)',
153
+ zIndex: 100,
154
+ };
155
+ });
156
+
157
+ const spacerStyle = after(isSticky, spacerHeight).compute((values) => {
158
+ const [active, height] = values;
159
+ return { height: active ? `${height}px` : '0px' };
160
+ });
161
+
162
+ return Div(
163
+ Div(
164
+ {
165
+ className: cx(
166
+ 'g-ui-tabs',
167
+ classMap(orientation, { vertical: 'g-ui-tabs-vertical' }),
168
+ classVar('g-ui-tabs-variant-', variant, 'default'),
169
+ props.className ?? className
170
+ ),
171
+ },
172
+ Div({ node: sentinelNode }),
173
+ Div({ style: spacerStyle }),
174
+ Div(
175
+ { node: listNode, className: 'g-ui-tabs-list', style: stickyStyle },
176
+ list(tabs, (tab) =>
177
+ Button(
178
+ {
179
+ className: after(currentState, tab.value).compute(([v, tabVal]) =>
180
+ cx('g-ui-tabs-tab', tabVal === v && 'g-ui-tabs-tab-active')
181
+ ),
182
+ onClick: () => setValue(tab.value.get()),
183
+ },
184
+ tab.label
185
+ )
186
+ )
187
+ ),
188
+ Div(
189
+ { className: 'g-ui-tabs-panel' },
190
+ when(currentState, () => tabs.get()?.find((tab) => tab.value === currentState.get())?.content ?? null)
191
+ )
192
+ )
193
+ );
194
+ }
@@ -0,0 +1,8 @@
1
+ import { Span } from '@granularjs/core';
2
+ import { cx, splitPropsChildren } from '../utils.js';
3
+
4
+ export function Tag(...args) {
5
+ const { props, children } = splitPropsChildren(args);
6
+ const { className, ...rest } = props;
7
+ return Span({ ...rest, className: cx('g-ui-tag', className) }, children);
8
+ }
@@ -0,0 +1,42 @@
1
+ import { Span } from '@granularjs/core';
2
+ import { cx, splitPropsChildren, classVar, classFlag, classMap } from '../utils.js';
3
+
4
+ export function Text(...args) {
5
+ const { props, children } = splitPropsChildren(args, { size: 'md' });
6
+ const { size, weight, color, dimmed, align, className, style, ...rest } = props;
7
+ const weightClass = classMap(weight, {
8
+ bold: 'g-ui-text-weight-700',
9
+ semibold: 'g-ui-text-weight-600',
10
+ medium: 'g-ui-text-weight-500',
11
+ 700: 'g-ui-text-weight-700',
12
+ 600: 'g-ui-text-weight-600',
13
+ 500: 'g-ui-text-weight-500',
14
+ 400: 'g-ui-text-weight-400',
15
+ });
16
+ const colorClass = classMap(color, {
17
+ primary: 'g-ui-text-primary',
18
+ success: 'g-ui-text-success',
19
+ danger: 'g-ui-text-danger',
20
+ muted: 'g-ui-text-dimmed',
21
+ });
22
+ const alignClass = classMap(align, {
23
+ center: 'g-ui-text-align-center',
24
+ right: 'g-ui-text-align-right',
25
+ left: 'g-ui-text-align-left',
26
+ });
27
+ return Span(
28
+ {
29
+ ...rest,
30
+ className: cx(
31
+ 'g-ui-text',
32
+ classVar('g-ui-text-size-', size, 'md'),
33
+ classFlag('g-ui-text-dimmed', dimmed),
34
+ weightClass,
35
+ colorClass,
36
+ alignClass,
37
+ className
38
+ ),
39
+ },
40
+ children
41
+ );
42
+ }
@@ -0,0 +1,74 @@
1
+ import { Div, Input, Textarea as HtmlTextarea, Label, Span, when, state, after, isState } from '@granularjs/core';
2
+ import { cx, splitPropsChildren, classFlag, classVar, resolveValue, resolveBool } from '../utils.js';
3
+
4
+ export function TextInput(...args) {
5
+ const { props, rawProps } = splitPropsChildren(args, { size: 'md' });
6
+ const {
7
+ label,
8
+ description,
9
+ error,
10
+ size,
11
+ leftSection,
12
+ rightSection,
13
+ className,
14
+ inputClassName,
15
+ multiline,
16
+ value: computed_value,
17
+ ...rest
18
+ } = props;
19
+ const { value: raw_value, onChange, onInput, onFocus, onBlur, onKeyDown, onKeyUp, onClick } = rawProps;
20
+
21
+ const isValueTwoWay = isState(raw_value) && !onChange && !onInput
22
+ const currentState = isValueTwoWay ? raw_value : state(resolveValue(computed_value) ?? '');
23
+
24
+ after(computed_value).change((next) => {
25
+ if (isValueTwoWay) return;
26
+ currentState.set(resolveValue(next) ?? '');
27
+ });
28
+
29
+ const handleInput = (ev) => {
30
+ const next = ev?.target?.value ?? '';
31
+ if (next === computed_value.get()) return;
32
+ currentState.set(next);
33
+ onChange?.(ev);
34
+ onInput?.(ev);
35
+ };
36
+
37
+ const isMultiline = resolveBool(multiline);
38
+ const Control = isMultiline ? HtmlTextarea : Input;
39
+ const finalInputClassName = cx(inputClassName, isMultiline && 'g-ui-textarea');
40
+
41
+ const input = Control({
42
+ ...rest,
43
+ value: currentState,
44
+ onInput: handleInput,
45
+ onChange: handleInput,
46
+ onFocus,
47
+ onBlur,
48
+ onKeyDown,
49
+ onKeyUp,
50
+ onClick,
51
+ className: cx('g-ui-input', finalInputClassName),
52
+ });
53
+
54
+
55
+ return Div(
56
+ { className: cx('g-ui-text-input', className) },
57
+ when(label, () => Label({ className: 'g-ui-text-input-label' }, label)),
58
+ when(description, () => Span({ className: 'g-ui-text-input-description' }, description)),
59
+ Div(
60
+ {
61
+ className: cx(
62
+ 'g-ui-input-wrapper',
63
+ classFlag('g-ui-input-multiline', multiline),
64
+ classVar('g-ui-input-size-', size, 'md'),
65
+ classFlag('g-ui-input-error', error)
66
+ ),
67
+ },
68
+ when(leftSection, () => Div({ className: 'g-ui-input-section' }, leftSection)),
69
+ input,
70
+ when(rightSection, () => Div({ className: 'g-ui-input-section' }, rightSection))
71
+ ),
72
+ when(error, () => Div({ className: 'g-ui-text-input-error-text' }, error))
73
+ );
74
+ }
@@ -0,0 +1,15 @@
1
+ import { splitPropsChildren } from '../utils.js';
2
+ import { TextInput } from './TextInput.js';
3
+
4
+ export function Textarea(...args) {
5
+ const { props } = splitPropsChildren(args, { size: 'md' });
6
+ const { size, leftSection, rightSection, className, ...rest } = props;
7
+ return TextInput({
8
+ ...rest,
9
+ size,
10
+ className,
11
+ leftSection,
12
+ rightSection,
13
+ multiline: true,
14
+ });
15
+ }
@@ -0,0 +1,22 @@
1
+ import { Div, when } from '@granularjs/core';
2
+ import { cx, splitPropsChildren } from '../utils.js';
3
+
4
+ export function Timeline(...args) {
5
+ const { props } = splitPropsChildren(args, { items: [] });
6
+ const { items, className, ...rest } = props;
7
+ return Div(
8
+ { ...rest, className: cx('g-ui-timeline', className) },
9
+ items.map((item) =>
10
+ Div(
11
+ { className: 'g-ui-timeline-item' },
12
+ Div({ className: 'g-ui-timeline-dot' }),
13
+ Div(
14
+ { className: 'g-ui-timeline-content' },
15
+ when(item.title, () => Div({ className: 'g-ui-timeline-title' }, item.title)),
16
+ when(item.description, () => Div({ className: 'g-ui-timeline-desc' }, item.description)),
17
+ item.content
18
+ )
19
+ )
20
+ )
21
+ );
22
+ }
@@ -0,0 +1,18 @@
1
+ import { H1, H2, H3, H4, H5, H6 } from '@granularjs/core';
2
+ import { cx, splitPropsChildren, resolveValue, classVar } from '../utils.js';
3
+
4
+ const map = { 1: H1, 2: H2, 3: H3, 4: H4, 5: H5, 6: H6 };
5
+
6
+ export function Title(...args) {
7
+ const { props, children } = splitPropsChildren(args, { order: 2 });
8
+ const { order, className, style, ...rest } = props;
9
+ const orderValue = resolveValue(order) || 2;
10
+ const Tag = map[orderValue] || H2;
11
+ return Tag(
12
+ {
13
+ ...rest,
14
+ className: cx('g-ui-title', classVar('g-ui-title-order-', order, 2), className),
15
+ },
16
+ children
17
+ );
18
+ }
@@ -0,0 +1,16 @@
1
+ import { Div, Button, when } from '@granularjs/core';
2
+ import { cx, splitPropsChildren } from '../utils.js';
3
+
4
+ export function Toast(...args) {
5
+ const { props, children } = splitPropsChildren(args);
6
+ const { title, onClose, className, ...rest } = props;
7
+ return Div(
8
+ { ...rest, className: cx('g-ui-toast', className) },
9
+ Div(
10
+ { className: 'g-ui-toast-row' },
11
+ when(title, () => Div({ className: 'g-ui-toast-title' }, title)),
12
+ when(onClose, () => Button({ className: 'g-ui-toast-close', onClick: onClose }, '×'))
13
+ ),
14
+ children
15
+ );
16
+ }
@@ -0,0 +1,21 @@
1
+ import { Div, when } from '@granularjs/core';
2
+ import { cx, splitPropsChildren } from '../utils.js';
3
+
4
+ export function ToastStack(...args) {
5
+ const { props } = splitPropsChildren(args, { items: [] });
6
+ const { items, className, onClose, timeout, ...rest } = props;
7
+ return Div(
8
+ { ...rest, className: cx('g-ui-toast-stack', className) },
9
+ items.map((item) =>
10
+ Div(
11
+ { className: cx('g-ui-toast', [timeout, 'g-ui-toast-auto']) },
12
+ Div(
13
+ { className: 'g-ui-toast-row' },
14
+ when(item.title, () => Div({ className: 'g-ui-toast-title' }, item.title)),
15
+ when(onClose, () => Div({ className: 'g-ui-toast-close', onClick: () => onClose(item) }, '×'))
16
+ ),
17
+ item.message
18
+ )
19
+ )
20
+ );
21
+ }
@@ -0,0 +1,12 @@
1
+ import { Span } from '@granularjs/core';
2
+ import { cx, splitPropsChildren } from '../utils.js';
3
+
4
+ export function Tooltip(...args) {
5
+ const { props, children } = splitPropsChildren(args);
6
+ const { label, className, style } = props;
7
+ return Span(
8
+ { className: cx('g-ui-tooltip', className) },
9
+ children,
10
+ Span({ className: 'g-ui-tooltip-content' }, label)
11
+ );
12
+ }
@@ -0,0 +1,13 @@
1
+ import { state } from '@granularjs/core';
2
+
3
+ export function useDisclosure(initial = false) {
4
+ const opened = state(!!initial);
5
+ return [
6
+ opened,
7
+ {
8
+ open: () => opened.set(true),
9
+ close: () => opened.set(false),
10
+ toggle: () => opened.set(!opened.get()),
11
+ },
12
+ ];
13
+ }
package/src/index.js ADDED
@@ -0,0 +1,98 @@
1
+ import { ensureStyles } from './theme/styles.js';
2
+
3
+ ensureStyles();
4
+
5
+ export { setThemeVars, setThemeMode } from './theme/theme.js';
6
+ export { cx } from './utils.js';
7
+ export { Button } from './components/Button.js';
8
+ export { Text } from './components/Text.js';
9
+ export { Title } from './components/Title.js';
10
+ export { Container } from './components/Container.js';
11
+ export { Stack } from './components/Stack.js';
12
+ export { Group } from './components/Group.js';
13
+ export { Card } from './components/Card.js';
14
+ export { Badge } from './components/Badge.js';
15
+ export { TextInput } from './components/TextInput.js';
16
+ export { Textarea } from './components/Textarea.js';
17
+ export { NumberInput } from './components/NumberInput.js';
18
+ export { Modal } from './components/Modal.js';
19
+ export { Loading } from './components/Loading.js';
20
+ export { Checkbox } from './components/Checkbox.js';
21
+ export { Switch } from './components/Switch.js';
22
+ export { Select } from './components/Select.js';
23
+ export { Tabs } from './components/Tabs.js';
24
+ export { Table } from './components/Table.js';
25
+ export { Accordion } from './components/Accordion.js';
26
+ export { Tooltip } from './components/Tooltip.js';
27
+ export { Menu } from './components/Menu.js';
28
+ export { Drawer } from './components/Drawer.js';
29
+ export { Notification } from './components/Notification.js';
30
+ export { Divider } from './components/Divider.js';
31
+ export { Paper } from './components/Paper.js';
32
+ export { Alert } from './components/Alert.js';
33
+ export { Avatar } from './components/Avatar.js';
34
+ export { Kbd } from './components/Kbd.js';
35
+ export { Code } from './components/Code.js';
36
+ export { Blockquote } from './components/Blockquote.js';
37
+ export { SimpleGrid } from './components/SimpleGrid.js';
38
+ export { List } from './components/List.js';
39
+ export { Anchor } from './components/Anchor.js';
40
+ export { Image } from './components/Image.js';
41
+ export { Icon } from './components/Icon.js';
42
+ export { Progress } from './components/Progress.js';
43
+ export { Slider } from './components/Slider.js';
44
+ export { Skeleton } from './components/Skeleton.js';
45
+ export { Chip } from './components/Chip.js';
46
+ export { SegmentedControl } from './components/SegmentedControl.js';
47
+ export { Pagination } from './components/Pagination.js';
48
+ export { Radio } from './components/Radio.js';
49
+ export { RadioGroup } from './components/RadioGroup.js';
50
+ export { Breadcrumbs } from './components/Breadcrumbs.js';
51
+ export { Center } from './components/Center.js';
52
+ export { Space } from './components/Space.js';
53
+ export { Collapse } from './components/Collapse.js';
54
+ export { ActionIcon } from './components/ActionIcon.js';
55
+ export { Popover } from './components/Popover.js';
56
+ export { HoverCard } from './components/HoverCard.js';
57
+ export { Affix } from './components/Affix.js';
58
+ export { Fieldset } from './components/Fieldset.js';
59
+ export { AppBar } from './components/AppBar.js';
60
+ export { Sidebar } from './components/Sidebar.js';
61
+ export { Timeline } from './components/Timeline.js';
62
+ export { Stepper } from './components/Stepper.js';
63
+ export { Rating } from './components/Rating.js';
64
+ export { Tag } from './components/Tag.js';
65
+ export { Calendar } from './components/Calendar.js';
66
+ export { MultiSelect } from './components/MultiSelect.js';
67
+ export { ToastStack } from './components/ToastStack.js';
68
+ export { DatePicker } from './components/DatePicker.js';
69
+ export { Notifications } from './components/Notifications.js';
70
+ export { RangeSlider } from './components/RangeSlider.js';
71
+ export { DateInput } from './components/DateInput.js';
72
+ export { NumberField } from './components/NumberField.js';
73
+ export { Popper } from './components/Popper.js';
74
+ export { PasswordInput } from './components/PasswordInput.js';
75
+ export { SearchInput } from './components/SearchInput.js';
76
+ export { CopyButton } from './components/CopyButton.js';
77
+ export { ProgressRing } from './components/ProgressRing.js';
78
+ export { Toast } from './components/Toast.js';
79
+ export { SelectSearch } from './components/SelectSearch.js';
80
+ export { SwitchGroup } from './components/SwitchGroup.js';
81
+ export { RangePicker } from './components/RangePicker.js';
82
+ export { Flex } from './components/Flex.js';
83
+ export { NavLink } from './components/NavLink.js';
84
+ export { Indicator } from './components/Indicator.js';
85
+ export { Burger } from './components/Burger.js';
86
+ export { LoadingOverlay } from './components/LoadingOverlay.js';
87
+ export { Grid } from './components/Grid.js';
88
+ export { Col } from './components/Col.js';
89
+ export { ScrollArea } from './components/ScrollArea.js';
90
+ export { PinInput } from './components/PinInput.js';
91
+ export { CheckboxGroup } from './components/CheckboxGroup.js';
92
+ export { AvatarGroup } from './components/AvatarGroup.js';
93
+ export { BadgeGroup } from './components/BadgeGroup.js';
94
+ export { GridTable } from './components/GridTable.js';
95
+ export { BottomBar } from './components/BottomBar.js';
96
+ export { EventCalendar } from './components/EventCalendar.js';
97
+ export { useDisclosure } from './hooks/useDisclosure.js';
98
+
Binary file