@admin-layout/tailwind-ui 12.2.4-alpha.12 → 12.2.4-alpha.16

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 (44) hide show
  1. package/lib/components/DatePicker/DatePicker.js +1 -1
  2. package/lib/components/InputToolBar/InputToolBar.d.ts +10 -0
  3. package/lib/components/InputToolBar/InputToolBar.d.ts.map +1 -0
  4. package/lib/components/InputToolBar/InputToolBar.js +225 -0
  5. package/lib/components/InputToolBar/InputToolBar.js.map +1 -0
  6. package/lib/components/InputToolBar/defaults.d.ts +14 -0
  7. package/lib/components/InputToolBar/defaults.d.ts.map +1 -0
  8. package/lib/components/InputToolBar/defaults.js +51 -0
  9. package/lib/components/InputToolBar/defaults.js.map +1 -0
  10. package/lib/components/InputToolBar/index.d.ts +5 -0
  11. package/lib/components/InputToolBar/index.d.ts.map +1 -0
  12. package/lib/components/InputToolBar/types.d.ts +61 -0
  13. package/lib/components/InputToolBar/types.d.ts.map +1 -0
  14. package/lib/components/Markdown/MarkdownBreadcrumbs.d.ts +13 -0
  15. package/lib/components/Markdown/MarkdownBreadcrumbs.d.ts.map +1 -0
  16. package/lib/components/Markdown/MarkdownBreadcrumbs.js +27 -0
  17. package/lib/components/Markdown/MarkdownBreadcrumbs.js.map +1 -0
  18. package/lib/components/Markdown/MarkdownCopyButton.d.ts +10 -0
  19. package/lib/components/Markdown/MarkdownCopyButton.d.ts.map +1 -0
  20. package/lib/components/Markdown/MarkdownCopyButton.js +200 -0
  21. package/lib/components/Markdown/MarkdownCopyButton.js.map +1 -0
  22. package/lib/components/Markdown/MarkdownHeader.d.ts +13 -0
  23. package/lib/components/Markdown/MarkdownHeader.d.ts.map +1 -0
  24. package/lib/components/Markdown/MarkdownHeader.js +29 -0
  25. package/lib/components/Markdown/MarkdownHeader.js.map +1 -0
  26. package/lib/components/Markdown/MarkdownNavigation.d.ts +15 -0
  27. package/lib/components/Markdown/MarkdownNavigation.d.ts.map +1 -0
  28. package/lib/components/Markdown/MarkdownNavigation.js +31 -0
  29. package/lib/components/Markdown/MarkdownNavigation.js.map +1 -0
  30. package/lib/components/Markdown/MarkdownPage.d.ts +41 -0
  31. package/lib/components/Markdown/MarkdownPage.d.ts.map +1 -0
  32. package/lib/components/Markdown/MarkdownPage.js +221 -0
  33. package/lib/components/Markdown/MarkdownPage.js.map +1 -0
  34. package/lib/components/Markdown/MarkdownTableOfContents.d.ts +15 -0
  35. package/lib/components/Markdown/MarkdownTableOfContents.d.ts.map +1 -0
  36. package/lib/components/Markdown/MarkdownTableOfContents.js +51 -0
  37. package/lib/components/Markdown/MarkdownTableOfContents.js.map +1 -0
  38. package/lib/components/Markdown/index.d.ts +7 -0
  39. package/lib/components/Markdown/index.d.ts.map +1 -0
  40. package/lib/components/Select/Select.js +1 -1
  41. package/lib/components/index.d.ts +2 -0
  42. package/lib/components/index.d.ts.map +1 -1
  43. package/lib/index.js +1 -1
  44. package/package.json +2 -2
@@ -197,4 +197,4 @@ import React__default,{useRef,useEffect}from'react';import {useActor}from'@xstat
197
197
  className: "px-2 py-0.5 text-xs text-blue-600 hover:bg-blue-50 transition-colors",
198
198
  onClick: () => handleDateSelect(new Date())
199
199
  }, "Today"))));
200
- };export{DatePicker};//# sourceMappingURL=DatePicker.js.map
200
+ };export{DatePicker,DatePicker as default};//# sourceMappingURL=DatePicker.js.map
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { InputToolBarProps } from './types';
3
+ /**
4
+ * InputToolBar – horizontal toolbar for text input UIs (e.g. chat/composer).
5
+ * Data and behavior are passed via props; items can be enabled/disabled, and custom left/right content can be injected.
6
+ * Layout: left (mode toggles + template pill), flexible middle, right (attach, capture, mic/send).
7
+ */
8
+ export declare function InputToolBar({ className, leftItems, rightItems, templateButton, leftCustomRender, rightCustomRender, micSendButton, children, }: InputToolBarProps): React.JSX.Element;
9
+ export default InputToolBar;
10
+ //# sourceMappingURL=InputToolBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputToolBar.d.ts","sourceRoot":"","sources":["../../../src/components/InputToolBar/InputToolBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EACR,iBAAiB,EAMpB,MAAM,SAAS,CAAC;AAuMjB;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EACzB,SAAS,EACT,SAAS,EACT,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,QAAQ,GACX,EAAE,iBAAiB,qBAgCnB;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,225 @@
1
+ import {Lightbulb,Zap,Search,Mic,Paperclip,Camera,Tag,ArrowUpRight}from'lucide-react';import React__default from'react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const iconSize = 'h-3.5 w-3.5';
2
+ const iconSizeRight = 'h-4 w-4';
3
+ const defaultLeftIconMap = {
4
+ search: React__default.createElement(Search, {
5
+ className: iconSize
6
+ }),
7
+ zap: React__default.createElement(Zap, {
8
+ className: iconSize
9
+ }),
10
+ lightbulb: React__default.createElement(Lightbulb, {
11
+ className: iconSize
12
+ }),
13
+ template: null // template is rendered as pill, not in icon group
14
+ };
15
+ const defaultRightIconMap = {
16
+ tag: React__default.createElement(Tag, {
17
+ className: iconSizeRight
18
+ }),
19
+ chip: React__default.createElement("svg", {
20
+ className: iconSizeRight,
21
+ viewBox: "0 0 24 24",
22
+ fill: "none",
23
+ stroke: "currentColor",
24
+ strokeWidth: "2",
25
+ strokeLinecap: "round",
26
+ strokeLinejoin: "round",
27
+ "aria-hidden": true
28
+ }, React__default.createElement("rect", {
29
+ x: "4",
30
+ y: "4",
31
+ width: "16",
32
+ height: "16",
33
+ rx: "2",
34
+ ry: "2"
35
+ }), React__default.createElement("line", {
36
+ x1: "9",
37
+ y1: "9",
38
+ x2: "15",
39
+ y2: "9"
40
+ }), React__default.createElement("line", {
41
+ x1: "9",
42
+ y1: "15",
43
+ x2: "15",
44
+ y2: "15"
45
+ }), React__default.createElement("line", {
46
+ x1: "9",
47
+ y1: "9",
48
+ x2: "9",
49
+ y2: "15"
50
+ }), React__default.createElement("line", {
51
+ x1: "15",
52
+ y1: "9",
53
+ x2: "15",
54
+ y2: "15"
55
+ })),
56
+ camera: React__default.createElement(Camera, {
57
+ className: iconSizeRight
58
+ }),
59
+ attach: React__default.createElement(Paperclip, {
60
+ className: iconSizeRight
61
+ }),
62
+ mic: React__default.createElement(Mic, {
63
+ className: iconSizeRight
64
+ })
65
+ };
66
+ function MicSendButton({
67
+ hasContent,
68
+ onSend,
69
+ onMic,
70
+ disabled
71
+ }) {
72
+ const isSend = hasContent;
73
+ const base = 'inline-flex h-7 w-7 items-center justify-center rounded-2xl transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary';
74
+ return React__default.createElement("button", {
75
+ type: "button",
76
+ "aria-label": isSend ? 'Send' : 'Start voice input',
77
+ title: isSend ? 'Send' : 'Start voice input',
78
+ onClick: isSend ? onSend : onMic,
79
+ disabled: disabled,
80
+ className: base
81
+ }, isSend ? React__default.createElement(ArrowUpRight, {
82
+ className: iconSizeRight
83
+ }) : React__default.createElement(Mic, {
84
+ className: iconSizeRight
85
+ }));
86
+ }
87
+ function ToolbarIconButton({
88
+ item,
89
+ getDefaultIcon,
90
+ isLeftGroup
91
+ }) {
92
+ if (item.enabled === false) return null;
93
+ const icon = item.customButton ?? item.icon ?? getDefaultIcon(item.id);
94
+ if (item.customButton) {
95
+ return React__default.createElement(React__default.Fragment, null, item.customButton);
96
+ }
97
+ const isActive = item.active === true;
98
+ const base = 'inline-flex h-7 w-7 items-center justify-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:opacity-50 disabled:pointer-events-none';
99
+ const leftVariant = isActive ? 'rounded-full border border-primary bg-primary text-primary-foreground hover:bg-primary/90' : 'rounded-full border border-primary/50 bg-card text-primary hover:border-primary hover:text-primary';
100
+ const rightVariant = 'rounded-2xl text-muted-foreground hover:bg-secondary/70 active:bg-secondary';
101
+ return React__default.createElement("button", {
102
+ type: "button",
103
+ "aria-label": item.label,
104
+ title: item.label,
105
+ onClick: item.onClick,
106
+ className: cn(base, isLeftGroup ? leftVariant : rightVariant)
107
+ }, icon);
108
+ }
109
+ function LeftSection({
110
+ leftItems,
111
+ templateButton,
112
+ leftCustomRender
113
+ }) {
114
+ if (leftCustomRender != null) {
115
+ return React__default.createElement("div", {
116
+ className: "flex items-center gap-2"
117
+ }, leftCustomRender);
118
+ }
119
+ const left = leftItems ?? [];
120
+ const hasTemplate = templateButton != null;
121
+ const hasLeft = left.length > 0 || hasTemplate;
122
+ if (!hasLeft) return null;
123
+ return React__default.createElement("div", {
124
+ className: "flex items-center gap-2"
125
+ }, left.length > 0 && React__default.createElement("div", {
126
+ className: "flex items-center gap-1 rounded-full bg-secondary px-2 py-1"
127
+ }, left.map((item, index) => React__default.createElement(React__default.Fragment, {
128
+ key: item.id
129
+ }, React__default.createElement(ToolbarIconButton, {
130
+ item: item,
131
+ getDefaultIcon: id => defaultLeftIconMap[id] ?? null,
132
+ isLeftGroup: true
133
+ }), index < left.length - 1 && React__default.createElement("span", {
134
+ "aria-hidden": "true",
135
+ className: "mx-1 h-5 w-px bg-border/70"
136
+ })))), hasTemplate && React__default.createElement(TemplatePill, {
137
+ label: templateButton.label,
138
+ count: templateButton.count,
139
+ onClick: templateButton.onClick,
140
+ disabled: templateButton.disabled
141
+ }));
142
+ }
143
+ function TemplatePill({
144
+ label,
145
+ count,
146
+ onClick,
147
+ disabled
148
+ }) {
149
+ const text = count != null && count > 0 ? `${label} (${count})` : label;
150
+ return React__default.createElement("button", {
151
+ type: "button",
152
+ onClick: onClick,
153
+ disabled: disabled,
154
+ className: cn('flex items-center gap-1 rounded-full border border-border bg-card px-2 py-1 text-xs font-medium text-foreground transition-colors hover:border-primary hover:bg-primary/5', disabled && 'opacity-50 cursor-not-allowed' || ''),
155
+ "aria-label": "Select template"
156
+ }, text);
157
+ }
158
+ function RightSection({
159
+ rightItems,
160
+ rightCustomRender,
161
+ micSendButton
162
+ }) {
163
+ if (rightCustomRender != null) {
164
+ return React__default.createElement("div", {
165
+ className: "flex items-center gap-1"
166
+ }, rightCustomRender);
167
+ }
168
+ const right = rightItems ?? [];
169
+ const filteredRight = micSendButton != null ? right.filter(item => item.id !== 'mic') : right;
170
+ const hasRight = filteredRight.length > 0 || micSendButton != null;
171
+ if (!hasRight) return null;
172
+ return React__default.createElement("div", {
173
+ className: "flex flex-wrap items-center gap-1 text-muted-foreground"
174
+ }, filteredRight.map(item => React__default.createElement(ToolbarIconButton, {
175
+ key: item.id,
176
+ item: item,
177
+ getDefaultIcon: id => defaultRightIconMap[id] ?? null
178
+ })), micSendButton != null && React__default.createElement(MicSendButton, {
179
+ hasContent: micSendButton.hasContent,
180
+ onSend: micSendButton.onSend,
181
+ onMic: micSendButton.onMic,
182
+ disabled: micSendButton.disabled
183
+ }));
184
+ }
185
+ /**
186
+ * InputToolBar – horizontal toolbar for text input UIs (e.g. chat/composer).
187
+ * Data and behavior are passed via props; items can be enabled/disabled, and custom left/right content can be injected.
188
+ * Layout: left (mode toggles + template pill), flexible middle, right (attach, capture, mic/send).
189
+ */
190
+ function InputToolBar({
191
+ className,
192
+ leftItems,
193
+ rightItems,
194
+ templateButton,
195
+ leftCustomRender,
196
+ rightCustomRender,
197
+ micSendButton,
198
+ children
199
+ }) {
200
+ const hasChildren = children != null;
201
+ return React__default.createElement("section", {
202
+ className: cn('w-full overflow-visible rounded-[24px] border border-border/70 bg-card shadow-md', hasChildren && 'cursor-text', className)
203
+ }, React__default.createElement("div", {
204
+ className: cn('flex px-3 py-2', hasChildren ? 'flex-col gap-2' : 'flex-wrap items-center gap-3')
205
+ }, hasChildren && React__default.createElement("div", {
206
+ className: "min-w-0 flex-1"
207
+ }, children), React__default.createElement("div", {
208
+ className: cn('flex flex-wrap items-center gap-3', hasChildren && 'pt-2')
209
+ }, React__default.createElement("div", {
210
+ className: cn('flex items-center gap-2', hasChildren && 'mb-2')
211
+ }, React__default.createElement(LeftSection, {
212
+ leftItems: leftItems,
213
+ templateButton: templateButton,
214
+ leftCustomRender: leftCustomRender
215
+ })), !hasChildren && React__default.createElement("div", {
216
+ className: "min-w-0 flex-1",
217
+ "aria-hidden": true
218
+ }), React__default.createElement("div", {
219
+ className: "flex flex-1 flex-wrap items-center justify-end gap-2"
220
+ }, React__default.createElement(RightSection, {
221
+ rightItems: rightItems,
222
+ rightCustomRender: rightCustomRender,
223
+ micSendButton: micSendButton
224
+ })))));
225
+ }export{InputToolBar,InputToolBar as default};//# sourceMappingURL=InputToolBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputToolBar.js","sources":["../../../src/components/InputToolBar/InputToolBar.tsx"],"sourcesContent":[null],"names":["React"],"mappings":";;;AAqNG,EAAA,MAAA,EAAAA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AACH,IAAA,SAAA,EAAA;AA2CA,GAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,14 @@
1
+ import type { LeftToolbarItemId, RightToolbarItemId, ToolbarItemConfig } from './types';
2
+ export type LeftItemOverrides = Partial<Record<LeftToolbarItemId, Partial<Omit<ToolbarItemConfig<LeftToolbarItemId>, 'id'>>>>;
3
+ export type RightItemOverrides = Partial<Record<RightToolbarItemId, Partial<Omit<ToolbarItemConfig<RightToolbarItemId>, 'id'>>>>;
4
+ /**
5
+ * Build default left toolbar items (search, zap, lightbulb). Omit or set enabled: false to hide.
6
+ * Override label, enabled, active, onClick, icon, customButton per id.
7
+ */
8
+ export declare function getDefaultLeftItems(overrides?: LeftItemOverrides): ToolbarItemConfig<LeftToolbarItemId>[];
9
+ /**
10
+ * Build default right toolbar items (tag, chip, camera, attach, mic). Omit or set enabled: false to hide.
11
+ * Override label, enabled, active, onClick, icon, customButton per id.
12
+ */
13
+ export declare function getDefaultRightItems(overrides?: RightItemOverrides): ToolbarItemConfig<RightToolbarItemId>[];
14
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/components/InputToolBar/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAoBxF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CACnC,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CACvF,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACpC,MAAM,CAAC,kBAAkB,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CACzF,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,CAazG;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,EAAE,CAa5G"}
@@ -0,0 +1,51 @@
1
+ const DEFAULT_LEFT_IDS = ['search', 'zap', 'lightbulb'];
2
+ const DEFAULT_RIGHT_IDS = ['tag', 'chip', 'camera', 'attach', 'mic'];
3
+ const DEFAULT_LEFT_LABELS = {
4
+ search: 'Chat mode',
5
+ zap: 'Deep Search',
6
+ lightbulb: 'Build mode',
7
+ template: 'Template'
8
+ };
9
+ const DEFAULT_RIGHT_LABELS = {
10
+ tag: 'Tag',
11
+ chip: 'Module',
12
+ camera: 'Capture image',
13
+ attach: 'Attach file',
14
+ mic: 'Mic / Send'
15
+ };
16
+ /**
17
+ * Build default left toolbar items (search, zap, lightbulb). Omit or set enabled: false to hide.
18
+ * Override label, enabled, active, onClick, icon, customButton per id.
19
+ */
20
+ function getDefaultLeftItems(overrides) {
21
+ return DEFAULT_LEFT_IDS.map(id => {
22
+ const o = overrides?.[id];
23
+ return {
24
+ id,
25
+ label: o?.label ?? DEFAULT_LEFT_LABELS[id],
26
+ enabled: o?.enabled ?? true,
27
+ active: o?.active,
28
+ onClick: o?.onClick,
29
+ icon: o?.icon,
30
+ customButton: o?.customButton
31
+ };
32
+ });
33
+ }
34
+ /**
35
+ * Build default right toolbar items (tag, chip, camera, attach, mic). Omit or set enabled: false to hide.
36
+ * Override label, enabled, active, onClick, icon, customButton per id.
37
+ */
38
+ function getDefaultRightItems(overrides) {
39
+ return DEFAULT_RIGHT_IDS.map(id => {
40
+ const o = overrides?.[id];
41
+ return {
42
+ id,
43
+ label: o?.label ?? DEFAULT_RIGHT_LABELS[id],
44
+ enabled: o?.enabled ?? true,
45
+ active: o?.active,
46
+ onClick: o?.onClick,
47
+ icon: o?.icon,
48
+ customButton: o?.customButton
49
+ };
50
+ });
51
+ }export{getDefaultLeftItems,getDefaultRightItems};//# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sources":["../../../src/components/InputToolBar/defaults.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,MAAA,gBAAc,GAAA,CAAA,QAAmB,EAAA,KAAA,EAAA,WAAoB,CAAA;AAoBrD,MAAM,0BAA0B,EAAA,MAC5B,EAAA,QAAO,EAAA,QAAA,EAAA,KAAmB,CAAA;AAE9B,MAAM;AAIN,EAAA,MAAA,EAAA,WAAA;;;AAGG,EAAA,QAAA,EAAA;AACH,CAAA;AAeA,MAAA,oBAAA,GAAA;;;AAGG,EAAA,MAAA,EAAA,eAAA;AACH,EAAA,MAAA,EAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,5 @@
1
+ export { InputToolBar } from './InputToolBar';
2
+ export { getDefaultLeftItems, getDefaultRightItems } from './defaults';
3
+ export type { InputToolBarProps, LeftToolbarItemId, MicSendButtonConfig, RightToolbarItemId, TemplateButtonConfig, ToolbarItemConfig, } from './types';
4
+ export type { LeftItemOverrides, RightItemOverrides } from './defaults';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/InputToolBar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,YAAY,EACR,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Predefined toolbar action ids for left section (mode toggles, template) */
3
+ export type LeftToolbarItemId = 'search' | 'zap' | 'lightbulb' | 'template';
4
+ /** Predefined toolbar action ids for right section (attach, capture, mic/send) */
5
+ export type RightToolbarItemId = 'tag' | 'chip' | 'camera' | 'attach' | 'mic';
6
+ /** Single toolbar button/item configuration */
7
+ export interface ToolbarItemConfig<TId extends string = string> {
8
+ /** Unique id for the item (used for enable/disable and callbacks) */
9
+ id: TId;
10
+ /** Icon (React node) or custom content for the button */
11
+ icon?: ReactNode;
12
+ /** Accessible label / title */
13
+ label: string;
14
+ /** Whether the item is enabled (default true) */
15
+ enabled?: boolean;
16
+ /** Whether the item is in active/selected state (dark background in UI) */
17
+ active?: boolean;
18
+ /** Click handler */
19
+ onClick?: () => void;
20
+ /** Optional custom button element; when set, icon/label are ignored and this is rendered */
21
+ customButton?: ReactNode;
22
+ }
23
+ /** When provided, the rightmost button shows Send (arrow) when hasContent is true, else Mic. Replaces any "mic" item in rightItems. */
24
+ export interface MicSendButtonConfig {
25
+ /** True when input has content – show send icon; otherwise show mic icon */
26
+ hasContent: boolean;
27
+ onSend: () => void;
28
+ onMic: () => void;
29
+ disabled?: boolean;
30
+ }
31
+ /** Configuration for the optional "+ Template (N)" pill button */
32
+ export interface TemplateButtonConfig {
33
+ /** Button label prefix, e.g. "+ Template" */
34
+ label: string;
35
+ /** Count to show in parentheses, e.g. (1) */
36
+ count?: number;
37
+ /** Click handler */
38
+ onClick?: () => void;
39
+ /** Disabled state */
40
+ disabled?: boolean;
41
+ }
42
+ /** Props for the InputToolBar container (UI only; data passed via props) */
43
+ export interface InputToolBarProps {
44
+ /** Optional class name for the toolbar container */
45
+ className?: string;
46
+ /** Left section: predefined items (search, zap, lightbulb) + optional template pill. Pass enabled: false to hide/disable. */
47
+ leftItems?: Array<ToolbarItemConfig<LeftToolbarItemId>>;
48
+ /** Right section: tag, chip, camera, attach, mic. Pass enabled: false to hide/disable. */
49
+ rightItems?: Array<ToolbarItemConfig<RightToolbarItemId>>;
50
+ /** Optional template pill button config (e.g. "+ Template (1)") */
51
+ templateButton?: TemplateButtonConfig | null;
52
+ /** Custom content to render in the left section instead of leftItems (takes precedence) */
53
+ leftCustomRender?: ReactNode;
54
+ /** Custom content to render in the right section instead of rightItems (takes precedence) */
55
+ rightCustomRender?: ReactNode;
56
+ /** When set, shows Send (arrow) when input has content, else Mic. Replaces "mic" in rightItems. */
57
+ micSendButton?: MicSendButtonConfig | null;
58
+ /** Optional content in the middle (e.g. text input); can be used with or without left/right */
59
+ children?: ReactNode;
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/InputToolBar/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,8EAA8E;AAC9E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAE5E,kFAAkF;AAClF,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9E,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM;IAC1D,qEAAqE;IACrE,EAAE,EAAE,GAAG,CAAC;IACR,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,uIAAuI;AACvI,MAAM,WAAW,mBAAmB;IAChC,4EAA4E;IAC5E,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACjC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAC9B,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6HAA6H;IAC7H,SAAS,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACxD,0FAA0F;IAC1F,UAAU,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC1D,mEAAmE;IACnE,cAAc,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,mGAAmG;IACnG,aAAa,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC3C,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface MarkdownBreadcrumbsProps {
3
+ categoryId: string;
4
+ categoryTitle?: string;
5
+ markdownTitle: string;
6
+ className?: string;
7
+ getHelpCenterLink: () => string;
8
+ getCategoryLink: (categoryId: string) => string;
9
+ helpCenterLabel: string;
10
+ }
11
+ export declare const MarkdownBreadcrumbs: React.FC<MarkdownBreadcrumbsProps>;
12
+ export {};
13
+ //# sourceMappingURL=MarkdownBreadcrumbs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownBreadcrumbs.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownBreadcrumbs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,wBAAwB;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAwBlE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import React__default from'react';import {Link}from'@remix-run/react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const MarkdownBreadcrumbs = ({
2
+ categoryId,
3
+ categoryTitle,
4
+ markdownTitle,
5
+ className,
6
+ getHelpCenterLink,
7
+ getCategoryLink,
8
+ helpCenterLabel
9
+ }) => {
10
+ return React__default.createElement("div", {
11
+ className: cn('w-full max-w-[90rem] mx-auto px-4 sm:px-6 lg:px-8 xl:px-16', className)
12
+ }, React__default.createElement("nav", {
13
+ className: "flex items-center space-x-2 text-sm text-muted-foreground"
14
+ }, React__default.createElement(Link, {
15
+ to: getHelpCenterLink(),
16
+ className: "hover:text-foreground transition-colors"
17
+ }, helpCenterLabel), React__default.createElement("span", {
18
+ className: "text-muted-foreground/60"
19
+ }, "\u203A"), React__default.createElement(Link, {
20
+ to: getCategoryLink(categoryId),
21
+ className: "hover:text-foreground transition-colors"
22
+ }, categoryTitle || categoryId), React__default.createElement("span", {
23
+ className: "text-muted-foreground/60"
24
+ }, "\u203A"), React__default.createElement("span", {
25
+ className: "text-primary"
26
+ }, markdownTitle)));
27
+ };export{MarkdownBreadcrumbs};//# sourceMappingURL=MarkdownBreadcrumbs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownBreadcrumbs.js","sources":["../../../src/components/Markdown/MarkdownBreadcrumbs.tsx"],"sourcesContent":[null],"names":[],"mappings":"mLAMI,MAAA,mBAAuB,GAAA,CAAA;YACvB;eACU;eACV;AACA,EAAA,SAAA;mBACe;AAClB,EAAA,eAAA;AAED,EAAA;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface MarkdownCopyButtonProps {
3
+ markdownTitle: string;
4
+ markdownContent: string;
5
+ markdownUrl?: string;
6
+ className?: string;
7
+ }
8
+ export declare const MarkdownCopyButton: React.FC<MarkdownCopyButtonProps>;
9
+ export {};
10
+ //# sourceMappingURL=MarkdownCopyButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownCopyButton.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownCopyButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,UAAU,uBAAuB;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAsQhE,CAAC"}
@@ -0,0 +1,200 @@
1
+ import React__default,{useState,useRef,useEffect}from'react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const MarkdownCopyButton = ({
2
+ markdownTitle,
3
+ markdownContent,
4
+ markdownUrl,
5
+ className
6
+ }) => {
7
+ const [isOpen, setIsOpen] = useState(false);
8
+ const [copySuccess, setCopySuccess] = useState(false);
9
+ const dropdownRef = useRef(null);
10
+ // Close dropdown when clicking outside
11
+ useEffect(() => {
12
+ const handleClickOutside = event => {
13
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
14
+ setIsOpen(false);
15
+ }
16
+ };
17
+ if (isOpen) {
18
+ document.addEventListener('mousedown', handleClickOutside);
19
+ }
20
+ return () => {
21
+ document.removeEventListener('mousedown', handleClickOutside);
22
+ };
23
+ }, [isOpen]);
24
+ // Convert HTML to Markdown (simplified version)
25
+ const htmlToMarkdown = html => {
26
+ // Remove script and style tags
27
+ let text = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
28
+ text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
29
+ // Convert headings
30
+ text = text.replace(/<h([1-6])[^>]*>(.*?)<\/h\1>/gi, (match, level, content) => {
31
+ const hashes = '#'.repeat(parseInt(level));
32
+ return `\n${hashes} ${content.trim()}\n`;
33
+ });
34
+ // Convert bold
35
+ text = text.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**');
36
+ text = text.replace(/<b[^>]*>(.*?)<\/b>/gi, '**$1**');
37
+ // Convert italic
38
+ text = text.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*');
39
+ text = text.replace(/<i[^>]*>(.*?)<\/i>/gi, '*$1*');
40
+ // Convert links
41
+ text = text.replace(/<a[^>]*href=["']([^"']*)["'][^>]*>(.*?)<\/a>/gi, '[$2]($1)');
42
+ // Convert code blocks
43
+ text = text.replace(/<pre[^>]*><code[^>]*>(.*?)<\/code><\/pre>/gis, '```\n$1\n```');
44
+ text = text.replace(/<code[^>]*>(.*?)<\/code>/gi, '`$1`');
45
+ // Convert lists
46
+ text = text.replace(/<ul[^>]*>(.*?)<\/ul>/gis, (match, content) => {
47
+ const items = content.match(/<li[^>]*>(.*?)<\/li>/gis) || [];
48
+ return '\n' + items.map(item => {
49
+ const cleanItem = item.replace(/<li[^>]*>|<\/li>/gi, '').trim();
50
+ return `- ${cleanItem}`;
51
+ }).join('\n') + '\n';
52
+ });
53
+ text = text.replace(/<ol[^>]*>(.*?)<\/ol>/gis, (match, content) => {
54
+ const items = content.match(/<li[^>]*>(.*?)<\/li>/gis) || [];
55
+ return '\n' + items.map((item, index) => {
56
+ const cleanItem = item.replace(/<li[^>]*>|<\/li>/gi, '').trim();
57
+ return `${index + 1}. ${cleanItem}`;
58
+ }).join('\n') + '\n';
59
+ });
60
+ // Convert paragraphs
61
+ text = text.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n');
62
+ // Remove remaining HTML tags
63
+ text = text.replace(/<[^>]+>/g, '');
64
+ // Decode HTML entities
65
+ const textarea = document.createElement('textarea');
66
+ textarea.innerHTML = text;
67
+ text = textarea.value;
68
+ // Clean up extra whitespace
69
+ text = text.replace(/\n{3,}/g, '\n\n').trim();
70
+ return `# ${markdownTitle}\n\n${text}`;
71
+ };
72
+ const handleCopyMarkdown = async () => {
73
+ try {
74
+ const markdown = htmlToMarkdown(markdownContent);
75
+ await navigator.clipboard.writeText(markdown);
76
+ setCopySuccess(true);
77
+ setIsOpen(false);
78
+ setTimeout(() => setCopySuccess(false), 2000);
79
+ } catch (err) {
80
+ console.error('Failed to copy:', err);
81
+ }
82
+ };
83
+ const handleOpenChatGPT = () => {
84
+ const url = `https://chat.openai.com/?q=${encodeURIComponent(markdownTitle)}`;
85
+ window.open(url, '_blank');
86
+ setIsOpen(false);
87
+ };
88
+ const handleOpenClaude = () => {
89
+ const url = `https://claude.ai/?q=${encodeURIComponent(markdownTitle)}`;
90
+ window.open(url, '_blank');
91
+ setIsOpen(false);
92
+ };
93
+ return React__default.createElement("div", {
94
+ className: cn('relative inline-flex items-center rounded-md border border-border bg-background', className),
95
+ ref: dropdownRef
96
+ }, React__default.createElement("div", {
97
+ className: "flex items-center overflow-hidden rounded-md"
98
+ }, React__default.createElement("button", {
99
+ onClick: handleCopyMarkdown,
100
+ className: cn('flex items-center gap-2 px-3 py-1.5', 'bg-background hover:bg-muted/50 transition-colors', 'text-sm text-foreground', 'border-0')
101
+ }, React__default.createElement("svg", {
102
+ className: "w-4 h-4",
103
+ fill: "none",
104
+ stroke: "currentColor",
105
+ viewBox: "0 0 24 24",
106
+ xmlns: "http://www.w3.org/2000/svg"
107
+ }, React__default.createElement("path", {
108
+ strokeLinecap: "round",
109
+ strokeLinejoin: "round",
110
+ strokeWidth: 2,
111
+ d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
112
+ })), React__default.createElement("span", null, copySuccess ? 'Copied' : 'Copy page')), React__default.createElement("div", {
113
+ className: "h-5 w-px bg-border"
114
+ }), React__default.createElement("button", {
115
+ onClick: e => {
116
+ e.stopPropagation();
117
+ setIsOpen(!isOpen);
118
+ },
119
+ className: cn('flex items-center justify-center px-2 py-1.5', 'bg-background hover:bg-muted/50 transition-colors', 'text-sm text-foreground', 'border-0')
120
+ }, React__default.createElement("svg", {
121
+ className: cn('w-3 h-3 transition-transform', isOpen && 'rotate-180'),
122
+ fill: "none",
123
+ stroke: "currentColor",
124
+ viewBox: "0 0 24 24"
125
+ }, React__default.createElement("path", {
126
+ strokeLinecap: "round",
127
+ strokeLinejoin: "round",
128
+ strokeWidth: 2,
129
+ d: "M19 9l-7 7-7-7"
130
+ })))), isOpen && React__default.createElement("div", {
131
+ className: "absolute right-0 top-full mt-2 w-64 bg-background border border-border rounded-lg shadow-lg z-[100] overflow-hidden"
132
+ }, React__default.createElement("div", {
133
+ className: "py-1"
134
+ }, React__default.createElement("button", {
135
+ onClick: handleCopyMarkdown,
136
+ className: "w-full px-4 py-3 text-left hover:bg-muted/50 transition-colors flex items-start gap-3 group"
137
+ }, React__default.createElement("svg", {
138
+ className: "w-5 h-5 text-muted-foreground group-hover:text-foreground mt-0.5 flex-shrink-0",
139
+ fill: "none",
140
+ stroke: "currentColor",
141
+ viewBox: "0 0 24 24"
142
+ }, React__default.createElement("path", {
143
+ strokeLinecap: "round",
144
+ strokeLinejoin: "round",
145
+ strokeWidth: 2,
146
+ d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
147
+ })), React__default.createElement("div", {
148
+ className: "flex-1 min-w-0"
149
+ }, React__default.createElement("div", {
150
+ className: "text-sm font-medium text-foreground"
151
+ }, "Copy page"), React__default.createElement("div", {
152
+ className: "text-xs text-muted-foreground mt-0.5"
153
+ }, "Copy page as Markdown for LLMs"))), React__default.createElement("button", {
154
+ onClick: handleOpenChatGPT,
155
+ className: "w-full px-4 py-3 text-left hover:bg-muted/50 transition-colors flex items-start gap-3 group"
156
+ }, React__default.createElement("div", {
157
+ className: "w-5 h-5 mt-0.5 flex-shrink-0 flex items-center justify-center"
158
+ }, React__default.createElement("span", {
159
+ className: "text-lg"
160
+ }, "\uD83E\uDD16")), React__default.createElement("div", {
161
+ className: "flex-1 min-w-0"
162
+ }, React__default.createElement("div", {
163
+ className: "text-sm font-medium text-foreground"
164
+ }, "Open in ChatGPT"), React__default.createElement("div", {
165
+ className: "text-xs text-muted-foreground mt-0.5"
166
+ }, "Ask questions about this page")), React__default.createElement("svg", {
167
+ className: "w-4 h-4 text-muted-foreground group-hover:text-foreground mt-1 flex-shrink-0",
168
+ fill: "none",
169
+ stroke: "currentColor",
170
+ viewBox: "0 0 24 24"
171
+ }, React__default.createElement("path", {
172
+ strokeLinecap: "round",
173
+ strokeLinejoin: "round",
174
+ strokeWidth: 2,
175
+ d: "M9 5l7 7-7 7"
176
+ }))), React__default.createElement("button", {
177
+ onClick: handleOpenClaude,
178
+ className: "w-full px-4 py-3 text-left hover:bg-muted/50 transition-colors flex items-start gap-3 group"
179
+ }, React__default.createElement("div", {
180
+ className: "w-5 h-5 mt-0.5 flex-shrink-0 flex items-center justify-center"
181
+ }, React__default.createElement("span", {
182
+ className: "text-lg"
183
+ }, "\u2744\uFE0F")), React__default.createElement("div", {
184
+ className: "flex-1 min-w-0"
185
+ }, React__default.createElement("div", {
186
+ className: "text-sm font-medium text-foreground"
187
+ }, "Open in Claude"), React__default.createElement("div", {
188
+ className: "text-xs text-muted-foreground mt-0.5"
189
+ }, "Ask questions about this page")), React__default.createElement("svg", {
190
+ className: "w-4 h-4 text-muted-foreground group-hover:text-foreground mt-1 flex-shrink-0",
191
+ fill: "none",
192
+ stroke: "currentColor",
193
+ viewBox: "0 0 24 24"
194
+ }, React__default.createElement("path", {
195
+ strokeLinecap: "round",
196
+ strokeLinejoin: "round",
197
+ strokeWidth: 2,
198
+ d: "M9 5l7 7-7 7"
199
+ }))))));
200
+ };export{MarkdownCopyButton};//# sourceMappingURL=MarkdownCopyButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownCopyButton.js","sources":["../../../src/components/Markdown/MarkdownCopyButton.tsx"],"sourcesContent":[null],"names":[],"mappings":"0KAII,MAAA,kBAAsB,GAAA,CAAA;eACtB;iBACY;aACH;AACZ,EAAA;AAED,CAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface MarkdownHeaderProps {
3
+ categoryTitle?: string;
4
+ title: string;
5
+ description?: string;
6
+ author?: string;
7
+ updatedAt?: string;
8
+ markdownContent: string;
9
+ className?: string;
10
+ }
11
+ export declare const MarkdownHeader: React.FC<MarkdownHeaderProps>;
12
+ export {};
13
+ //# sourceMappingURL=MarkdownHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,mBAAmB;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAmDxD,CAAC"}
@@ -0,0 +1,29 @@
1
+ import React__default from'react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const MarkdownHeader = ({
2
+ categoryTitle,
3
+ title,
4
+ description,
5
+ author,
6
+ updatedAt,
7
+ markdownContent,
8
+ className
9
+ }) => {
10
+ return React__default.createElement("div", {
11
+ className: cn('mb-10', className)
12
+ }, categoryTitle && React__default.createElement("div", {
13
+ className: "text-[11px] font-semibold tracking-[0.16em] uppercase text-primary mb-3"
14
+ }, categoryTitle), React__default.createElement("div", {
15
+ className: "flex items-start justify-between gap-4 mb-5"
16
+ }, React__default.createElement("h1", {
17
+ className: "text-[2.4rem] md:text-[2.9rem] lg:text-[3.1rem] font-semibold text-foreground leading-tight tracking-tight flex-1"
18
+ }, title)), description && React__default.createElement("p", {
19
+ className: "text-[1.15rem] md:text-[1.3rem] text-muted-foreground mb-8 leading-relaxed font-normal max-w-3xl"
20
+ }, description), (author || updatedAt) && React__default.createElement("div", {
21
+ className: "flex items-center space-x-4 text-sm text-muted-foreground"
22
+ }, author && React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
23
+ className: "flex items-center"
24
+ }, React__default.createElement("div", {
25
+ className: "mr-2 flex h-6 w-6 items-center justify-center rounded-full bg-muted text-xs text-foreground font-medium"
26
+ }, author.charAt(0)), React__default.createElement("span", null, "Written by ", author)), updatedAt && React__default.createElement("span", {
27
+ className: "text-muted-foreground/60"
28
+ }, "\u2022")), updatedAt && React__default.createElement("span", null, "Updated ", updatedAt)));
29
+ };export{MarkdownHeader};//# sourceMappingURL=MarkdownHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownHeader.js","sources":["../../../src/components/Markdown/MarkdownHeader.tsx"],"sourcesContent":[null],"names":[],"mappings":"+IAII,MAAA,cAAuB,GAAA,CAAA;;OAEvB;aACS;QACT;WACA;iBACY;AACf,EAAA;AAED,CAAA,KAAA;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ interface Markdown {
3
+ categoryId: string;
4
+ slug: string;
5
+ title: string;
6
+ }
7
+ interface MarkdownNavigationProps {
8
+ previousMarkdown?: Markdown | null;
9
+ nextMarkdown?: Markdown | null;
10
+ className?: string;
11
+ getMarkdownLink: (categoryId: string, slug: string) => string;
12
+ }
13
+ export declare const MarkdownNavigation: React.FC<MarkdownNavigationProps>;
14
+ export {};
15
+ //# sourceMappingURL=MarkdownNavigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownNavigation.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,QAAQ;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,uBAAuB;IAC7B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACjE;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA+ChE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import React__default from'react';import {Link}from'@remix-run/react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const MarkdownNavigation = ({
2
+ previousMarkdown,
3
+ nextMarkdown,
4
+ className,
5
+ getMarkdownLink
6
+ }) => {
7
+ if (!previousMarkdown && !nextMarkdown) {
8
+ return null;
9
+ }
10
+ return React__default.createElement("div", {
11
+ className: cn('mt-16 pt-8 border-t border-border grid grid-cols-1 md:grid-cols-2 gap-6', className)
12
+ }, previousMarkdown ? React__default.createElement(Link, {
13
+ to: getMarkdownLink(previousMarkdown.categoryId, previousMarkdown.slug),
14
+ className: cn('group rounded-lg border border-border bg-background px-6 py-5', 'hover:bg-muted/30 transition-colors')
15
+ }, React__default.createElement("div", {
16
+ className: "text-sm text-muted-foreground mb-1"
17
+ }, "Previous"), React__default.createElement("div", {
18
+ className: "text-primary font-semibold group-hover:underline text-base"
19
+ }, "\u00AB ", previousMarkdown.title)) : React__default.createElement("div", {
20
+ className: "hidden md:block"
21
+ }), nextMarkdown ? React__default.createElement(Link, {
22
+ to: getMarkdownLink(nextMarkdown.categoryId, nextMarkdown.slug),
23
+ className: cn('group rounded-lg border border-border bg-background px-6 py-5', 'hover:bg-muted/30 transition-colors md:text-right')
24
+ }, React__default.createElement("div", {
25
+ className: "text-sm text-muted-foreground mb-1"
26
+ }, "Next"), React__default.createElement("div", {
27
+ className: "text-primary font-semibold group-hover:underline text-base"
28
+ }, nextMarkdown.title, " \u00BB")) : React__default.createElement("div", {
29
+ className: "hidden md:block"
30
+ }));
31
+ };export{MarkdownNavigation};//# sourceMappingURL=MarkdownNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownNavigation.js","sources":["../../../src/components/Markdown/MarkdownNavigation.tsx"],"sourcesContent":[null],"names":["React"],"mappings":"2MAMiB,GAAA,CAAA;kBACC;AACjB,EAAA,YAAA;AAED,EAAA,SAAU;AACN,EAAA;AACA,CAAA,KAAA;MACA,CAAA,gBAAmB,IAAA,CAAA,YAAA,EAAA;IACnB,OAAA,IAAA;AACH,EAAA;AAED,EAAA,OAAAA,cAAA,CAAO;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ export interface Heading {
3
+ id: string;
4
+ text: string;
5
+ level: number;
6
+ }
7
+ export interface Markdown {
8
+ id: string;
9
+ title: string;
10
+ description: string;
11
+ slug: string;
12
+ author: string;
13
+ updatedAt: string;
14
+ categoryId: string;
15
+ content: string;
16
+ htmlContent: string;
17
+ headings: Heading[];
18
+ }
19
+ export interface NavigationItem {
20
+ categoryId: string;
21
+ slug: string;
22
+ title: string;
23
+ }
24
+ interface MarkdownPageProps {
25
+ article?: Markdown | null;
26
+ categoryId?: string;
27
+ categoryTitle?: string;
28
+ articleSlug?: string;
29
+ loadArticle?: (slug: string) => Promise<Markdown | null>;
30
+ previousMarkdown?: NavigationItem | null;
31
+ nextMarkdown?: NavigationItem | null;
32
+ getMarkdownLink: (categoryId: string, slug: string) => string;
33
+ getCategoryLink: (categoryId: string) => string;
34
+ getHelpCenterLink: () => string;
35
+ helpCenterLabel: string;
36
+ backToHelpCenterLabel?: string;
37
+ className?: string;
38
+ }
39
+ export declare const MarkdownPage: React.FC<MarkdownPageProps>;
40
+ export {};
41
+ //# sourceMappingURL=MarkdownPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownPage.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAS3D,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iBAAiB;IACvB,OAAO,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACzD,gBAAgB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9D,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwQpD,CAAC"}
@@ -0,0 +1,221 @@
1
+ import React__default,{useState,useRef,useEffect}from'react';import {Link}from'@remix-run/react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';import {MarkdownTableOfContents}from'./MarkdownTableOfContents.js';import {MarkdownNavigation}from'./MarkdownNavigation.js';import {MarkdownBreadcrumbs}from'./MarkdownBreadcrumbs.js';import {MarkdownCopyButton}from'./MarkdownCopyButton.js';const MarkdownPage = ({
2
+ article: articleProp,
3
+ categoryId: categoryIdProp,
4
+ categoryTitle: categoryTitleProp,
5
+ articleSlug,
6
+ loadArticle,
7
+ previousMarkdown: previousMarkdownProp,
8
+ nextMarkdown: nextMarkdownProp,
9
+ getMarkdownLink,
10
+ getCategoryLink,
11
+ getHelpCenterLink,
12
+ helpCenterLabel,
13
+ backToHelpCenterLabel,
14
+ className
15
+ }) => {
16
+ const [article, setArticle] = useState(articleProp || null);
17
+ const [loading, setLoading] = useState(!articleProp && !!articleSlug);
18
+ const [activeHeadingId, setActiveHeadingId] = useState('');
19
+ const observerRef = useRef(null);
20
+ const isScrollingRef = useRef(false);
21
+ const scrollTimeoutRef = useRef(null);
22
+ useEffect(() => {
23
+ if (articleProp) {
24
+ setArticle(articleProp);
25
+ setLoading(false);
26
+ } else if (articleSlug && loadArticle) {
27
+ const loadContent = async () => {
28
+ const articleData = await loadArticle(articleSlug);
29
+ setArticle(articleData);
30
+ setLoading(false);
31
+ };
32
+ loadContent();
33
+ } else if (!articleProp && !articleSlug) {
34
+ setLoading(false);
35
+ }
36
+ }, [articleProp, articleSlug, loadArticle]);
37
+ // Scroll spy functionality
38
+ useEffect(() => {
39
+ if (!article?.headings || article.headings.length === 0) return;
40
+ // Clean up previous observer
41
+ if (observerRef.current) {
42
+ observerRef.current.disconnect();
43
+ }
44
+ // Create new intersection observer
45
+ observerRef.current = new IntersectionObserver(entries => {
46
+ // Don't update if we're programmatically scrolling
47
+ if (isScrollingRef.current) return;
48
+ // Find the heading that's most visible in the viewport
49
+ const visibleEntries = entries.filter(entry => entry.isIntersecting);
50
+ if (visibleEntries.length === 0) return;
51
+ // Find the heading that's closest to the top of the viewport (within the top 30%)
52
+ // Prioritize headings that are in the upper portion of the viewport
53
+ let bestEntry = visibleEntries[0];
54
+ let bestScore = Infinity;
55
+ visibleEntries.forEach(entry => {
56
+ const rect = entry.boundingClientRect;
57
+ const viewportHeight = window.innerHeight;
58
+ const top30Percent = viewportHeight * 0.3;
59
+ // Calculate a score: lower is better
60
+ // Headings in the top 30% of viewport get priority
61
+ let score;
62
+ if (rect.top >= 0 && rect.top <= top30Percent) {
63
+ // Heading is in the top 30% - prioritize by distance from top
64
+ score = rect.top;
65
+ } else if (rect.top >= 0) {
66
+ // Heading is below top 30% but visible - lower priority
67
+ score = 1000 + rect.top;
68
+ } else {
69
+ // Heading is above viewport - lowest priority unless it's the only one
70
+ score = 2000 + Math.abs(rect.top);
71
+ }
72
+ if (score < bestScore) {
73
+ bestScore = score;
74
+ bestEntry = entry;
75
+ }
76
+ });
77
+ setActiveHeadingId(bestEntry.target.id);
78
+ }, {
79
+ rootMargin: '-10% 0px -70% 0px',
80
+ threshold: [0, 0.1, 0.5, 1]
81
+ });
82
+ // Observe all headings
83
+ article.headings.forEach(heading => {
84
+ const element = document.getElementById(heading.id);
85
+ if (element && observerRef.current) {
86
+ observerRef.current.observe(element);
87
+ }
88
+ });
89
+ // Cleanup function
90
+ return () => {
91
+ if (observerRef.current) {
92
+ observerRef.current.disconnect();
93
+ }
94
+ if (scrollTimeoutRef.current) {
95
+ clearTimeout(scrollTimeoutRef.current);
96
+ }
97
+ };
98
+ }, [article]);
99
+ if (loading) {
100
+ return React__default.createElement("div", {
101
+ className: "min-h-screen bg-background text-foreground overflow-x-hidden"
102
+ }, React__default.createElement("div", {
103
+ className: "w-full max-w-[90rem] mx-auto px-4 sm:px-6 lg:px-8 xl:px-16 py-16"
104
+ }, React__default.createElement("div", {
105
+ className: "animate-pulse"
106
+ }, React__default.createElement("div", {
107
+ className: "h-8 bg-muted rounded w-1/3 mb-4"
108
+ }), React__default.createElement("div", {
109
+ className: "h-4 bg-muted rounded w-1/2 mb-8"
110
+ }), React__default.createElement("div", {
111
+ className: "space-y-4"
112
+ }, React__default.createElement("div", {
113
+ className: "h-4 bg-muted rounded"
114
+ }), React__default.createElement("div", {
115
+ className: "h-4 bg-muted rounded w-5/6"
116
+ }), React__default.createElement("div", {
117
+ className: "h-4 bg-muted rounded w-4/6"
118
+ })))));
119
+ }
120
+ if (!article) {
121
+ return React__default.createElement("div", {
122
+ className: "min-h-screen bg-background text-foreground mt-20 overflow-x-hidden"
123
+ }, React__default.createElement("div", {
124
+ className: "w-full max-w-[90rem] mx-auto px-4 sm:px-6 lg:px-8 xl:px-16 py-16"
125
+ }, React__default.createElement("h1", {
126
+ className: "text-2xl font-bold"
127
+ }, "Article not found"), React__default.createElement(Link, {
128
+ to: getHelpCenterLink(),
129
+ className: "mt-4 text-primary hover:text-primary/80"
130
+ }, backToHelpCenterLabel || `← Back to ${helpCenterLabel}`)));
131
+ }
132
+ // Use previous/next articles from props
133
+ const previousMarkdown = previousMarkdownProp;
134
+ const nextMarkdown = nextMarkdownProp;
135
+ return React__default.createElement("div", {
136
+ className: cn('min-h-screen bg-background text-foreground scroll-smooth overflow-x-hidden', className)
137
+ }, React__default.createElement("div", {
138
+ className: "flex w-full justify-center gap-10"
139
+ }, React__default.createElement("div", {
140
+ className: "flex-1 max-w-3xl w-full"
141
+ }, React__default.createElement("div", {
142
+ className: "flex items-center justify-between"
143
+ }, React__default.createElement(MarkdownBreadcrumbs, {
144
+ categoryId: article.categoryId || categoryIdProp || '',
145
+ categoryTitle: categoryTitleProp,
146
+ markdownTitle: article.title,
147
+ className: "pb-4",
148
+ getHelpCenterLink: getHelpCenterLink,
149
+ getCategoryLink: getCategoryLink,
150
+ helpCenterLabel: helpCenterLabel
151
+ }), React__default.createElement(MarkdownCopyButton, {
152
+ markdownTitle: article.title,
153
+ markdownContent: article.htmlContent,
154
+ className: "flex-shrink-0"
155
+ })), React__default.createElement("main", {
156
+ className: "w-full py-2"
157
+ }, React__default.createElement("div", {
158
+ className: "max-w-[90rem] mx-auto px-4 sm:px-6 lg:px-8 xl:px-16 relative"
159
+ }, React__default.createElement("div", {
160
+ className: "flex flex-col xl:flex-row gap-12 xl:gap-16 align-start"
161
+ }, React__default.createElement("div", {
162
+ className: "flex-1 min-w-0 max-w-5xl"
163
+ }, React__default.createElement("div", {
164
+ className: "prose prose-lg max-w-none w-full overflow-x-hidden"
165
+ }, React__default.createElement("div", {
166
+ className: cn(
167
+ // Base prose styles
168
+ 'prose-headings:font-semibold prose-headings:text-foreground prose-headings:tracking-tight',
169
+ // Body H1 styles (within article) - slightly smaller than page title
170
+ 'prose-h1:text-[1.5rem] prose-h1:md:text-[1.75rem] prose-h1:mb-4 prose-h1:mt-5 prose-h1:leading-tight',
171
+ // H2 styles - strong section headings
172
+ 'prose-h2:text-[1.2rem] prose-h2:md:text-[1.5rem] prose-h2:mb-4 prose-h2:mt-5 prose-h2:leading-tight',
173
+ // H3 styles - sub section headings
174
+ 'prose-h3:text-[1.05rem] prose-h3:md:text-[1.25rem] prose-h3:mb-3 prose-h3:mt-4 prose-h3:leading-snug',
175
+ // H4 styles
176
+ 'prose-h4:text-lg prose-h4:md:text-xl prose-h4:mb-3 prose-h4:mt-4',
177
+ // Paragraph styles
178
+ 'prose-p:text-[0.85rem] prose-p:md:text-[0.95rem] prose-p:text-muted-foreground prose-p:leading-relaxed prose-p:mb-5',
179
+ // Strong text
180
+ 'prose-strong:text-foreground prose-strong:font-semibold',
181
+ // Links
182
+ 'prose-a:text-primary prose-a:no-underline hover:prose-a:underline prose-a:font-medium',
183
+ // Lists
184
+ 'prose-ul:text-muted-foreground prose-ol:text-muted-foreground prose-li:text-muted-foreground prose-li:mb-2 prose-li:text-base prose-li:md:text-lg',
185
+ // Blockquotes
186
+ 'prose-blockquote:text-muted-foreground prose-blockquote:border-l-primary prose-blockquote:pl-4 prose-blockquote:my-6',
187
+ // Code
188
+ 'prose-code:text-foreground prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-code:font-mono',
189
+ // Pre blocks
190
+ 'prose-pre:bg-muted prose-pre:text-foreground prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:p-4 prose-pre:my-6',
191
+ // Images
192
+ 'prose-img:rounded-lg prose-img:my-8',
193
+ // Tables
194
+ 'prose-table:text-muted-foreground prose-th:text-foreground prose-th:font-semibold',
195
+ // Horizontal rules
196
+ 'prose-hr:border-border prose-hr:my-8'),
197
+ dangerouslySetInnerHTML: {
198
+ __html: article.htmlContent
199
+ }
200
+ })), React__default.createElement(MarkdownNavigation, {
201
+ previousMarkdown: previousMarkdown,
202
+ nextMarkdown: nextMarkdown,
203
+ getMarkdownLink: getMarkdownLink
204
+ })))))), React__default.createElement(MarkdownTableOfContents, {
205
+ headings: article.headings || [],
206
+ activeHeadingId: activeHeadingId,
207
+ onHeadingClick: headingId => {
208
+ // Set scrolling flag to prevent observer from overriding
209
+ isScrollingRef.current = true;
210
+ setActiveHeadingId(headingId);
211
+ // Clear any existing timeout
212
+ if (scrollTimeoutRef.current) {
213
+ clearTimeout(scrollTimeoutRef.current);
214
+ }
215
+ // Re-enable observer after scroll completes (smooth scroll takes ~500ms)
216
+ scrollTimeoutRef.current = setTimeout(() => {
217
+ isScrollingRef.current = false;
218
+ }, 800);
219
+ }
220
+ })));
221
+ };export{MarkdownPage};//# sourceMappingURL=MarkdownPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownPage.js","sources":["../../../src/components/Markdown/MarkdownPage.tsx"],"sourcesContent":[null],"names":[],"mappings":"gdAiBkB,GAAA,CAAA;SACd,EAAA;4BACa;kCACE;aACN;aACT;oBACgB,oBAAA;cAChB,EAAW,gBAAS;iBACV;AACb,EAAA,eAAA;AAED,EAAA,iBAAiB;;uBAEA;;AAEhB,CAAA,KAAA;AAED,EAAA,MAAA,CAAA,OAAU,EAAA,UAAiB,CAAA,GAAA,QAAA,CAAA,WAAA,IAAA,IAAA,CAAA;AACvB,EAAA,MAAA,CAAA,OAAU,EAAA,WAAe,GAAC,QAAA,CAAA,CAAA,WAAA,IAAA,CAAA,CAAA,WAAA,CAAA;QAC1B,CAAA,eAAoB,EAAA,kBAAA,CAAA,GAAA,QAAA,CAAA,EAAA,CAAA;QACpB,WAAc,GAAE,MAAO,CAAA,IAAA,CAAA;QACvB,cAAc,GAAO,MAAA,CAAA,KAAA,CAAA;AACrB,EAAA,MAAA,gBAAmB,GAAE,MAAM,CAAA,IAAK,CAAA;AAChC,EAAA,SAAA,CAAA,MAAA;AACA,IAAA,IAAA,WAAe,EAAA;MACf,UAAA,CAAA,WAAkB,CAAA;AAClB,MAAA,UAAA,CAAA,KAAkB,CAAA;IAClB,CAAA,MAAA,IAAA,WAAmB,IAAM,WAAO,EAAA;MAChC,MAAA,0BAAwB;QACxB,MAAA,WAAqB,GAAG,MAAM,WAAC,CAAA,WAAA,CAAA;QAC/B,UAAY,CAAA,WAAO,CAAA;AACtB,QAAA,UAAA,CAAA,KAAA,CAAA;AAED,MAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ interface Heading {
3
+ id: string;
4
+ text: string;
5
+ level: number;
6
+ }
7
+ interface MarkdownTableOfContentsProps {
8
+ headings: Heading[];
9
+ activeHeadingId: string;
10
+ onHeadingClick?: (headingId: string) => void;
11
+ className?: string;
12
+ }
13
+ export declare const MarkdownTableOfContents: React.FC<MarkdownTableOfContentsProps>;
14
+ export {};
15
+ //# sourceMappingURL=MarkdownTableOfContents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownTableOfContents.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/MarkdownTableOfContents.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,OAAO;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,4BAA4B;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CA6E1E,CAAC"}
@@ -0,0 +1,51 @@
1
+ import React__default from'react';import {Link}from'@remix-run/react';import'../../utils/isBrowser/index.js';import {cn}from'../../utils/util.js';import'fast-deep-equal/react.js';const MarkdownTableOfContents = ({
2
+ headings,
3
+ activeHeadingId,
4
+ onHeadingClick,
5
+ className
6
+ }) => {
7
+ if (!headings || headings.length === 0) {
8
+ return null;
9
+ }
10
+ const handleClick = headingId => {
11
+ // Immediately set the active heading when clicked
12
+ if (onHeadingClick) {
13
+ onHeadingClick(headingId);
14
+ }
15
+ // Smooth scroll to the heading with proper offset
16
+ const element = document.getElementById(headingId);
17
+ if (element) {
18
+ // Calculate the position with offset for header
19
+ const elementPosition = element.getBoundingClientRect().top + window.pageYOffset;
20
+ const offsetPosition = elementPosition - 100; // 100px offset from top
21
+ window.scrollTo({
22
+ top: offsetPosition,
23
+ behavior: 'smooth'
24
+ });
25
+ }
26
+ };
27
+ return React__default.createElement("aside", {
28
+ className: "hidden xl:block xl:w-80 xl:flex-shrink-0 max-w-[28rem]"
29
+ }, React__default.createElement("div", {
30
+ className: "fixed flex flex-col h-[calc(100vh-3rem)] w-[19rem]"
31
+ }, React__default.createElement("div", {
32
+ className: "mb-4 flex-shrink-0"
33
+ }, React__default.createElement("h2", {
34
+ className: "text-sm font-semibold text-primary flex items-center"
35
+ }, React__default.createElement("span", {
36
+ className: "mr-2"
37
+ }, "\u2630"), "On this page")), React__default.createElement("nav", {
38
+ className: "space-y-1 flex-1 overflow-y-auto overflow-x-hidden min-h-0"
39
+ }, headings.map((heading, index) => {
40
+ const isActive = activeHeadingId === heading.id;
41
+ return React__default.createElement(Link, {
42
+ key: index,
43
+ to: `#${heading.id}`,
44
+ onClick: e => {
45
+ e.preventDefault();
46
+ handleClick(heading.id);
47
+ },
48
+ className: cn('relative block text-sm transition-colors py-1 pl-4', 'border-l-2 border-transparent', isActive ? 'text-primary border-l-primary bg-muted/20' : 'text-muted-foreground hover:text-primary hover:border-l-primary', heading.level === 1 ? 'font-semibold' : heading.level === 2 ? 'ml-2' : heading.level === 3 ? 'ml-4' : heading.level === 4 ? 'ml-6' : heading.level === 5 ? 'ml-8' : 'ml-10')
49
+ }, heading.text);
50
+ }))));
51
+ };export{MarkdownTableOfContents};//# sourceMappingURL=MarkdownTableOfContents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownTableOfContents.js","sources":["../../../src/components/Markdown/MarkdownTableOfContents.tsx"],"sourcesContent":[null],"names":[],"mappings":"gNAMiB,GAAA,CAAA;UACR;AACR,EAAA,eAAA;AAED,EAAA,cAAU;;MAEN;MACA,CAAA,QAAA,IAAe,QAAG,CAAA,MAAW,KAAM,CAAA,EAAA;IACnC,OAAA,IAAU;AACb,EAAA;AAED,EAAA,MAAA,WAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,7 @@
1
+ export * from './MarkdownBreadcrumbs';
2
+ export * from './MarkdownCopyButton';
3
+ export * from './MarkdownHeader';
4
+ export * from './MarkdownNavigation';
5
+ export * from './MarkdownPage';
6
+ export * from './MarkdownTableOfContents';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC"}
@@ -1,4 +1,4 @@
1
- import*as React from'react';import {Search,ChevronDown}from'lucide-react';import {cn}from'../../utils/util.js';const SelectContext = React.createContext(undefined);
1
+ import*as React from'react';import {ChevronDown,Search}from'lucide-react';import {cn}from'../../utils/util.js';const SelectContext = React.createContext(undefined);
2
2
  const SelectProvider = ({
3
3
  children,
4
4
  value,
@@ -11,5 +11,7 @@ export * from './DatePicker';
11
11
  export * from './Button/Button';
12
12
  export * from './ThemeProvider';
13
13
  export * from './LanguageMenuDropdown';
14
+ export * from './InputToolBar';
15
+ export * from './Markdown';
14
16
  export { PageLoading };
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,CAAC"}
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- export{default as PageLoading}from'./components/PageLoading/index.js';export{ApplicationErrorHandler}from'./components/ErrorHandlers/ApplicationErrorHandler.js';export{ErrorBoundary}from'./components/ErrorHandlers/ErrorBoundary.js';export{LayoutErrorBoundary}from'./components/ErrorHandlers/LayoutErrorBoundary.js';export{RemixErrorBoundary}from'./components/ErrorHandlers/RemixErrorBoundary.js';export{SPAErrorBoundary}from'./components/ErrorHandlers/SPAErrorBoundary.js';export{ReactTable}from'./components/ReactTable/Table.js';export{DefaultColumnFilter,SelectColumnFilter}from'./components/ReactTable/TableFilters.js';export{Error404}from'./components/ErrorPages/404.js';export{Error500}from'./components/ErrorPages/500.js';export{Error403}from'./components/ErrorPages/403.js';export{PageContainer}from'./components/PageContainer/PageContainer.js';export{Spin}from'./components/Spin/index.js';export{OTPInput}from'./components/OTP/OTPInput.js';export{SingleInput}from'./components/OTP/SingleInput.js';export{useOTPInput}from'./components/OTP/hooks.js';export{OTPVerification}from'./components/OTP/OTPVerification.js';export{SearchInput}from'./components/Search/SearchInput.js';export{Select,SelectContent,SelectItem,SelectSearch,SelectTrigger,SelectValue}from'./components/Select/Select.js';export{DatePicker}from'./components/DatePicker/DatePicker.js';export{TailwindUiButton}from'./components/Button/Button.js';export{TailwindThemeProvider,ThemeContext,themes}from'./components/ThemeProvider/ThemeProvider.js';export{ThemeToggle}from'./components/ThemeProvider/ThemeToggle.js';export{LanguageMenuDropdown}from'./components/LanguageMenuDropdown/LanguageMenuDropdown.js';export{useTheme}from'./hooks/useTheme.js';export{useWindowSize}from'./hooks/useWindowSize.js';export{ToastContainer,useToast,useToastCloseAll}from'./hooks/useToast.js';export{useMediaQuery}from'./hooks/useMediaQuery.js';export{cn}from'./utils/util.js';//# sourceMappingURL=index.js.map
1
+ export{default as PageLoading}from'./components/PageLoading/index.js';export{ApplicationErrorHandler}from'./components/ErrorHandlers/ApplicationErrorHandler.js';export{ErrorBoundary}from'./components/ErrorHandlers/ErrorBoundary.js';export{LayoutErrorBoundary}from'./components/ErrorHandlers/LayoutErrorBoundary.js';export{RemixErrorBoundary}from'./components/ErrorHandlers/RemixErrorBoundary.js';export{SPAErrorBoundary}from'./components/ErrorHandlers/SPAErrorBoundary.js';export{ReactTable}from'./components/ReactTable/Table.js';export{DefaultColumnFilter,SelectColumnFilter}from'./components/ReactTable/TableFilters.js';export{Error404}from'./components/ErrorPages/404.js';export{Error500}from'./components/ErrorPages/500.js';export{Error403}from'./components/ErrorPages/403.js';export{PageContainer}from'./components/PageContainer/PageContainer.js';export{Spin}from'./components/Spin/index.js';export{OTPInput}from'./components/OTP/OTPInput.js';export{SingleInput}from'./components/OTP/SingleInput.js';export{useOTPInput}from'./components/OTP/hooks.js';export{OTPVerification}from'./components/OTP/OTPVerification.js';export{SearchInput}from'./components/Search/SearchInput.js';export{Select,SelectContent,SelectItem,SelectSearch,SelectTrigger,SelectValue}from'./components/Select/Select.js';export{DatePicker}from'./components/DatePicker/DatePicker.js';export{TailwindUiButton}from'./components/Button/Button.js';export{TailwindThemeProvider,ThemeContext,themes}from'./components/ThemeProvider/ThemeProvider.js';export{ThemeToggle}from'./components/ThemeProvider/ThemeToggle.js';export{LanguageMenuDropdown}from'./components/LanguageMenuDropdown/LanguageMenuDropdown.js';export{InputToolBar}from'./components/InputToolBar/InputToolBar.js';export{getDefaultLeftItems,getDefaultRightItems}from'./components/InputToolBar/defaults.js';export{MarkdownBreadcrumbs}from'./components/Markdown/MarkdownBreadcrumbs.js';export{MarkdownCopyButton}from'./components/Markdown/MarkdownCopyButton.js';export{MarkdownHeader}from'./components/Markdown/MarkdownHeader.js';export{MarkdownNavigation}from'./components/Markdown/MarkdownNavigation.js';export{MarkdownPage}from'./components/Markdown/MarkdownPage.js';export{MarkdownTableOfContents}from'./components/Markdown/MarkdownTableOfContents.js';export{useTheme}from'./hooks/useTheme.js';export{useWindowSize}from'./hooks/useWindowSize.js';export{ToastContainer,useToast,useToastCloseAll}from'./hooks/useToast.js';export{useMediaQuery}from'./hooks/useMediaQuery.js';export{cn}from'./utils/util.js';//# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@admin-layout/tailwind-ui",
3
- "version": "12.2.4-alpha.12",
3
+ "version": "12.2.4-alpha.16",
4
4
  "description": "Sample core for higher packages to depend on",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -90,5 +90,5 @@
90
90
  "typescript": {
91
91
  "definition": "lib/index.d.ts"
92
92
  },
93
- "gitHead": "ebc266babcf79ef46a60363f21c68edf3d2dd1c0"
93
+ "gitHead": "171b0ea9753cac315279fe1dcbb54f3225ad89e4"
94
94
  }