@tiny-server/design 0.0.0-pre202605241751
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/components/badge-group/BadgeGroup.d.ts +6 -0
- package/dist/components/badge-group/BadgeGroup.stories.d.ts +6 -0
- package/dist/components/badge-group/index.d.ts +1 -0
- package/dist/components/checkbox-card/CheckboxCard.d.ts +7 -0
- package/dist/components/checkbox-card/CheckboxCard.stories.d.ts +6 -0
- package/dist/components/checkbox-card/index.d.ts +1 -0
- package/dist/components/form/Form.d.ts +15 -0
- package/dist/components/form/Form.stories.d.ts +6 -0
- package/dist/components/form/FormAlert.d.ts +6 -0
- package/dist/components/form/FormFooter.d.ts +4 -0
- package/dist/components/form/FormSection.d.ts +4 -0
- package/dist/components/form/index.d.ts +1 -0
- package/dist/components/image-cropper/ImageCropper.d.ts +11 -0
- package/dist/components/image-cropper/cropImage.d.ts +11 -0
- package/dist/components/image-cropper/index.d.ts +1 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/labeled-info/LabeledInfo.d.ts +19 -0
- package/dist/components/labeled-info/LabeledInfo.stories.d.ts +6 -0
- package/dist/components/labeled-info/index.d.ts +1 -0
- package/dist/components/section-card/Header.d.ts +18 -0
- package/dist/components/section-card/Section.d.ts +14 -0
- package/dist/components/section-card/SectionCard.d.ts +21 -0
- package/dist/components/section-card/SectionCard.stories.d.ts +7 -0
- package/dist/components/section-card/index.d.ts +3 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +312 -0
- package/package.json +52 -0
- package/src/components/badge-group/BadgeGroup.stories.tsx +24 -0
- package/src/components/badge-group/BadgeGroup.tsx +24 -0
- package/src/components/badge-group/index.ts +1 -0
- package/src/components/checkbox-card/CheckboxCard.stories.tsx +33 -0
- package/src/components/checkbox-card/CheckboxCard.tsx +22 -0
- package/src/components/checkbox-card/index.ts +1 -0
- package/src/components/form/Form.stories.tsx +30 -0
- package/src/components/form/Form.tsx +22 -0
- package/src/components/form/FormAlert.tsx +25 -0
- package/src/components/form/FormFooter.tsx +7 -0
- package/src/components/form/FormSection.tsx +7 -0
- package/src/components/form/index.ts +1 -0
- package/src/components/image-cropper/ImageCropper.tsx +73 -0
- package/src/components/image-cropper/cropImage.ts +87 -0
- package/src/components/image-cropper/index.ts +1 -0
- package/src/components/index.ts +6 -0
- package/src/components/labeled-info/LabeledInfo.stories.tsx +27 -0
- package/src/components/labeled-info/LabeledInfo.tsx +54 -0
- package/src/components/labeled-info/index.ts +1 -0
- package/src/components/section-card/Header.tsx +81 -0
- package/src/components/section-card/Section.tsx +48 -0
- package/src/components/section-card/SectionCard.module.css +40 -0
- package/src/components/section-card/SectionCard.stories.tsx +61 -0
- package/src/components/section-card/SectionCard.tsx +52 -0
- package/src/components/section-card/index.ts +4 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
2
|
+
export interface BadgeGroupProps extends PropsWithChildren {
|
|
3
|
+
max?: number;
|
|
4
|
+
renderHidden?(hidden: number): ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare function BadgeGroup({ children, max, renderHidden }: BadgeGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BadgeGroup';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CheckboxCardProps as MantineCheckboxCardProps } from '@mantine/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export interface CheckboxCardProps extends MantineCheckboxCardProps {
|
|
4
|
+
label?: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare function CheckboxCard({ label, description, children, disabled, ...rest }: CheckboxCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CheckboxCard';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ContainerProps, StackProps, ElementProps } from '@mantine/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { FormSection } from './FormSection';
|
|
4
|
+
import { FormFooter } from './FormFooter';
|
|
5
|
+
import { FormAlert } from './FormAlert';
|
|
6
|
+
export interface FormProps extends ElementProps<'form'>, Omit<ContainerProps, keyof ElementProps<'div'>> {
|
|
7
|
+
gap?: StackProps['gap'];
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare function Form({ ref, size, p, gap, children, ...rest }: FormProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare namespace Form {
|
|
12
|
+
var Alert: typeof FormAlert;
|
|
13
|
+
var Section: typeof FormSection;
|
|
14
|
+
var Footer: typeof FormFooter;
|
|
15
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AlertProps } from '@mantine/core';
|
|
2
|
+
export type FormAlertKind = 'success' | 'error';
|
|
3
|
+
export interface FormAlertProps extends Omit<AlertProps, 'color' | 'icon'> {
|
|
4
|
+
kind: FormAlertKind;
|
|
5
|
+
}
|
|
6
|
+
export declare function FormAlert({ kind, variant, ...rest }: FormAlertProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Form';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { CropperProps } from 'react-easy-crop';
|
|
3
|
+
export interface ImageCropperProps extends Partial<Omit<CropperProps, 'crop' | 'zoom' | 'rotation' | 'onCropChange' | 'onZoomChange' | 'onRotationChange' | 'onCropComplete'>> {
|
|
4
|
+
src?: string;
|
|
5
|
+
initialCrop?: CropperProps['crop'];
|
|
6
|
+
initialZoom?: CropperProps['zoom'];
|
|
7
|
+
initialRotation?: CropperProps['rotation'];
|
|
8
|
+
fallback?: ReactNode;
|
|
9
|
+
onCropped?(croppedImageBlob: File): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function ImageCropper({ src, initialCrop, initialZoom, initialRotation, fallback, onCropped, ...rest }: ImageCropperProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Area } from 'react-easy-crop';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an image blob, representing a cropped version of the source image.
|
|
4
|
+
*
|
|
5
|
+
* Source:
|
|
6
|
+
* https://valentinh.github.io/react-easy-crop/docs/examples/output
|
|
7
|
+
*/
|
|
8
|
+
export declare function cropImage(imageSrc: string, pixelCrop: Area, rotation?: number, flip?: {
|
|
9
|
+
horizontal: boolean;
|
|
10
|
+
vertical: boolean;
|
|
11
|
+
}): Promise<File>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ImageCropper';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* {@link LabeledInfo} variants.
|
|
4
|
+
*
|
|
5
|
+
* - `default`: Renders an icon, label as header and children below.
|
|
6
|
+
* - `inline`: Renders an icon and the children in a single row.
|
|
7
|
+
*/
|
|
8
|
+
export type LabeledInfoVariant = 'default' | 'inline';
|
|
9
|
+
export interface LabeledInfoProps {
|
|
10
|
+
variant?: LabeledInfoVariant;
|
|
11
|
+
icon?: ReactNode;
|
|
12
|
+
label?: ReactNode;
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
fallback?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Enriches the children with an optional label and icon.
|
|
18
|
+
*/
|
|
19
|
+
export declare function LabeledInfo({ icon, label, children, variant, fallback }: LabeledInfoProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './LabeledInfo';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BoxProps, ElementProps, Factory, StylesApiProps, TextProps, TitleProps } from '@mantine/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export interface SectionCardHeaderProps extends BoxProps, StylesApiProps<SectionCardHeaderFactory>, ElementProps<'header', 'title'> {
|
|
4
|
+
illustration?: ReactNode;
|
|
5
|
+
title?: ReactNode;
|
|
6
|
+
titleProps?: Omit<TitleProps, 'children'>;
|
|
7
|
+
subTitle?: ReactNode;
|
|
8
|
+
subTitleProps?: Omit<TextProps, 'children'>;
|
|
9
|
+
actions?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export type SectionCardHeaderFactory = Factory<{
|
|
12
|
+
props: SectionCardHeaderProps;
|
|
13
|
+
ref: HTMLDivElement;
|
|
14
|
+
}>;
|
|
15
|
+
export declare const SectionCardHeader: import('@mantine/core').MantineComponent<{
|
|
16
|
+
props: SectionCardHeaderProps;
|
|
17
|
+
ref: HTMLDivElement;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BoxProps, ElementProps, Factory, StylesApiProps, TitleProps } from '@mantine/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export interface SectionCardSectionProps extends BoxProps, StylesApiProps<SectionCardSectionFactory>, ElementProps<'section', 'title'> {
|
|
4
|
+
title?: ReactNode;
|
|
5
|
+
titleProps?: Omit<TitleProps, 'children'>;
|
|
6
|
+
}
|
|
7
|
+
export type SectionCardSectionFactory = Factory<{
|
|
8
|
+
props: SectionCardSectionProps;
|
|
9
|
+
ref: HTMLDivElement;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const SectionCardSection: import('@mantine/core').MantineComponent<{
|
|
12
|
+
props: SectionCardSectionProps;
|
|
13
|
+
ref: HTMLDivElement;
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BoxProps, ElementProps, Factory, PaperBaseProps, StylesApiProps } from '@mantine/core';
|
|
2
|
+
import { SectionCardSection } from './Section';
|
|
3
|
+
import { SectionCardHeader } from './Header';
|
|
4
|
+
export interface SectionCardProps extends BoxProps, PaperBaseProps, StylesApiProps<SectionCardFactory>, ElementProps<'section'> {
|
|
5
|
+
}
|
|
6
|
+
export type SectionCardFactory = Factory<{
|
|
7
|
+
props: SectionCardProps;
|
|
8
|
+
ref: HTMLDivElement;
|
|
9
|
+
staticComponents: {
|
|
10
|
+
Header: typeof SectionCardHeader;
|
|
11
|
+
Section: typeof SectionCardSection;
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
export declare const SectionCard: import('@mantine/core').MantineComponent<{
|
|
15
|
+
props: SectionCardProps;
|
|
16
|
+
ref: HTMLDivElement;
|
|
17
|
+
staticComponents: {
|
|
18
|
+
Header: typeof SectionCardHeader;
|
|
19
|
+
Section: typeof SectionCardSection;
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { SectionCard } from './SectionCard';
|
|
3
|
+
declare const meta: Meta<typeof SectionCard>;
|
|
4
|
+
type Story = StoryObj<typeof meta>;
|
|
5
|
+
export declare const Default: Story;
|
|
6
|
+
export declare const TitleOnly: Story;
|
|
7
|
+
export default meta;
|
package/dist/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._section-card_4lpwj_1{color:var(--mantine-color-text)}._section-card_4lpwj_1 ._section-card__header_4lpwj_4{display:flex;flex-direction:column;gap:var(--mantine-spacing-md)}._section-card_4lpwj_1 ._section-card__header_4lpwj_4 ._section-card__header__header_4lpwj_9{display:flex;flex-direction:row;gap:var(--mantine-spacing-md);align-items:center}._section-card_4lpwj_1 ._section-card__header_4lpwj_4 ._section-card__header__header_4lpwj_9 ._section-card__header__header__illustration_4lpwj_15{flex:0 0 auto}._section-card_4lpwj_1 ._section-card__header_4lpwj_4 ._section-card__header__header_4lpwj_9 ._section-card__header__header__title_4lpwj_19{flex:1 1 auto;min-width:0}._section-card_4lpwj_1 ._section-card__header_4lpwj_4 ._section-card__header__header_4lpwj_9 ._section-card__header__header__actions_4lpwj_24{flex:0 0 auto}._section-card_4lpwj_1 ._section-card__header_4lpwj_4+._section-card__section_4lpwj_30,._section-card_4lpwj_1 ._section-card__section_4lpwj_30+._section-card__section_4lpwj_30{padding-top:0!important}._ellipsis_4lpwj_36{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { jsxs as l, jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import { Group as w, Badge as U, Checkbox as j, Input as F, Stack as v, Alert as V, Container as q, Box as y, LoadingOverlay as K, Tooltip as X, Text as f, Center as L, factory as I, useProps as E, Title as z, Paper as J } from "@mantine/core";
|
|
3
|
+
import { Children as Q, useContext as Y, createContext as ee, forwardRef as T, createElement as A, useState as x, useRef as k, useCallback as te, useEffect as R } from "react";
|
|
4
|
+
import re from "react-easy-crop";
|
|
5
|
+
function ne(t) {
|
|
6
|
+
return /* @__PURE__ */ l(U, { variant: "default", children: [
|
|
7
|
+
"+",
|
|
8
|
+
t
|
|
9
|
+
] });
|
|
10
|
+
}
|
|
11
|
+
function Pe({ children: t, max: e = Number.MAX_SAFE_INTEGER, renderHidden: n = ne }) {
|
|
12
|
+
const r = Q.toArray(t), o = r.slice(0, e), c = r.length - e;
|
|
13
|
+
return /* @__PURE__ */ l(w, { gap: "xs", children: [
|
|
14
|
+
o,
|
|
15
|
+
c > 0 && n(c)
|
|
16
|
+
] });
|
|
17
|
+
}
|
|
18
|
+
function je({ label: t, description: e, children: n, disabled: r, ...o }) {
|
|
19
|
+
return /* @__PURE__ */ a(j.Card, { radius: "md", p: "md", disabled: r, ...o, children: /* @__PURE__ */ l(w, { h: "100%", wrap: "nowrap", align: "flex-start", children: [
|
|
20
|
+
/* @__PURE__ */ a(j.Indicator, { mt: "calc(var(--mantine-spacing-xs) / 2)", disabled: r }),
|
|
21
|
+
/* @__PURE__ */ l("div", { children: [
|
|
22
|
+
t && /* @__PURE__ */ a(F.Label, { htmlFor: o.id, children: t }),
|
|
23
|
+
e && /* @__PURE__ */ a(F.Description, { children: e }),
|
|
24
|
+
n
|
|
25
|
+
] })
|
|
26
|
+
] }) });
|
|
27
|
+
}
|
|
28
|
+
function oe({ gap: t = "md", ...e }) {
|
|
29
|
+
return /* @__PURE__ */ a(v, { gap: t, ...e });
|
|
30
|
+
}
|
|
31
|
+
function ce({ gap: t = "md", wrap: e = "wrap", ...n }) {
|
|
32
|
+
return /* @__PURE__ */ a(w, { gap: t, wrap: e, ...n });
|
|
33
|
+
}
|
|
34
|
+
const W = (...t) => t.filter((e, n, r) => !!e && e.trim() !== "" && r.indexOf(e) === n).join(" ").trim();
|
|
35
|
+
const ae = (t) => t.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
36
|
+
const ie = (t) => t.replace(
|
|
37
|
+
/^([A-Z])|[\s-_]+(\w)/g,
|
|
38
|
+
(e, n, r) => r ? r.toUpperCase() : n.toLowerCase()
|
|
39
|
+
);
|
|
40
|
+
const B = (t) => {
|
|
41
|
+
const e = ie(t);
|
|
42
|
+
return e.charAt(0).toUpperCase() + e.slice(1);
|
|
43
|
+
};
|
|
44
|
+
var $ = {
|
|
45
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
46
|
+
width: 24,
|
|
47
|
+
height: 24,
|
|
48
|
+
viewBox: "0 0 24 24",
|
|
49
|
+
fill: "none",
|
|
50
|
+
stroke: "currentColor",
|
|
51
|
+
strokeWidth: 2,
|
|
52
|
+
strokeLinecap: "round",
|
|
53
|
+
strokeLinejoin: "round"
|
|
54
|
+
};
|
|
55
|
+
const se = (t) => {
|
|
56
|
+
for (const e in t)
|
|
57
|
+
if (e.startsWith("aria-") || e === "role" || e === "title")
|
|
58
|
+
return !0;
|
|
59
|
+
return !1;
|
|
60
|
+
}, de = ee({}), le = () => Y(de), he = T(
|
|
61
|
+
({ color: t, size: e, strokeWidth: n, absoluteStrokeWidth: r, className: o = "", children: c, iconNode: i, ...s }, d) => {
|
|
62
|
+
const {
|
|
63
|
+
size: _ = 24,
|
|
64
|
+
strokeWidth: h = 2,
|
|
65
|
+
absoluteStrokeWidth: p = !1,
|
|
66
|
+
color: C = "currentColor",
|
|
67
|
+
className: g = ""
|
|
68
|
+
} = le() ?? {}, m = r ?? p ? Number(n ?? h) * 24 / Number(e ?? _) : n ?? h;
|
|
69
|
+
return A(
|
|
70
|
+
"svg",
|
|
71
|
+
{
|
|
72
|
+
ref: d,
|
|
73
|
+
...$,
|
|
74
|
+
width: e ?? _ ?? $.width,
|
|
75
|
+
height: e ?? _ ?? $.height,
|
|
76
|
+
stroke: t ?? C,
|
|
77
|
+
strokeWidth: m,
|
|
78
|
+
className: W("lucide", g, o),
|
|
79
|
+
...!c && !se(s) && { "aria-hidden": "true" },
|
|
80
|
+
...s
|
|
81
|
+
},
|
|
82
|
+
[
|
|
83
|
+
...i.map(([S, N]) => A(S, N)),
|
|
84
|
+
...Array.isArray(c) ? c : [c]
|
|
85
|
+
]
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
const H = (t, e) => {
|
|
90
|
+
const n = T(
|
|
91
|
+
({ className: r, ...o }, c) => A(he, {
|
|
92
|
+
ref: c,
|
|
93
|
+
iconNode: e,
|
|
94
|
+
className: W(
|
|
95
|
+
`lucide-${ae(B(t))}`,
|
|
96
|
+
`lucide-${t}`,
|
|
97
|
+
r
|
|
98
|
+
),
|
|
99
|
+
...o
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
return n.displayName = B(t), n;
|
|
103
|
+
};
|
|
104
|
+
const ue = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]], _e = H("check", ue);
|
|
105
|
+
const me = [
|
|
106
|
+
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
107
|
+
["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
|
|
108
|
+
["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
|
|
109
|
+
], pe = H("circle-alert", me), ge = {
|
|
110
|
+
success: "green",
|
|
111
|
+
error: "red"
|
|
112
|
+
}, fe = {
|
|
113
|
+
success: /* @__PURE__ */ a(_e, { size: 16 }),
|
|
114
|
+
error: /* @__PURE__ */ a(pe, { size: 16 })
|
|
115
|
+
};
|
|
116
|
+
function we({ kind: t, variant: e = "outline", ...n }) {
|
|
117
|
+
const r = ge[t], o = fe[t];
|
|
118
|
+
return /* @__PURE__ */ a(V, { variant: e, color: r, icon: o, ...n });
|
|
119
|
+
}
|
|
120
|
+
function M({ ref: t, size: e = "xs", p: n = 0, gap: r = "lg", children: o, ...c }) {
|
|
121
|
+
return /* @__PURE__ */ a(q, { ...c, component: "form", ref: t, mx: 0, size: e, p: n, children: /* @__PURE__ */ a(v, { gap: r, children: o }) });
|
|
122
|
+
}
|
|
123
|
+
M.Alert = we;
|
|
124
|
+
M.Section = oe;
|
|
125
|
+
M.Footer = ce;
|
|
126
|
+
async function Ce(t, e, n = 0, r = { horizontal: !1, vertical: !1 }) {
|
|
127
|
+
const o = await ve(t), c = document.createElement("canvas"), i = c.getContext("2d");
|
|
128
|
+
if (!i)
|
|
129
|
+
throw new Error("Failed to create canvas context.");
|
|
130
|
+
const s = Z(n), { width: d, height: _ } = xe(o.width, o.height, n);
|
|
131
|
+
c.width = d, c.height = _, i.translate(d / 2, _ / 2), i.rotate(s), i.scale(r.horizontal ? -1 : 1, r.vertical ? -1 : 1), i.translate(-o.width / 2, -o.height / 2), i.drawImage(o, 0, 0);
|
|
132
|
+
const h = document.createElement("canvas"), p = h.getContext("2d");
|
|
133
|
+
if (!p)
|
|
134
|
+
throw new Error("Failed to create canvas context.");
|
|
135
|
+
return h.width = e.width, h.height = e.height, p.drawImage(
|
|
136
|
+
c,
|
|
137
|
+
e.x,
|
|
138
|
+
e.y,
|
|
139
|
+
e.width,
|
|
140
|
+
e.height,
|
|
141
|
+
0,
|
|
142
|
+
0,
|
|
143
|
+
e.width,
|
|
144
|
+
e.height
|
|
145
|
+
), new Promise(
|
|
146
|
+
(C, g) => h.toBlob(
|
|
147
|
+
(m) => m ? C(new File([m], "img.png", { type: m.type })) : g(new Error("Failed to crop image.")),
|
|
148
|
+
"image/png"
|
|
149
|
+
)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
function Z(t) {
|
|
153
|
+
return t * Math.PI / 180;
|
|
154
|
+
}
|
|
155
|
+
function xe(t, e, n) {
|
|
156
|
+
const r = Z(n);
|
|
157
|
+
return {
|
|
158
|
+
width: Math.abs(Math.cos(r) * t) + Math.abs(Math.sin(r) * e),
|
|
159
|
+
height: Math.abs(Math.sin(r) * t) + Math.abs(Math.cos(r) * e)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function ve(t) {
|
|
163
|
+
return new Promise((e, n) => {
|
|
164
|
+
const r = new Image();
|
|
165
|
+
r.addEventListener("load", () => e(r)), r.addEventListener("error", n), r.setAttribute("crossOrigin", "anonymous"), r.src = t;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function ye(t, e, n = { leading: !1 }) {
|
|
169
|
+
const [r, o] = x(t), c = k(!1), i = k(null), s = k(!1), d = te(() => window.clearTimeout(i.current), []);
|
|
170
|
+
return R(() => {
|
|
171
|
+
c.current && (!s.current && n.leading ? (s.current = !0, o(t)) : (d(), i.current = window.setTimeout(() => {
|
|
172
|
+
s.current = !1, o(t);
|
|
173
|
+
}, e)));
|
|
174
|
+
}, [
|
|
175
|
+
t,
|
|
176
|
+
n.leading,
|
|
177
|
+
e
|
|
178
|
+
]), R(() => (c.current = !0, d), []), [r, d];
|
|
179
|
+
}
|
|
180
|
+
function Fe({
|
|
181
|
+
src: t,
|
|
182
|
+
initialCrop: e = { x: 0, y: 0 },
|
|
183
|
+
initialZoom: n = 1,
|
|
184
|
+
initialRotation: r = 0,
|
|
185
|
+
fallback: o,
|
|
186
|
+
onCropped: c,
|
|
187
|
+
...i
|
|
188
|
+
}) {
|
|
189
|
+
const [s, d] = x(e), [_, h] = x(n), [p, C] = x(r), [g, m] = x(!1), [S] = ye(g, 250, { leading: !1 }), N = async ($e, D) => {
|
|
190
|
+
try {
|
|
191
|
+
if (g)
|
|
192
|
+
return;
|
|
193
|
+
m(!0);
|
|
194
|
+
const b = await Ce(t, D);
|
|
195
|
+
c?.(b);
|
|
196
|
+
} catch (b) {
|
|
197
|
+
console.error("Image cropping failed.", b);
|
|
198
|
+
} finally {
|
|
199
|
+
m(!1);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
return t ? /* @__PURE__ */ l(y, { pos: "relative", w: "100%", h: "100%", children: [
|
|
203
|
+
/* @__PURE__ */ a(K, { visible: S }),
|
|
204
|
+
/* @__PURE__ */ a(
|
|
205
|
+
re,
|
|
206
|
+
{
|
|
207
|
+
...i,
|
|
208
|
+
image: t,
|
|
209
|
+
crop: s,
|
|
210
|
+
zoom: _,
|
|
211
|
+
rotation: p,
|
|
212
|
+
onCropChange: d,
|
|
213
|
+
onZoomChange: h,
|
|
214
|
+
onRotationChange: C,
|
|
215
|
+
onCropComplete: N
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
] }) : o;
|
|
219
|
+
}
|
|
220
|
+
function Le({ icon: t, label: e, children: n, variant: r = "default", fallback: o = "–" }) {
|
|
221
|
+
const c = /* @__PURE__ */ a(f, { component: "div", children: n || o });
|
|
222
|
+
if (r === "inline") {
|
|
223
|
+
const i = /* @__PURE__ */ a(f, { component: "div", c: "dimmed", children: /* @__PURE__ */ a(L, { children: t }) });
|
|
224
|
+
return /* @__PURE__ */ l(w, { gap: "xs", align: "center", wrap: "nowrap", children: [
|
|
225
|
+
e ? /* @__PURE__ */ a(X, { label: e, children: i }) : i,
|
|
226
|
+
c
|
|
227
|
+
] });
|
|
228
|
+
}
|
|
229
|
+
return /* @__PURE__ */ l(v, { gap: 0, children: [
|
|
230
|
+
/* @__PURE__ */ a(f, { component: "div", c: "dimmed", fz: "sm", children: /* @__PURE__ */ l(w, { gap: "xs", align: "center", wrap: "nowrap", children: [
|
|
231
|
+
t && /* @__PURE__ */ a(L, { children: t }),
|
|
232
|
+
/* @__PURE__ */ a(f, { component: "div", truncate: !0, inherit: !0, children: e })
|
|
233
|
+
] }) }),
|
|
234
|
+
c
|
|
235
|
+
] });
|
|
236
|
+
}
|
|
237
|
+
const Se = "_ellipsis_4lpwj_36", u = {
|
|
238
|
+
"section-card": "_section-card_4lpwj_1",
|
|
239
|
+
"section-card__header": "_section-card__header_4lpwj_4",
|
|
240
|
+
"section-card__header__header": "_section-card__header__header_4lpwj_9",
|
|
241
|
+
"section-card__header__header__illustration": "_section-card__header__header__illustration_4lpwj_15",
|
|
242
|
+
"section-card__header__header__title": "_section-card__header__header__title_4lpwj_19",
|
|
243
|
+
"section-card__header__header__actions": "_section-card__header__header__actions_4lpwj_24",
|
|
244
|
+
"section-card__section": "_section-card__section_4lpwj_30",
|
|
245
|
+
ellipsis: Se
|
|
246
|
+
}, Ne = {
|
|
247
|
+
p: "md"
|
|
248
|
+
}, G = I((t) => {
|
|
249
|
+
const { title: e, titleProps: n, className: r, children: o, ...c } = E(
|
|
250
|
+
"SectionCard.Section",
|
|
251
|
+
Ne,
|
|
252
|
+
t
|
|
253
|
+
);
|
|
254
|
+
return /* @__PURE__ */ l(y, { component: "section", className: `${u["section-card__section"]} ${r ?? ""}`, ...c, children: [
|
|
255
|
+
e && /* @__PURE__ */ a(z, { order: 3, ...n, className: `${u.ellipsis} ${n?.className ?? ""}`, children: e }),
|
|
256
|
+
o && /* @__PURE__ */ a("div", { children: o })
|
|
257
|
+
] });
|
|
258
|
+
});
|
|
259
|
+
G.displayName = "SectionCard.Section";
|
|
260
|
+
const be = {
|
|
261
|
+
p: "md"
|
|
262
|
+
}, O = I((t) => {
|
|
263
|
+
const { illustration: e, title: n, titleProps: r, subTitle: o, subTitleProps: c, actions: i, children: s, className: d, ..._ } = E(
|
|
264
|
+
"SectionCard.Header",
|
|
265
|
+
be,
|
|
266
|
+
t
|
|
267
|
+
), h = /* @__PURE__ */ l(v, { gap: "xs", className: `${u["section-card__header__header__title"]} ${u.ellipsis}`, children: [
|
|
268
|
+
n && /* @__PURE__ */ a(z, { order: 2, ...r, className: `${u.ellipsis} ${r?.className ?? ""}`, children: n }),
|
|
269
|
+
o && /* @__PURE__ */ a(
|
|
270
|
+
f,
|
|
271
|
+
{
|
|
272
|
+
component: "div",
|
|
273
|
+
c: "dimmed",
|
|
274
|
+
...c,
|
|
275
|
+
className: `${u.ellipsis} ${c?.className ?? ""}`,
|
|
276
|
+
children: o
|
|
277
|
+
}
|
|
278
|
+
)
|
|
279
|
+
] });
|
|
280
|
+
return /* @__PURE__ */ l(y, { component: "header", className: `${u["section-card__header"]} ${d ?? ""}`, ..._, children: [
|
|
281
|
+
/* @__PURE__ */ l("div", { className: u["section-card__header__header"], children: [
|
|
282
|
+
e && /* @__PURE__ */ a("div", { className: u["section-card__header__header__illustration"], children: e }),
|
|
283
|
+
h,
|
|
284
|
+
i && /* @__PURE__ */ a(w, { gap: "xs", className: u["section-card__header__header__actions"], children: i })
|
|
285
|
+
] }),
|
|
286
|
+
s && /* @__PURE__ */ a("div", { children: s })
|
|
287
|
+
] });
|
|
288
|
+
});
|
|
289
|
+
O.displayName = "SectionCard.Header";
|
|
290
|
+
const ke = {
|
|
291
|
+
radius: "lg",
|
|
292
|
+
shadow: "sm",
|
|
293
|
+
withBorder: !1
|
|
294
|
+
}, P = I((t) => {
|
|
295
|
+
const { radius: e, shadow: n, withBorder: r, children: o, className: c, ...i } = E(
|
|
296
|
+
"SectionCard",
|
|
297
|
+
ke,
|
|
298
|
+
t
|
|
299
|
+
);
|
|
300
|
+
return /* @__PURE__ */ a(y, { component: "section", className: `${u["section-card"]} ${c ?? ""}`, ...i, children: /* @__PURE__ */ a(J, { radius: e, shadow: n, withBorder: r, children: /* @__PURE__ */ a(f, { component: "div", children: o }) }) });
|
|
301
|
+
});
|
|
302
|
+
P.displayName = "SectionCard";
|
|
303
|
+
P.Header = O;
|
|
304
|
+
P.Section = G;
|
|
305
|
+
export {
|
|
306
|
+
Pe as BadgeGroup,
|
|
307
|
+
je as CheckboxCard,
|
|
308
|
+
M as Form,
|
|
309
|
+
Fe as ImageCropper,
|
|
310
|
+
Le as LabeledInfo,
|
|
311
|
+
P as SectionCard
|
|
312
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tiny-server/design",
|
|
3
|
+
"version": "0.0.0-pre202605241751",
|
|
4
|
+
"description": "The Tiny Server design library package.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tiny-server",
|
|
7
|
+
"design",
|
|
8
|
+
"library"
|
|
9
|
+
],
|
|
10
|
+
"author": "Manuel Römer",
|
|
11
|
+
"license": "AGPL-3.0-only",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/manuelroemer/tiny-server.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/manuelroemer/tiny-server/issues"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"module": "dist/index.js",
|
|
22
|
+
"types": "dist/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"src",
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./index.css": {
|
|
33
|
+
"import": "./dist/index.css"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"start": "vite build --watch",
|
|
38
|
+
"build": "vite build",
|
|
39
|
+
"test": "",
|
|
40
|
+
"lint": "eslint src",
|
|
41
|
+
"storybook": "storybook dev -p 6006"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"react-easy-crop": "5.5.7"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@mantine/core": "^9",
|
|
48
|
+
"react": "^19",
|
|
49
|
+
"react-dom": "^19"
|
|
50
|
+
},
|
|
51
|
+
"gitHead": "193d19cb2bc34732a7d80e709067851e249803c4"
|
|
52
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Badge } from '@mantine/core';
|
|
2
|
+
import { BadgeGroup } from './BadgeGroup';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof BadgeGroup> = {
|
|
6
|
+
component: BadgeGroup,
|
|
7
|
+
title: 'Components/BadgeGroup',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Story = StoryObj<typeof meta>;
|
|
11
|
+
|
|
12
|
+
export const Default: Story = {
|
|
13
|
+
render: () => (
|
|
14
|
+
<BadgeGroup max={3}>
|
|
15
|
+
<Badge>Badge 1</Badge>
|
|
16
|
+
<Badge>Badge 2</Badge>
|
|
17
|
+
<Badge>Badge 3</Badge>
|
|
18
|
+
<Badge>Badge 4</Badge>
|
|
19
|
+
<Badge>Badge 5</Badge>
|
|
20
|
+
</BadgeGroup>
|
|
21
|
+
),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Badge, Group } from '@mantine/core';
|
|
2
|
+
import { Children, type PropsWithChildren, type ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
export interface BadgeGroupProps extends PropsWithChildren {
|
|
5
|
+
max?: number;
|
|
6
|
+
renderHidden?(hidden: number): ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function defaultMore(hidden: number) {
|
|
10
|
+
return <Badge variant="default">+{hidden}</Badge>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function BadgeGroup({ children, max = Number.MAX_SAFE_INTEGER, renderHidden = defaultMore }: BadgeGroupProps) {
|
|
14
|
+
const childElements = Children.toArray(children);
|
|
15
|
+
const visibleElement = childElements.slice(0, max);
|
|
16
|
+
const hiddenElements = childElements.length - max;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Group gap="xs">
|
|
20
|
+
{visibleElement}
|
|
21
|
+
{hiddenElements > 0 && renderHidden(hiddenElements)}
|
|
22
|
+
</Group>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BadgeGroup';
|