lupine.components 1.1.21 → 1.1.23
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.
- package/package.json +1 -1
- package/src/components/action-sheet-demo.tsx +105 -0
- package/src/components/button-demo.tsx +33 -0
- package/src/components/button-push-animation-demo.tsx +32 -0
- package/src/components/button-push-animation.tsx +8 -4
- package/src/components/editable-label-demo.tsx +33 -0
- package/src/components/input-with-title-demo.tsx +42 -0
- package/src/components/message-box-demo.tsx +107 -0
- package/src/components/modal-demo.tsx +56 -0
- package/src/components/notice-message-demo.tsx +60 -0
- package/src/components/popup-menu-demo.tsx +68 -0
- package/src/components/popup-menu.tsx +1 -1
- package/src/components/progress-demo.tsx +63 -0
- package/src/components/progress.tsx +3 -3
- package/src/components/radio-label-demo.tsx +41 -0
- package/src/components/redirect-demo.tsx +36 -0
- package/src/components/resizable-splitter-demo.tsx +76 -0
- package/src/components/resizable-splitter.tsx +6 -6
- package/src/components/select-angle-demo.tsx +32 -0
- package/src/components/select-with-title-demo.tsx +53 -0
- package/src/components/spinner-demo.tsx +52 -0
- package/src/components/stars-component-demo.tsx +36 -0
- package/src/components/stars-component.tsx +11 -3
- package/src/components/switch-option-demo.tsx +36 -0
- package/src/components/tabs-demo.tsx +42 -0
- package/src/components/text-glow-demo.tsx +46 -0
- package/src/components/text-scale-demo.tsx +41 -0
- package/src/components/text-wave-demo.tsx +46 -0
- package/src/components/toggle-button-demo.tsx +42 -0
- package/src/components/toggle-play-button-demo.tsx +56 -0
- package/src/components/toggle-switch-demo.tsx +43 -0
- package/src/demo/demo-about.tsx +12 -0
- package/src/demo/demo-container.tsx +57 -0
- package/src/demo/demo-css.tsx +3 -0
- package/src/demo/demo-frame-helper.tsx +395 -0
- package/src/demo/demo-frame.tsx +139 -0
- package/src/demo/demo-index.tsx +17 -0
- package/src/demo/demo-page.tsx +198 -0
- package/src/demo/demo-registry.ts +54 -0
- package/src/demo/demo-render-page.tsx +77 -0
- package/src/demo/demo-types.ts +22 -0
- package/src/html-editor/buttons_morden.gif +0 -0
- package/src/html-editor/h-editor.ts +817 -0
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import {
|
|
3
|
+
ActionSheet,
|
|
4
|
+
ActionSheetSelect,
|
|
5
|
+
ActionSheetMessage,
|
|
6
|
+
ActionSheetInput,
|
|
7
|
+
ActionSheetSelectOptionsProps,
|
|
8
|
+
} from './action-sheet';
|
|
9
|
+
import { Button, ButtonSize } from './button';
|
|
10
|
+
|
|
11
|
+
export const actionSheetDemo: DemoStory<any> = {
|
|
12
|
+
id: 'action-sheet-demo',
|
|
13
|
+
text: 'Action Sheet Demo',
|
|
14
|
+
args: {
|
|
15
|
+
title: 'Select an Action',
|
|
16
|
+
confirmButtonText: 'Confirm Option',
|
|
17
|
+
cancelButtonText: 'Cancel Action',
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
title: { control: 'text', description: 'Title of the action sheet' },
|
|
21
|
+
confirmButtonText: { control: 'text', description: 'Confirm button text' },
|
|
22
|
+
cancelButtonText: { control: 'text', description: 'Cancel button text' },
|
|
23
|
+
},
|
|
24
|
+
render: (args) => {
|
|
25
|
+
return (
|
|
26
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px', padding: '20px' }}>
|
|
27
|
+
<Button
|
|
28
|
+
text='Show Simple Action Sheet'
|
|
29
|
+
size={ButtonSize.Medium}
|
|
30
|
+
onClick={() => {
|
|
31
|
+
ActionSheet.show({
|
|
32
|
+
title: args.title,
|
|
33
|
+
children: <div style={{ padding: '20px' }}>Custom Content Here</div>,
|
|
34
|
+
confirmButtonText: args.confirmButtonText,
|
|
35
|
+
cancelButtonText: args.cancelButtonText,
|
|
36
|
+
handleConfirmClicked: (close) => close('confirm'),
|
|
37
|
+
});
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
<Button
|
|
41
|
+
text='Show Action Sheet Select'
|
|
42
|
+
size={ButtonSize.Medium}
|
|
43
|
+
onClick={() => {
|
|
44
|
+
ActionSheetSelect.show({
|
|
45
|
+
title: args.title,
|
|
46
|
+
options: ['Option A', 'Option B', 'Option C'],
|
|
47
|
+
confirmButtonText: args.confirmButtonText,
|
|
48
|
+
cancelButtonText: args.cancelButtonText,
|
|
49
|
+
handleClicked: (index, close) => {
|
|
50
|
+
console.log('Selected index:', index);
|
|
51
|
+
close('select');
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}}
|
|
55
|
+
/>
|
|
56
|
+
<Button
|
|
57
|
+
text='Show Action Sheet Message'
|
|
58
|
+
size={ButtonSize.Medium}
|
|
59
|
+
onClick={() => {
|
|
60
|
+
ActionSheetMessage.show({
|
|
61
|
+
title: args.title,
|
|
62
|
+
message: 'This is a detailed message shown inside the action sheet.',
|
|
63
|
+
confirmButtonText: args.confirmButtonText,
|
|
64
|
+
cancelButtonText: args.cancelButtonText,
|
|
65
|
+
});
|
|
66
|
+
}}
|
|
67
|
+
/>
|
|
68
|
+
<Button
|
|
69
|
+
text='Show Action Sheet Input'
|
|
70
|
+
size={ButtonSize.Medium}
|
|
71
|
+
onClick={() => {
|
|
72
|
+
ActionSheetInput.show({
|
|
73
|
+
title: args.title,
|
|
74
|
+
defaultValue: 'Default text',
|
|
75
|
+
confirmButtonText: args.confirmButtonText,
|
|
76
|
+
cancelButtonText: args.cancelButtonText,
|
|
77
|
+
handleConfirmValue: (val, close) => {
|
|
78
|
+
console.log('Input value:', val);
|
|
79
|
+
close('confirm');
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
code: `import { ActionSheet, ActionSheetSelect, ActionSheetMessage, ActionSheetInput } from 'lupine.components/components/action-sheet';
|
|
88
|
+
|
|
89
|
+
// Simple Action Sheet
|
|
90
|
+
ActionSheet.show({
|
|
91
|
+
title: 'Select an Action',
|
|
92
|
+
children: <div style={{ padding: '20px' }}>Custom Content Here</div>,
|
|
93
|
+
confirmButtonText: 'Confirm Option',
|
|
94
|
+
cancelButtonText: 'Cancel Action',
|
|
95
|
+
handleConfirmClicked: (close) => close('confirm'),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Action Sheet Select
|
|
99
|
+
ActionSheetSelect.show({
|
|
100
|
+
title: 'Select an Action',
|
|
101
|
+
options: ['Option A', 'Option B', 'Option C'],
|
|
102
|
+
handleClicked: (index, close) => close('select'),
|
|
103
|
+
});
|
|
104
|
+
`,
|
|
105
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { Button, ButtonProps, ButtonSize } from './button';
|
|
3
|
+
|
|
4
|
+
export const buttonDemo: DemoStory<ButtonProps> = {
|
|
5
|
+
id: 'button-demo',
|
|
6
|
+
text: 'Button Demo',
|
|
7
|
+
args: {
|
|
8
|
+
text: 'Click Me',
|
|
9
|
+
size: ButtonSize.Medium,
|
|
10
|
+
disabled: false,
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
text: { control: 'text', description: 'The text displayed inside the button' },
|
|
14
|
+
size: {
|
|
15
|
+
control: 'select',
|
|
16
|
+
options: Object.values(ButtonSize),
|
|
17
|
+
description: 'The size of the button',
|
|
18
|
+
},
|
|
19
|
+
disabled: { control: 'boolean', description: 'Whether the button is disabled' },
|
|
20
|
+
},
|
|
21
|
+
render: (args: ButtonProps) => {
|
|
22
|
+
return <Button {...args} />;
|
|
23
|
+
},
|
|
24
|
+
code: `import { Button, ButtonSize } from 'lupine.components/components/button';
|
|
25
|
+
|
|
26
|
+
// Basic Usage
|
|
27
|
+
<Button
|
|
28
|
+
text="Click Me"
|
|
29
|
+
size={ButtonSize.Medium}
|
|
30
|
+
onClick={() => console.log('Clicked!')}
|
|
31
|
+
/>
|
|
32
|
+
`,
|
|
33
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { ButtonPushAnimation, ButtonPushAnimationProps, ButtonPushAnimationSize } from './button-push-animation';
|
|
3
|
+
|
|
4
|
+
export const buttonPushAnimationDemo: DemoStory<ButtonPushAnimationProps> = {
|
|
5
|
+
id: 'button-push-animation-demo',
|
|
6
|
+
text: 'Button Push Animation Demo',
|
|
7
|
+
args: {
|
|
8
|
+
text: 'Push Me',
|
|
9
|
+
size: ButtonPushAnimationSize.Medium,
|
|
10
|
+
disabled: false,
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
text: { control: 'text', description: 'The text displayed inside the button' },
|
|
14
|
+
size: {
|
|
15
|
+
control: 'select',
|
|
16
|
+
options: Object.values(ButtonPushAnimationSize),
|
|
17
|
+
description: 'The size of the button',
|
|
18
|
+
},
|
|
19
|
+
disabled: { control: 'boolean', description: 'Whether the button is disabled' },
|
|
20
|
+
},
|
|
21
|
+
render: (args: ButtonPushAnimationProps) => {
|
|
22
|
+
return <ButtonPushAnimation {...args} />;
|
|
23
|
+
},
|
|
24
|
+
code: `import { ButtonPushAnimation, ButtonPushAnimationSize } from 'lupine.components/components/button-push-animation';
|
|
25
|
+
|
|
26
|
+
<ButtonPushAnimation
|
|
27
|
+
text="Push Me"
|
|
28
|
+
size={ButtonPushAnimationSize.Medium}
|
|
29
|
+
onClick={() => console.log('Pushed!')}
|
|
30
|
+
/>
|
|
31
|
+
`,
|
|
32
|
+
};
|
|
@@ -86,6 +86,10 @@ export const ButtonPushAnimation = (props: ButtonPushAnimationProps) => {
|
|
|
86
86
|
textShadow: 'rgba(0, 0, 0, 0.1) 0 0 0.1em',
|
|
87
87
|
userSelect: 'none',
|
|
88
88
|
},
|
|
89
|
+
'&:disabled .button-inner span': {
|
|
90
|
+
backgroundImage: 'linear-gradient(135deg, rgba(150, 150, 150, 1), rgba(200, 200, 200, 1))',
|
|
91
|
+
opacity: 0.7,
|
|
92
|
+
},
|
|
89
93
|
'&.button-ss': {
|
|
90
94
|
borderRadius: '2px',
|
|
91
95
|
},
|
|
@@ -114,17 +118,17 @@ export const ButtonPushAnimation = (props: ButtonPushAnimationProps) => {
|
|
|
114
118
|
padding: '0.5rem 1.5rem',
|
|
115
119
|
fontSize: '2rem',
|
|
116
120
|
},
|
|
117
|
-
'&:active .button-outer': {
|
|
121
|
+
'&:active:not(:disabled) .button-outer': {
|
|
118
122
|
boxShadow: '0 0 0 0 rgba(5, 5, 5, 1), 0 0 0 0 rgba(5, 5, 5, 0.5), 0 0 0 0 rgba(5, 5, 5, 0.25)',
|
|
119
123
|
},
|
|
120
|
-
'&:active .button-inner': {
|
|
124
|
+
'&:active:not(:disabled) .button-inner': {
|
|
121
125
|
boxShadow:
|
|
122
126
|
'0.1em 0.15em 0.05em 0 inset rgba(5, 5, 5, 0.75), -0.025em -0.03em 0.05em 0.025em inset rgba(5, 5, 5, 0.5), 0.25em 0.25em 0.2em 0 inset rgba(5, 5, 5, 0.5), 0 0 0.05em 0.5em inset rgba(255, 255, 255, 0.15), 0 0 0 0 inset rgba(255, 255, 255, 1), 0.12em 0.12em 0.12em inset rgba(255, 255, 255, 0.25), -0.075em -0.12em 0.2em 0.1em inset rgba(5, 5, 5, 0.25)',
|
|
123
127
|
},
|
|
124
|
-
'&:hover .button-inner': {
|
|
128
|
+
'&:hover:not(:disabled) .button-inner': {
|
|
125
129
|
transform: 'scale(0.99)',
|
|
126
130
|
},
|
|
127
|
-
'&:hover .button-inner span': {
|
|
131
|
+
'&:hover:not(:disabled) .button-inner span': {
|
|
128
132
|
transform: 'scale(0.975)',
|
|
129
133
|
},
|
|
130
134
|
...props.css,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { EditableLabel, EditableLabelProps } from './editable-label';
|
|
3
|
+
|
|
4
|
+
export const editableLabelDemo: DemoStory<EditableLabelProps> = {
|
|
5
|
+
id: 'editable-label-demo',
|
|
6
|
+
text: 'Editable Label Demo',
|
|
7
|
+
args: {
|
|
8
|
+
text: 'Double click to edit me!',
|
|
9
|
+
mandtory: false,
|
|
10
|
+
},
|
|
11
|
+
argTypes: {
|
|
12
|
+
text: { control: 'text', description: 'Initial text content' },
|
|
13
|
+
mandtory: { control: 'boolean', description: 'If true, value cannot be left empty' },
|
|
14
|
+
},
|
|
15
|
+
render: (args: EditableLabelProps) => {
|
|
16
|
+
return (
|
|
17
|
+
<div style={{ padding: '20px', width: '300px' }}>
|
|
18
|
+
<p style={{ color: '#666', fontSize: '13px', marginBottom: '10px' }}>
|
|
19
|
+
Instructions: Double-click the text below to switch to edit mode. Press Enter to save, or Escape to cancel.
|
|
20
|
+
</p>
|
|
21
|
+
<EditableLabel {...args} save={(val) => console.log('Saved:', val)} />
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
},
|
|
25
|
+
code: `import { EditableLabel } from 'lupine.components/components/editable-label';
|
|
26
|
+
|
|
27
|
+
<EditableLabel
|
|
28
|
+
text="Double click to edit me!"
|
|
29
|
+
mandtory={false}
|
|
30
|
+
save={(val) => console.log('Saved:', val)}
|
|
31
|
+
/>
|
|
32
|
+
`,
|
|
33
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { InputWithTitle } from './input-with-title';
|
|
3
|
+
|
|
4
|
+
export const inputWithTitleDemo: DemoStory<any> = {
|
|
5
|
+
id: 'input-with-title-demo',
|
|
6
|
+
text: 'Input With Title Demo',
|
|
7
|
+
args: {
|
|
8
|
+
title: 'Enter your name',
|
|
9
|
+
defaultValue: 'John Doe',
|
|
10
|
+
width: '250px',
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
title: { control: 'text', description: 'Title text shown above input' },
|
|
14
|
+
defaultValue: { control: 'text', description: 'Initial default value' },
|
|
15
|
+
width: { control: 'text', description: 'Width of the input container' },
|
|
16
|
+
},
|
|
17
|
+
render: (args) => {
|
|
18
|
+
return (
|
|
19
|
+
<div style={{ padding: '20px' }}>
|
|
20
|
+
{InputWithTitle(
|
|
21
|
+
args.title,
|
|
22
|
+
args.defaultValue,
|
|
23
|
+
(val) => console.log('Input onChange:', val),
|
|
24
|
+
(val) => console.log('Input onInput:', val),
|
|
25
|
+
'input-base',
|
|
26
|
+
args.width
|
|
27
|
+
)}
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
code: `import { InputWithTitle } from 'lupine.components/components/input-with-title';
|
|
32
|
+
|
|
33
|
+
{InputWithTitle(
|
|
34
|
+
'Enter your name', // title
|
|
35
|
+
'John Doe', // defaultValue
|
|
36
|
+
(val) => console.log('onChange:', val),
|
|
37
|
+
(val) => console.log('onInput:', val),
|
|
38
|
+
'input-base', // className
|
|
39
|
+
'250px' // width
|
|
40
|
+
)}
|
|
41
|
+
`,
|
|
42
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { NotificationColor, NotificationMessage } from 'lupine.components';
|
|
2
|
+
import { DemoStory } from '../demo/demo-types';
|
|
3
|
+
import { MessageBox, MessageBoxButtonProps } from './message-box';
|
|
4
|
+
import { Button, ButtonSize } from './button';
|
|
5
|
+
|
|
6
|
+
export const messageBoxDemo: DemoStory<any> = {
|
|
7
|
+
id: 'message-box-demo',
|
|
8
|
+
text: 'MessageBox Demo',
|
|
9
|
+
args: {
|
|
10
|
+
title: 'System Alert',
|
|
11
|
+
contentMinWidth: '300px',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
title: { control: 'text', description: 'Title of the MessageBox' },
|
|
15
|
+
contentMinWidth: { control: 'text', description: 'Minimum width of MessageBox' },
|
|
16
|
+
},
|
|
17
|
+
render: (args) => {
|
|
18
|
+
return (
|
|
19
|
+
<div style={{ padding: '20px' }}>
|
|
20
|
+
<p style={{ color: '#666', marginBottom: '20px' }}>Test different button configurations for MessageBox.</p>
|
|
21
|
+
|
|
22
|
+
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
23
|
+
<Button
|
|
24
|
+
text='Yes / No Dialog'
|
|
25
|
+
size={ButtonSize.Medium}
|
|
26
|
+
onClick={() => {
|
|
27
|
+
MessageBox.show({
|
|
28
|
+
title: args.title,
|
|
29
|
+
buttonType: MessageBoxButtonProps.YesNo,
|
|
30
|
+
contentMinWidth: args.contentMinWidth,
|
|
31
|
+
children: <div style={{ padding: '20px' }}>Are you sure you want to proceed?</div>,
|
|
32
|
+
handleClicked: (index, close) => {
|
|
33
|
+
const result = index === 0 ? 'Yes' : 'No';
|
|
34
|
+
NotificationMessage.sendMessage('You clicked: ' + result, NotificationColor.Info);
|
|
35
|
+
close();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<Button
|
|
42
|
+
text='Ok / Cancel Dialog'
|
|
43
|
+
size={ButtonSize.Medium}
|
|
44
|
+
onClick={() => {
|
|
45
|
+
MessageBox.show({
|
|
46
|
+
title: args.title,
|
|
47
|
+
buttonType: MessageBoxButtonProps.OkCancel,
|
|
48
|
+
contentMinWidth: args.contentMinWidth,
|
|
49
|
+
children: <div style={{ padding: '20px' }}>Please confirm this action.</div>,
|
|
50
|
+
handleClicked: (index, close) => {
|
|
51
|
+
const result = index === 0 ? 'OK' : 'Cancel';
|
|
52
|
+
const level = index === 0 ? NotificationColor.Success : NotificationColor.Warning;
|
|
53
|
+
NotificationMessage.sendMessage('You clicked: ' + result, level);
|
|
54
|
+
close();
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
<Button
|
|
61
|
+
text='Ok Only'
|
|
62
|
+
size={ButtonSize.Medium}
|
|
63
|
+
onClick={() => {
|
|
64
|
+
MessageBox.show({
|
|
65
|
+
title: args.title,
|
|
66
|
+
buttonType: MessageBoxButtonProps.Ok,
|
|
67
|
+
contentMinWidth: args.contentMinWidth,
|
|
68
|
+
children: <div style={{ padding: '20px' }}>Operation completed successfully!</div>,
|
|
69
|
+
handleClicked: (index, close) => {
|
|
70
|
+
NotificationMessage.sendMessage('Dialog dismissed', NotificationColor.Success);
|
|
71
|
+
close();
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
code: `import { MessageBox, MessageBoxButtonProps } from 'lupine.components/components/message-box';
|
|
81
|
+
|
|
82
|
+
// Quick Alert
|
|
83
|
+
MessageBox.show({
|
|
84
|
+
title: 'System Alert',
|
|
85
|
+
buttonType: MessageBoxButtonProps.Ok,
|
|
86
|
+
children: <div style={{ padding: '20px' }}>Operation completed successfully!</div>,
|
|
87
|
+
handleClicked: (index, close) => {
|
|
88
|
+
close();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Confirmation Dialog
|
|
93
|
+
MessageBox.show({
|
|
94
|
+
title: 'Confirm Action',
|
|
95
|
+
buttonType: MessageBoxButtonProps.OkCancel,
|
|
96
|
+
children: <div style={{ padding: '20px' }}>Are you sure you want to proceed?</div>,
|
|
97
|
+
handleClicked: (index, close) => {
|
|
98
|
+
if (index === 0) {
|
|
99
|
+
console.log('User clicked OK');
|
|
100
|
+
} else {
|
|
101
|
+
console.log('User clicked Cancel');
|
|
102
|
+
}
|
|
103
|
+
close();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
`,
|
|
107
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { ModalWindow } from './modal';
|
|
3
|
+
import { Button, ButtonSize } from './button';
|
|
4
|
+
|
|
5
|
+
export const modalDemo: DemoStory<any> = {
|
|
6
|
+
id: 'modal-demo',
|
|
7
|
+
text: 'Modal Window Demo',
|
|
8
|
+
args: {
|
|
9
|
+
title: 'Example Modal',
|
|
10
|
+
noMoving: true,
|
|
11
|
+
noModal: false,
|
|
12
|
+
contentMinWidth: '300px',
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
title: { control: 'text', description: 'Title of the modal' },
|
|
16
|
+
noMoving: { control: 'boolean', description: 'Disable dragging?' },
|
|
17
|
+
noModal: { control: 'boolean', description: "If true, it won't block background interaction" },
|
|
18
|
+
contentMinWidth: { control: 'text', description: 'Minimum width of modal' },
|
|
19
|
+
},
|
|
20
|
+
render: (args) => {
|
|
21
|
+
return (
|
|
22
|
+
<div style={{ padding: '20px' }}>
|
|
23
|
+
<Button
|
|
24
|
+
text='Open Modal'
|
|
25
|
+
size={ButtonSize.Medium}
|
|
26
|
+
onClick={() => {
|
|
27
|
+
ModalWindow.show({
|
|
28
|
+
title: args.title,
|
|
29
|
+
children: <div style={{ padding: '20px' }}>This is the modal content!</div>,
|
|
30
|
+
noMoving: args.noMoving,
|
|
31
|
+
noModal: args.noModal,
|
|
32
|
+
contentMinWidth: args.contentMinWidth,
|
|
33
|
+
buttons: ['Cancel', 'Confirm'],
|
|
34
|
+
handleClicked: (ind, close) => {
|
|
35
|
+
console.log('Clicked button:', ind);
|
|
36
|
+
close();
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
code: `import { ModalWindow } from 'lupine.components/components/modal';
|
|
45
|
+
|
|
46
|
+
ModalWindow.show({
|
|
47
|
+
title: 'Example Modal',
|
|
48
|
+
children: <div style={{ padding: '20px' }}>This is the modal content!</div>,
|
|
49
|
+
buttons: ['Cancel', 'Confirm'],
|
|
50
|
+
handleClicked: (ind, close) => {
|
|
51
|
+
console.log('Clicked button:', ind);
|
|
52
|
+
close();
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
`,
|
|
56
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { NotificationMessage, NotificationColor } from './notice-message';
|
|
3
|
+
import { Button, ButtonSize } from './button';
|
|
4
|
+
|
|
5
|
+
export const noticeMessageDemo: DemoStory<any> = {
|
|
6
|
+
id: 'notice-message-demo',
|
|
7
|
+
text: 'Notice Message Demo',
|
|
8
|
+
args: {
|
|
9
|
+
message: 'Action completed successfully!',
|
|
10
|
+
permanent: false,
|
|
11
|
+
showTime: 3000,
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
message: { control: 'text', description: 'Message content' },
|
|
15
|
+
permanent: { control: 'boolean', description: 'If true, stays until manually closed' },
|
|
16
|
+
showTime: { control: 'number', description: 'Time in ms to show (if not permanent)' },
|
|
17
|
+
},
|
|
18
|
+
render: (args) => {
|
|
19
|
+
return (
|
|
20
|
+
<div style={{ padding: '20px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
21
|
+
<Button
|
|
22
|
+
text='Show Info'
|
|
23
|
+
size={ButtonSize.Medium}
|
|
24
|
+
onClick={() =>
|
|
25
|
+
NotificationMessage.sendMessage(args.message, NotificationColor.Info, args.permanent, args.showTime)
|
|
26
|
+
}
|
|
27
|
+
/>
|
|
28
|
+
<Button
|
|
29
|
+
text='Show Success'
|
|
30
|
+
size={ButtonSize.Medium}
|
|
31
|
+
onClick={() =>
|
|
32
|
+
NotificationMessage.sendMessage(args.message, NotificationColor.Success, args.permanent, args.showTime)
|
|
33
|
+
}
|
|
34
|
+
/>
|
|
35
|
+
<Button
|
|
36
|
+
text='Show Warning'
|
|
37
|
+
size={ButtonSize.Medium}
|
|
38
|
+
onClick={() =>
|
|
39
|
+
NotificationMessage.sendMessage(args.message, NotificationColor.Warning, args.permanent, args.showTime)
|
|
40
|
+
}
|
|
41
|
+
/>
|
|
42
|
+
<Button
|
|
43
|
+
text='Show Error'
|
|
44
|
+
size={ButtonSize.Medium}
|
|
45
|
+
onClick={() =>
|
|
46
|
+
NotificationMessage.sendMessage(args.message, NotificationColor.Error, args.permanent, args.showTime)
|
|
47
|
+
}
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
code: `import { NotificationMessage, NotificationColor } from 'lupine.components/components/notice-message';
|
|
53
|
+
|
|
54
|
+
// Show Info
|
|
55
|
+
NotificationMessage.sendMessage('Action completed successfully!', NotificationColor.Info);
|
|
56
|
+
|
|
57
|
+
// Show Success (permanent)
|
|
58
|
+
NotificationMessage.sendMessage('Action completed successfully!', NotificationColor.Success, true);
|
|
59
|
+
`,
|
|
60
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { DemoStory } from '../demo/demo-types';
|
|
2
|
+
import { PopupMenuWithButton, PopupMenuWithLabel, PopupMenuWithIcon } from './popup-menu';
|
|
3
|
+
|
|
4
|
+
export const popupMenuDemo: DemoStory<any> = {
|
|
5
|
+
id: 'popup-menu-demo',
|
|
6
|
+
text: 'Popup Menu Demo',
|
|
7
|
+
args: {
|
|
8
|
+
label: 'Actions',
|
|
9
|
+
defaultValue: 'Select...',
|
|
10
|
+
align: 'right',
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
label: { control: 'text', description: 'Label for button/text triggers' },
|
|
14
|
+
defaultValue: { control: 'text', description: 'Default selected text' },
|
|
15
|
+
align: { control: 'select', options: ['left', 'right'], description: 'Menu drop alignment' },
|
|
16
|
+
},
|
|
17
|
+
render: (args) => {
|
|
18
|
+
const list = ['Edit Profile', 'Settings', '', 'Log Out'];
|
|
19
|
+
return (
|
|
20
|
+
<div style={{ padding: '20px', display: 'flex', gap: '40px', alignItems: 'flex-start' }}>
|
|
21
|
+
<div>
|
|
22
|
+
<h3>With Button</h3>
|
|
23
|
+
<PopupMenuWithButton
|
|
24
|
+
label={args.label}
|
|
25
|
+
list={list}
|
|
26
|
+
defaultValue={args.defaultValue}
|
|
27
|
+
align={args.align}
|
|
28
|
+
handleSelected={(val: string) => console.log('Selected:', val)}
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div>
|
|
33
|
+
<h3>With Label</h3>
|
|
34
|
+
<PopupMenuWithLabel label={args.label} list={list} defaultValue={args.defaultValue} align={args.align} />
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div>
|
|
38
|
+
<h3>With Icon</h3>
|
|
39
|
+
<PopupMenuWithIcon
|
|
40
|
+
list={list}
|
|
41
|
+
defaultValue={args.defaultValue}
|
|
42
|
+
align={args.align}
|
|
43
|
+
icon={<span style={{ fontSize: '24px' }}>⚙️</span>}
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
code: `import { PopupMenuWithButton, PopupMenuWithLabel, PopupMenuWithIcon } from 'lupine.components/components/popup-menu';
|
|
50
|
+
|
|
51
|
+
const list = ['Edit Profile', 'Settings', '', 'Log Out'];
|
|
52
|
+
|
|
53
|
+
{/* With Button */}
|
|
54
|
+
<PopupMenuWithButton
|
|
55
|
+
label="Actions"
|
|
56
|
+
list={list}
|
|
57
|
+
defaultValue="Select..."
|
|
58
|
+
align="right"
|
|
59
|
+
handleSelected={(val: string) => console.log('Selected:', val)}
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
{/* With Icon */}
|
|
63
|
+
<PopupMenuWithIcon
|
|
64
|
+
list={list}
|
|
65
|
+
icon={<span style={{ fontSize: '24px' }}>⚙️</span>}
|
|
66
|
+
/>
|
|
67
|
+
`,
|
|
68
|
+
};
|
|
@@ -186,7 +186,7 @@ export const PopupMenu = ({
|
|
|
186
186
|
padding: '5px 0px',
|
|
187
187
|
overflow: 'auto',
|
|
188
188
|
'line-height': '1.2em',
|
|
189
|
-
'min-width': minWidth || '
|
|
189
|
+
'min-width': minWidth || 'max-content',
|
|
190
190
|
'max-width': maxWidth || '200px',
|
|
191
191
|
'max-height': maxHeight || '300px',
|
|
192
192
|
'box-shadow': 'var(--cover-box-shadow)', //'#0000004c 0px 19px 38px, #00000038 0px 15px 12px',
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { RefProps } from 'lupine.web';
|
|
2
|
+
import { DemoStory } from '../demo/demo-types';
|
|
3
|
+
import { Progress, ProgressHookProps } from './progress';
|
|
4
|
+
|
|
5
|
+
// Note: Progress uses a singleton-like hook approach internally,
|
|
6
|
+
// so we create a dummy hook object to interact with it.
|
|
7
|
+
const progressHook: ProgressHookProps = {};
|
|
8
|
+
|
|
9
|
+
export const progressDemo: DemoStory<any> = {
|
|
10
|
+
id: 'progress-demo',
|
|
11
|
+
text: 'Progress Demo',
|
|
12
|
+
args: {
|
|
13
|
+
simulate: false,
|
|
14
|
+
},
|
|
15
|
+
argTypes: {
|
|
16
|
+
simulate: {
|
|
17
|
+
control: 'boolean',
|
|
18
|
+
description: 'Check this to simulate a 3-second progress upload',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
render: (args) => {
|
|
22
|
+
const ref: RefProps = {
|
|
23
|
+
onLoad: async () => {
|
|
24
|
+
// If the simulate toggle is flipped, run a fake progression
|
|
25
|
+
if (args.simulate && progressHook.onShow) {
|
|
26
|
+
progressHook.onShow(true, 'Simulating Upload...');
|
|
27
|
+
let p = 0;
|
|
28
|
+
const interval = setInterval(() => {
|
|
29
|
+
p += 3;
|
|
30
|
+
if (p > 100) {
|
|
31
|
+
clearInterval(interval);
|
|
32
|
+
progressHook.onShow!(false);
|
|
33
|
+
} else {
|
|
34
|
+
progressHook.onProgress!(p / 100);
|
|
35
|
+
}
|
|
36
|
+
}, 100);
|
|
37
|
+
} else if (!args.simulate && progressHook.onShow) {
|
|
38
|
+
progressHook.onShow(false);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return (
|
|
43
|
+
<div ref={ref} style={{ padding: '20px' }}>
|
|
44
|
+
<p style={{ color: '#666' }}>
|
|
45
|
+
Toggle the 'simulate' control to see the fixed progress bar at the bottom of the screen.
|
|
46
|
+
</p>
|
|
47
|
+
<Progress hook={progressHook} />
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
code: `import { Progress, ProgressHookProps } from 'lupine.components/components/progress';
|
|
52
|
+
|
|
53
|
+
const progressHook: ProgressHookProps = {};
|
|
54
|
+
|
|
55
|
+
// 1. Render the component somewhere in your app (usually near the root)
|
|
56
|
+
<Progress hook={progressHook} />
|
|
57
|
+
|
|
58
|
+
// 2. Control it via the hook
|
|
59
|
+
progressHook.onShow!(true, 'Uploading...'); // Show progress
|
|
60
|
+
progressHook.onProgress!(0.5); // Set to 50%
|
|
61
|
+
progressHook.onShow!(false); // Hide
|
|
62
|
+
`,
|
|
63
|
+
};
|