@kirill.konshin/bootstrap 0.0.2 → 0.0.3
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/dist/adaptiveContainer.d.ts.map +1 -1
- package/dist/adaptiveContainer.js +14 -9
- package/dist/adaptiveContainer.js.map +1 -1
- package/dist/adaptiveContainer.stories.d.ts +2 -2
- package/dist/adaptiveContainer.stories.d.ts.map +1 -1
- package/dist/controls.d.ts +4 -4
- package/dist/controls.d.ts.map +1 -1
- package/dist/controls.js +79 -72
- package/dist/controls.js.map +1 -1
- package/dist/controls.stories.d.ts +2 -2
- package/dist/controls.stories.d.ts.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +23 -24
- package/dist/error.js.map +1 -1
- package/dist/error.stories.d.ts +2 -2
- package/dist/error.stories.d.ts.map +1 -1
- package/dist/field.d.ts.map +1 -1
- package/dist/field.js +27 -27
- package/dist/field.js.map +1 -1
- package/dist/field.stories.d.ts +2 -2
- package/dist/field.stories.d.ts.map +1 -1
- package/dist/footer.d.ts.map +1 -1
- package/dist/footer.js +41 -42
- package/dist/footer.js.map +1 -1
- package/dist/footer.stories.d.ts +2 -2
- package/dist/footer.stories.d.ts.map +1 -1
- package/dist/globalLoading.d.ts.map +1 -1
- package/dist/globalLoading.js +13 -9
- package/dist/globalLoading.js.map +1 -1
- package/dist/globalLoading.stories.d.ts +2 -2
- package/dist/globalLoading.stories.d.ts.map +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.js +3 -25
- package/dist/loading.d.ts.map +1 -1
- package/dist/loading.js +19 -17
- package/dist/loading.js.map +1 -1
- package/dist/loading.stories.d.ts +2 -2
- package/dist/loading.stories.d.ts.map +1 -1
- package/dist/responsiveHelper.d.ts.map +1 -1
- package/dist/responsiveHelper.js +69 -42
- package/dist/responsiveHelper.js.map +1 -1
- package/dist/responsiveHelper.stories.d.ts +2 -2
- package/dist/responsiveHelper.stories.d.ts.map +1 -1
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +84 -77
- package/dist/screen.js.map +1 -1
- package/dist/screen.stories.d.ts +2 -2
- package/dist/screen.stories.d.ts.map +1 -1
- package/dist/toaster.d.ts.map +1 -1
- package/dist/toaster.js +29 -30
- package/dist/toaster.js.map +1 -1
- package/dist/toaster.stories.d.ts +2 -2
- package/dist/toaster.stories.d.ts.map +1 -1
- package/dist/useModal.d.ts.map +1 -1
- package/dist/useModal.js +58 -47
- package/dist/useModal.js.map +1 -1
- package/dist/useModal.stories.d.ts +2 -2
- package/dist/useModal.stories.d.ts.map +1 -1
- package/dist/useWrappedForm.d.ts.map +1 -1
- package/dist/useWrappedForm.js +40 -29
- package/dist/useWrappedForm.js.map +1 -1
- package/package.json +17 -5
- package/.ctirc +0 -20
- package/.storybook/main.ts +0 -2
- package/.storybook/preview.ts +0 -2
- package/.turbo/turbo-build.log +0 -31
- package/CHANGELOG.md +0 -8
- package/dist/index.js.map +0 -1
- package/src/adaptiveContainer.stories.tsx +0 -59
- package/src/adaptiveContainer.tsx +0 -14
- package/src/controls.stories.tsx +0 -62
- package/src/controls.tsx +0 -119
- package/src/error.stories.tsx +0 -34
- package/src/error.tsx +0 -37
- package/src/field.stories.tsx +0 -42
- package/src/field.tsx +0 -37
- package/src/footer.stories.tsx +0 -121
- package/src/footer.tsx +0 -65
- package/src/globalLoading.stories.tsx +0 -25
- package/src/globalLoading.tsx +0 -19
- package/src/index.ts +0 -12
- package/src/loading.stories.tsx +0 -35
- package/src/loading.tsx +0 -24
- package/src/main.scss +0 -86
- package/src/responsiveHelper.stories.tsx +0 -109
- package/src/responsiveHelper.tsx +0 -55
- package/src/screen.stories.tsx +0 -160
- package/src/screen.tsx +0 -146
- package/src/toaster.stories.tsx +0 -32
- package/src/toaster.tsx +0 -40
- package/src/useModal.stories.tsx +0 -51
- package/src/useModal.tsx +0 -93
- package/src/useWrappedForm.ts +0 -42
- package/tsconfig.json +0 -10
- package/turbo.json +0 -10
- package/vite.config.ts +0 -2
package/src/controls.tsx
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import React, { HTMLInputTypeAttribute, memo, FC } from 'react';
|
|
2
|
-
|
|
3
|
-
const lcFirst = (str: string) => str[0].toLowerCase() + str.substring(1, str.length);
|
|
4
|
-
|
|
5
|
-
const toProperty = (str: string) => lcFirst(str).split(' ').join('');
|
|
6
|
-
|
|
7
|
-
export interface ControlProps {
|
|
8
|
-
value?: any;
|
|
9
|
-
setValue?: (v: any) => void;
|
|
10
|
-
defaultValue?: any;
|
|
11
|
-
options?: { [key: string]: any };
|
|
12
|
-
setOptions?: (v: { [key: string]: any }) => void;
|
|
13
|
-
defaultOptions?: { [key: string]: any };
|
|
14
|
-
name: string;
|
|
15
|
-
children?: React.ReactNode;
|
|
16
|
-
inputProps?: {
|
|
17
|
-
type: HTMLInputTypeAttribute;
|
|
18
|
-
property?: string;
|
|
19
|
-
valueExtractor?: (e: any) => any;
|
|
20
|
-
className?: string;
|
|
21
|
-
} & any;
|
|
22
|
-
hideValue?: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type LabelProps = Pick<ControlProps, 'name' | 'value' | 'defaultValue'> & { reset: () => void };
|
|
26
|
-
|
|
27
|
-
export const Label: FC<LabelProps> = memo(function Label({ name, reset, value, defaultValue }) {
|
|
28
|
-
return (
|
|
29
|
-
<label className="flex-grow-1 mb-0 d-flex align-items-center justify-content-start gap-2">
|
|
30
|
-
{name}
|
|
31
|
-
{value !== defaultValue && (
|
|
32
|
-
<>
|
|
33
|
-
<a href="javascript: void(0)" onClick={reset}>
|
|
34
|
-
<small>reset</small>
|
|
35
|
-
</a>
|
|
36
|
-
</>
|
|
37
|
-
)}
|
|
38
|
-
</label>
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
export const Control: FC<ControlProps> = memo(function Control({
|
|
43
|
-
value = null,
|
|
44
|
-
setValue,
|
|
45
|
-
defaultValue = null,
|
|
46
|
-
options = {},
|
|
47
|
-
setOptions,
|
|
48
|
-
defaultOptions = {},
|
|
49
|
-
name,
|
|
50
|
-
inputProps: { Tag = 'input', property = 'value', valueExtractor = (e: any) => e.target.value, ...inputProps } = {},
|
|
51
|
-
hideValue = false,
|
|
52
|
-
children,
|
|
53
|
-
}) {
|
|
54
|
-
const prop = toProperty(name);
|
|
55
|
-
|
|
56
|
-
defaultValue = defaultValue || defaultOptions[prop];
|
|
57
|
-
value = value || options?.[prop];
|
|
58
|
-
setValue = setValue || ((v) => setOptions?.({ [prop]: v }));
|
|
59
|
-
|
|
60
|
-
const reset = () => setValue(defaultValue);
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<div className="d-flex align-items-center gap-2">
|
|
64
|
-
<Label name={name} reset={reset} value={value} defaultValue={defaultValue} />
|
|
65
|
-
<Tag
|
|
66
|
-
{...inputProps}
|
|
67
|
-
{...{ [property]: value || '' }} // null is needed to make it always controlled
|
|
68
|
-
className={`${value === defaultValue ? 'opacity-75' : ''} ${inputProps.className}`}
|
|
69
|
-
onChange={(e: Event) => setValue(valueExtractor(e))}
|
|
70
|
-
>
|
|
71
|
-
{children}
|
|
72
|
-
</Tag>
|
|
73
|
-
{!hideValue && (
|
|
74
|
-
<span onDoubleClick={reset} className="text-start" style={{ width: '20px' }}>
|
|
75
|
-
{value}
|
|
76
|
-
</span>
|
|
77
|
-
)}
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
export interface RangeProps extends ControlProps {
|
|
83
|
-
min: number;
|
|
84
|
-
max: number;
|
|
85
|
-
step?: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export const Range: FC<RangeProps> = memo(function Range({ min, max, step = 0.1, ...props }) {
|
|
89
|
-
return (
|
|
90
|
-
<Control
|
|
91
|
-
inputProps={{
|
|
92
|
-
type: 'range',
|
|
93
|
-
min,
|
|
94
|
-
max,
|
|
95
|
-
step,
|
|
96
|
-
className: 'form-control-range',
|
|
97
|
-
valueExtractor: (e: any) => parseFloat(e.target.value),
|
|
98
|
-
}}
|
|
99
|
-
{...props}
|
|
100
|
-
/>
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
export const Checkbox: FC<ControlProps> = memo(function Checkbox(props) {
|
|
105
|
-
return (
|
|
106
|
-
<Control
|
|
107
|
-
inputProps={{ type: 'checkbox', property: 'checked', valueExtractor: (e: any) => e.target.checked }}
|
|
108
|
-
{...props}
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
export const Select: FC<ControlProps> = memo(function Select({ children, ...props }) {
|
|
114
|
-
return (
|
|
115
|
-
<Control inputProps={{ Tag: 'select', className: 'form-select' }} {...props} hideValue={true}>
|
|
116
|
-
{children}
|
|
117
|
-
</Control>
|
|
118
|
-
);
|
|
119
|
-
});
|
package/src/error.stories.tsx
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { fn } from '@storybook/test';
|
|
3
|
-
|
|
4
|
-
import { ErrorAlert } from './error';
|
|
5
|
-
|
|
6
|
-
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
|
7
|
-
const meta: Meta<typeof ErrorAlert> = {
|
|
8
|
-
title: 'Bootstrap / ErrorAlert',
|
|
9
|
-
component: ErrorAlert,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
},
|
|
13
|
-
tags: ['autodocs'],
|
|
14
|
-
argTypes: {
|
|
15
|
-
// backgroundColor: { control: 'color' },
|
|
16
|
-
children: { control: 'text' },
|
|
17
|
-
},
|
|
18
|
-
args: { onRetry: fn() },
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof meta>;
|
|
23
|
-
|
|
24
|
-
export const String: Story = {
|
|
25
|
-
args: {
|
|
26
|
-
children: 'An error occurred',
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const ErrorObject: Story = {
|
|
31
|
-
args: {
|
|
32
|
-
children: new Error('An error occurred') as any,
|
|
33
|
-
},
|
|
34
|
-
};
|
package/src/error.tsx
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React, { FC, memo } from 'react';
|
|
4
|
-
import { Alert, AlertProps, Button, ButtonProps } from 'react-bootstrap';
|
|
5
|
-
|
|
6
|
-
export type ErrorAlertProps = {
|
|
7
|
-
children?: Error | string | any;
|
|
8
|
-
onRetry?: () => any;
|
|
9
|
-
buttonProps?: ButtonProps;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
//TODO Create MUI-specific?
|
|
13
|
-
export const ErrorAlert: FC<ErrorAlertProps> = memo(function ErrorAlert({ onRetry, children, buttonProps, ...props }) {
|
|
14
|
-
if (!children) return null;
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<Alert variant="danger" {...props}>
|
|
18
|
-
<div>{children.message || children.toString()}</div>
|
|
19
|
-
{onRetry && (
|
|
20
|
-
<div>
|
|
21
|
-
<Button
|
|
22
|
-
variant="link"
|
|
23
|
-
className="alert-link"
|
|
24
|
-
{...buttonProps}
|
|
25
|
-
onClick={(e) => {
|
|
26
|
-
e.preventDefault();
|
|
27
|
-
e.stopPropagation();
|
|
28
|
-
onRetry();
|
|
29
|
-
}}
|
|
30
|
-
>
|
|
31
|
-
Retry
|
|
32
|
-
</Button>
|
|
33
|
-
</div>
|
|
34
|
-
)}
|
|
35
|
-
</Alert>
|
|
36
|
-
);
|
|
37
|
-
});
|
package/src/field.stories.tsx
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
import { fn } from '@storybook/test';
|
|
4
|
-
|
|
5
|
-
import { FieldGroup } from './field';
|
|
6
|
-
import { FormControl } from 'react-bootstrap';
|
|
7
|
-
|
|
8
|
-
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
|
9
|
-
const meta: Meta<typeof FieldGroup> = {
|
|
10
|
-
title: 'Bootstrap / FieldGroup',
|
|
11
|
-
component: FieldGroup,
|
|
12
|
-
parameters: {
|
|
13
|
-
layout: 'centered',
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs'],
|
|
16
|
-
argTypes: {
|
|
17
|
-
text: { control: 'text' },
|
|
18
|
-
label: { control: 'text' },
|
|
19
|
-
horizontal: { control: 'check' },
|
|
20
|
-
},
|
|
21
|
-
args: { onClick: fn() },
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export default meta;
|
|
25
|
-
|
|
26
|
-
type Story = StoryObj<typeof meta>;
|
|
27
|
-
|
|
28
|
-
export const Vertical: Story = {
|
|
29
|
-
args: {
|
|
30
|
-
label: 'Label',
|
|
31
|
-
children: <FormControl placeholder="Input" />,
|
|
32
|
-
text: 'Text',
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const Horizontal: Story = {
|
|
37
|
-
args: {
|
|
38
|
-
label: 'Label',
|
|
39
|
-
children: <FormControl placeholder="Input" />,
|
|
40
|
-
horizontal: true,
|
|
41
|
-
},
|
|
42
|
-
};
|
package/src/field.tsx
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import React, { FC, memo } from 'react';
|
|
2
|
-
import { Form, FormGroupProps, FormLabelProps, FormTextProps } from 'react-bootstrap';
|
|
3
|
-
|
|
4
|
-
export type FieldGroupProps = FormGroupProps & {
|
|
5
|
-
label?: any;
|
|
6
|
-
labelProps?: FormLabelProps;
|
|
7
|
-
text?: any;
|
|
8
|
-
textProps?: FormTextProps;
|
|
9
|
-
horizontal?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const FieldGroup: FC<FieldGroupProps> = memo(function FieldGroup({
|
|
13
|
-
label,
|
|
14
|
-
labelProps = {},
|
|
15
|
-
text,
|
|
16
|
-
textProps = {},
|
|
17
|
-
horizontal,
|
|
18
|
-
children,
|
|
19
|
-
...props
|
|
20
|
-
}) {
|
|
21
|
-
if (horizontal) {
|
|
22
|
-
props.className = 'hstack gap-3 ' + (props.className || '');
|
|
23
|
-
labelProps.className = 'm-0 ' + (labelProps.className || '');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (text && horizontal) {
|
|
27
|
-
throw new Error('Cannot use text and horizontal together');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<Form.Group {...props}>
|
|
32
|
-
{label && <Form.Label {...labelProps}>{label}</Form.Label>}
|
|
33
|
-
{children}
|
|
34
|
-
{text && !horizontal && <Form.Text {...textProps}>{text}</Form.Text>}{' '}
|
|
35
|
-
</Form.Group>
|
|
36
|
-
);
|
|
37
|
-
});
|
package/src/footer.stories.tsx
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
|
|
4
|
-
import { Footer, FooterNavItem } from './footer';
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof Footer> = {
|
|
7
|
-
title: 'Bootstrap / Footer',
|
|
8
|
-
component: Footer,
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'fullscreen',
|
|
11
|
-
},
|
|
12
|
-
tags: ['autodocs'],
|
|
13
|
-
argTypes: {},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
|
|
18
|
-
type Story = StoryObj<typeof meta>;
|
|
19
|
-
|
|
20
|
-
export const Default: Story = {
|
|
21
|
-
args: {
|
|
22
|
-
children: (
|
|
23
|
-
<>
|
|
24
|
-
<FooterNavItem href="#" icon="bi-house">
|
|
25
|
-
Home
|
|
26
|
-
</FooterNavItem>
|
|
27
|
-
<FooterNavItem href="#" icon="bi-search">
|
|
28
|
-
Search
|
|
29
|
-
</FooterNavItem>
|
|
30
|
-
<FooterNavItem href="#" icon="bi-person">
|
|
31
|
-
Profile
|
|
32
|
-
</FooterNavItem>
|
|
33
|
-
</>
|
|
34
|
-
),
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const WithActiveItem: Story = {
|
|
39
|
-
args: {
|
|
40
|
-
children: (
|
|
41
|
-
<>
|
|
42
|
-
<FooterNavItem href="#" icon="bi-house" active>
|
|
43
|
-
Home
|
|
44
|
-
</FooterNavItem>
|
|
45
|
-
<FooterNavItem href="#" icon="bi-search">
|
|
46
|
-
Search
|
|
47
|
-
</FooterNavItem>
|
|
48
|
-
<FooterNavItem href="#" icon="bi-gear">
|
|
49
|
-
Settings
|
|
50
|
-
</FooterNavItem>
|
|
51
|
-
<FooterNavItem href="#" icon="bi-person">
|
|
52
|
-
Profile
|
|
53
|
-
</FooterNavItem>
|
|
54
|
-
</>
|
|
55
|
-
),
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export const ManyItems: Story = {
|
|
60
|
-
args: {
|
|
61
|
-
children: (
|
|
62
|
-
<>
|
|
63
|
-
<FooterNavItem href="#" icon="bi-house">
|
|
64
|
-
Home
|
|
65
|
-
</FooterNavItem>
|
|
66
|
-
<FooterNavItem href="#" icon="bi-search">
|
|
67
|
-
Search
|
|
68
|
-
</FooterNavItem>
|
|
69
|
-
<FooterNavItem href="#" icon="bi-bell">
|
|
70
|
-
Notifications
|
|
71
|
-
</FooterNavItem>
|
|
72
|
-
<FooterNavItem href="#" icon="bi-chat">
|
|
73
|
-
Messages
|
|
74
|
-
</FooterNavItem>
|
|
75
|
-
<FooterNavItem href="#" icon="bi-person">
|
|
76
|
-
Profile
|
|
77
|
-
</FooterNavItem>
|
|
78
|
-
</>
|
|
79
|
-
),
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// FooterNavItem stories - rendered within Footer for proper context
|
|
84
|
-
export const NavItemDefault: StoryObj<typeof FooterNavItem> = {
|
|
85
|
-
args: {
|
|
86
|
-
href: '#',
|
|
87
|
-
icon: 'bi-house',
|
|
88
|
-
children: 'Home',
|
|
89
|
-
},
|
|
90
|
-
render: (args) => (
|
|
91
|
-
<Footer>
|
|
92
|
-
<FooterNavItem {...args} />
|
|
93
|
-
</Footer>
|
|
94
|
-
),
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export const NavItemActive: StoryObj<typeof FooterNavItem> = {
|
|
98
|
-
args: {
|
|
99
|
-
href: '#',
|
|
100
|
-
icon: 'bi-house',
|
|
101
|
-
children: 'Home',
|
|
102
|
-
active: true,
|
|
103
|
-
},
|
|
104
|
-
render: (args) => (
|
|
105
|
-
<Footer>
|
|
106
|
-
<FooterNavItem {...args} />
|
|
107
|
-
</Footer>
|
|
108
|
-
),
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export const NavItemIconOnly: StoryObj<typeof FooterNavItem> = {
|
|
112
|
-
args: {
|
|
113
|
-
href: '#',
|
|
114
|
-
icon: 'bi-bell',
|
|
115
|
-
},
|
|
116
|
-
render: (args) => (
|
|
117
|
-
<Footer>
|
|
118
|
-
<FooterNavItem {...args} />
|
|
119
|
-
</Footer>
|
|
120
|
-
),
|
|
121
|
-
};
|
package/src/footer.tsx
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import React, { FC, memo } from 'react';
|
|
2
|
-
import { Nav, Navbar } from 'react-bootstrap';
|
|
3
|
-
import { useBreakpoint } from './responsiveHelper';
|
|
4
|
-
import { AdaptiveContainer } from './adaptiveContainer';
|
|
5
|
-
|
|
6
|
-
export type FooterNavItemProps = {
|
|
7
|
-
href: any;
|
|
8
|
-
icon: any;
|
|
9
|
-
active?: boolean | undefined;
|
|
10
|
-
children?: string | undefined;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const FooterNavItem: FC<FooterNavItemProps> = memo(function FooterNavItem({
|
|
14
|
-
href,
|
|
15
|
-
icon,
|
|
16
|
-
active = false,
|
|
17
|
-
children = '',
|
|
18
|
-
}) {
|
|
19
|
-
// const pathname = usePathname();
|
|
20
|
-
|
|
21
|
-
const isFilepath = icon.includes('.');
|
|
22
|
-
let iconElement;
|
|
23
|
-
|
|
24
|
-
if (isFilepath) {
|
|
25
|
-
iconElement = <img src={icon} alt="icon" className="me-lg-2" />;
|
|
26
|
-
} else {
|
|
27
|
-
iconElement = <span className={`lead me-lg-2 ${icon}`} />;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// const active = isActivePath(href, pathname);
|
|
31
|
-
|
|
32
|
-
const link = (
|
|
33
|
-
<Nav.Link
|
|
34
|
-
// as={Link}
|
|
35
|
-
href={href}
|
|
36
|
-
// active={active} // has no effect when not pills or tabs
|
|
37
|
-
className={`px-0 px-lg-3 d-flex align-items-center flex-column flex-lg-row ${active ? 'text-primary' : ''}`}
|
|
38
|
-
>
|
|
39
|
-
{iconElement}
|
|
40
|
-
{children}
|
|
41
|
-
</Nav.Link>
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return <Nav.Item style={{ flex: 1 }}>{link}</Nav.Item>;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
export type FooterProps = {
|
|
48
|
-
children: any;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const Footer: FC<FooterProps> = memo(function Footer({ children }) {
|
|
52
|
-
const { isDesktop } = useBreakpoint();
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
// border-bottom
|
|
56
|
-
<div className={isDesktop ? '' : 'border-top'}>
|
|
57
|
-
<Navbar className={isDesktop ? '' : 'py-0'}>
|
|
58
|
-
<AdaptiveContainer>
|
|
59
|
-
{isDesktop && <Navbar.Brand href="/">Le Brand</Navbar.Brand>}
|
|
60
|
-
<Nav className={isDesktop ? 'me-auto' : 'justify-content-center flex-nowrap w-100'}>{children}</Nav>
|
|
61
|
-
</AdaptiveContainer>
|
|
62
|
-
</Navbar>
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
|
|
3
|
-
import { GlobalLoading } from './globalLoading';
|
|
4
|
-
|
|
5
|
-
const meta: Meta<typeof GlobalLoading> = {
|
|
6
|
-
title: 'Bootstrap / GlobalLoading',
|
|
7
|
-
component: GlobalLoading,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: 'centered',
|
|
10
|
-
},
|
|
11
|
-
tags: ['autodocs'],
|
|
12
|
-
argTypes: {
|
|
13
|
-
loading: { control: 'check' },
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default meta;
|
|
18
|
-
|
|
19
|
-
type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
export const Default: Story = {
|
|
22
|
-
args: {
|
|
23
|
-
loading: true,
|
|
24
|
-
},
|
|
25
|
-
};
|
package/src/globalLoading.tsx
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React, { FC, memo } from 'react';
|
|
2
|
-
// import { useLoading, useLoadingTimeout } from '../redux/loadingSlice';
|
|
3
|
-
import { Loading } from './loading';
|
|
4
|
-
|
|
5
|
-
export type GlobalLoadingProps = { loading: boolean };
|
|
6
|
-
|
|
7
|
-
export const GlobalLoading: FC<GlobalLoadingProps> = memo(function GlobalLoading({ loading }) {
|
|
8
|
-
// const { loading } = useLoading();
|
|
9
|
-
|
|
10
|
-
// useLoadingTimeout(15000); // escape latch if something is stuck
|
|
11
|
-
|
|
12
|
-
if (!loading) return null;
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<div className="bg-white position-absolute top-0 start-0 w-100 h-100 z-3 d-flex align-items-center justify-content-center">
|
|
16
|
-
<Loading />
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from './adaptiveContainer';
|
|
2
|
-
export * from './controls';
|
|
3
|
-
export * from './error';
|
|
4
|
-
export * from './field';
|
|
5
|
-
export * from './footer';
|
|
6
|
-
export * from './globalLoading';
|
|
7
|
-
export * from './loading';
|
|
8
|
-
export * from './responsiveHelper';
|
|
9
|
-
export * from './screen';
|
|
10
|
-
export * from './toaster';
|
|
11
|
-
export * from './useModal';
|
|
12
|
-
export * from './useWrappedForm';
|
package/src/loading.stories.tsx
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
|
|
3
|
-
import { Loading } from './loading';
|
|
4
|
-
|
|
5
|
-
const meta: Meta<typeof Loading> = {
|
|
6
|
-
title: 'Bootstrap / Loading',
|
|
7
|
-
component: Loading,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: 'centered',
|
|
10
|
-
},
|
|
11
|
-
tags: ['autodocs'],
|
|
12
|
-
argTypes: {
|
|
13
|
-
children: { control: 'text' },
|
|
14
|
-
show: { control: 'check' },
|
|
15
|
-
size: { control: 'select', options: ['sm', 'md'] },
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default meta;
|
|
20
|
-
|
|
21
|
-
type Story = StoryObj<typeof meta>;
|
|
22
|
-
|
|
23
|
-
export const Default: Story = {};
|
|
24
|
-
|
|
25
|
-
export const Children: Story = {
|
|
26
|
-
args: {
|
|
27
|
-
children: 'Custom Loading...',
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const Size: Story = {
|
|
32
|
-
args: {
|
|
33
|
-
size: 'sm',
|
|
34
|
-
},
|
|
35
|
-
};
|
package/src/loading.tsx
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Spinner, SpinnerProps, Stack } from 'react-bootstrap';
|
|
2
|
-
import React, { FC, memo } from 'react';
|
|
3
|
-
|
|
4
|
-
export type LoadingProps = {
|
|
5
|
-
children?: any;
|
|
6
|
-
show?: boolean;
|
|
7
|
-
className?: string;
|
|
8
|
-
size?: SpinnerProps['size'];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const Loading: FC<LoadingProps> = memo(function Loading({
|
|
12
|
-
children = 'Loading...' as any,
|
|
13
|
-
show = true,
|
|
14
|
-
className = '',
|
|
15
|
-
size,
|
|
16
|
-
}) {
|
|
17
|
-
if (!show) return null;
|
|
18
|
-
return (
|
|
19
|
-
<Stack direction="horizontal" gap={3} className={`align-self-auto ${className}`}>
|
|
20
|
-
<Spinner animation="border" role="status" size={size as any} />
|
|
21
|
-
<span>{children}</span>
|
|
22
|
-
</Stack>
|
|
23
|
-
);
|
|
24
|
-
});
|
package/src/main.scss
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
$primary: darken(#fd7e14, 6%) !default; // in order to accomodate MCR=3
|
|
2
|
-
$secondary: #0d6efd !default;
|
|
3
|
-
$danger: #dc3545 !default;
|
|
4
|
-
$warning: #fd7e14 !default;
|
|
5
|
-
$success: #198754 !default;
|
|
6
|
-
|
|
7
|
-
$theme-colors: (
|
|
8
|
-
'primary': $primary,
|
|
9
|
-
'secondary': $secondary,
|
|
10
|
-
'success': $success,
|
|
11
|
-
// "info": $info,
|
|
12
|
-
'warning': $warning,
|
|
13
|
-
'danger': $danger,
|
|
14
|
-
// non-bootstrap colors
|
|
15
|
-
'light': #dddddd,
|
|
16
|
-
'dark': #2c2414,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
$min-contrast-ratio: 3 !default; // 4.5 produces black on orange @see https://stackoverflow.com/a/68303393/5125659
|
|
20
|
-
|
|
21
|
-
@import 'bootstrap/scss/functions.scss';
|
|
22
|
-
@import 'bootstrap/scss/variables.scss';
|
|
23
|
-
@import 'bootstrap/scss/mixins.scss';
|
|
24
|
-
@import 'bootstrap/scss/bootstrap.scss';
|
|
25
|
-
|
|
26
|
-
// Nav
|
|
27
|
-
|
|
28
|
-
.btn-nav {
|
|
29
|
-
@extend .btn-outline-primary; // just vars to control styling
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.main-nav .btn-nav {
|
|
33
|
-
border-width: 0;
|
|
34
|
-
|
|
35
|
-
@include media-breakpoint-down(md) {
|
|
36
|
-
--bs-btn-active-color: var(--bs-primary);
|
|
37
|
-
--bs-btn-hover-color: var(--bs-primary);
|
|
38
|
-
background: none !important;
|
|
39
|
-
padding: 0;
|
|
40
|
-
text-decoration: none;
|
|
41
|
-
font-weight: 500;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
&.disabled {
|
|
45
|
-
color: var(--bs-gray-600);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Dropdowns
|
|
50
|
-
|
|
51
|
-
.dropdown-toggle-no-arrow::after,
|
|
52
|
-
.dropdown-toggle-no-arrow > .dropdown-toggle::after {
|
|
53
|
-
display: none !important;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.dropdown > button {
|
|
57
|
-
display: block; // fixes small padding on dropdowns
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Tables
|
|
61
|
-
|
|
62
|
-
.table {
|
|
63
|
-
//fixes table borders & margins
|
|
64
|
-
margin-bottom: 0;
|
|
65
|
-
|
|
66
|
-
& > :not(caption) > * > * {
|
|
67
|
-
background: none;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
& > :not(caption) > tr:last-of-type > * {
|
|
71
|
-
border-bottom: none;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Badges
|
|
76
|
-
|
|
77
|
-
.badge {
|
|
78
|
-
--bs-badge-font-weight: normal;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Icons
|
|
82
|
-
|
|
83
|
-
.icon-thick {
|
|
84
|
-
webkit-text-stroke: 1px;
|
|
85
|
-
text-stroke: 1px;
|
|
86
|
-
}
|