@brandlab-digital/site-next 3.9.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/contact/attachments-client.d.ts +3 -0
- package/dist/contact/attachments-client.d.ts.map +1 -1
- package/dist/contact/attachments-client.js +31 -8
- package/dist/contact/attachments-client.js.map +1 -1
- package/dist/contact/client-entry.d.ts +1 -1
- package/dist/contact/client-entry.d.ts.map +1 -1
- package/dist/contact/client-entry.js.map +1 -1
- package/dist/contact/contract.d.ts.map +1 -1
- package/dist/contact/contract.js +2 -2
- package/dist/contact/contract.js.map +1 -1
- package/dist/contact/email.d.ts.map +1 -1
- package/dist/contact/email.js +9 -0
- package/dist/contact/email.js.map +1 -1
- package/dist/contact/form-client.d.ts +4 -2
- package/dist/contact/form-client.d.ts.map +1 -1
- package/dist/contact/form-client.js +49 -13
- package/dist/contact/form-client.js.map +1 -1
- package/dist/contact/rate-limit.d.ts +59 -0
- package/dist/contact/rate-limit.d.ts.map +1 -0
- package/dist/contact/rate-limit.js +109 -0
- package/dist/contact/rate-limit.js.map +1 -0
- package/dist/contact/route-handler.d.ts +6 -0
- package/dist/contact/route-handler.d.ts.map +1 -1
- package/dist/contact/route-handler.js +4 -0
- package/dist/contact/route-handler.js.map +1 -1
- package/dist/contact/server-entry.d.ts +1 -1
- package/dist/contact/server-entry.d.ts.map +1 -1
- package/dist/contact/server-entry.js +1 -1
- package/dist/contact/server-entry.js.map +1 -1
- package/dist/contact/server.d.ts +9 -0
- package/dist/contact/server.d.ts.map +1 -1
- package/dist/contact/server.js +71 -7
- package/dist/contact/server.js.map +1 -1
- package/dist/contact/shared.d.ts +11 -0
- package/dist/contact/shared.d.ts.map +1 -1
- package/dist/contact/shared.js +11 -0
- package/dist/contact/shared.js.map +1 -1
- package/dist/contact/testing.d.ts +5 -0
- package/dist/contact/testing.d.ts.map +1 -1
- package/dist/contact/testing.js +1 -0
- package/dist/contact/testing.js.map +1 -1
- package/dist/lead-reporting.d.ts +6 -0
- package/dist/lead-reporting.d.ts.map +1 -1
- package/dist/lead-reporting.js +13 -1
- package/dist/lead-reporting.js.map +1 -1
- package/dist/ui-kit/brandlab-skin.d.ts +12 -0
- package/dist/ui-kit/brandlab-skin.d.ts.map +1 -1
- package/dist/ui-kit/brandlab-skin.js.map +1 -1
- package/dist/ui-kit/form/copy.d.ts +3 -0
- package/dist/ui-kit/form/copy.d.ts.map +1 -0
- package/dist/ui-kit/form/copy.js +5 -0
- package/dist/ui-kit/form/copy.js.map +1 -0
- package/dist/ui-kit/form/dialog.d.ts +24 -0
- package/dist/ui-kit/form/dialog.d.ts.map +1 -0
- package/dist/ui-kit/form/dialog.js +17 -0
- package/dist/ui-kit/form/dialog.js.map +1 -0
- package/dist/ui-kit/form/field.d.ts +30 -0
- package/dist/ui-kit/form/field.d.ts.map +1 -0
- package/dist/ui-kit/form/field.js +11 -0
- package/dist/ui-kit/form/field.js.map +1 -0
- package/dist/ui-kit/form/index.d.ts +7 -0
- package/dist/ui-kit/form/index.d.ts.map +1 -0
- package/dist/ui-kit/form/index.js +7 -0
- package/dist/ui-kit/form/index.js.map +1 -0
- package/dist/ui-kit/form/photo-upload.d.ts +37 -0
- package/dist/ui-kit/form/photo-upload.d.ts.map +1 -0
- package/dist/ui-kit/form/photo-upload.js +19 -0
- package/dist/ui-kit/form/photo-upload.js.map +1 -0
- package/dist/ui-kit/form/quote-dialog.d.ts +15 -0
- package/dist/ui-kit/form/quote-dialog.d.ts.map +1 -0
- package/dist/ui-kit/form/quote-dialog.js +68 -0
- package/dist/ui-kit/form/quote-dialog.js.map +1 -0
- package/dist/ui-kit/form/quote-form.d.ts +165 -0
- package/dist/ui-kit/form/quote-form.d.ts.map +1 -0
- package/dist/ui-kit/form/quote-form.js +235 -0
- package/dist/ui-kit/form/quote-form.js.map +1 -0
- package/dist/ui-kit/form/thank-you.d.ts +37 -0
- package/dist/ui-kit/form/thank-you.d.ts.map +1 -0
- package/dist/ui-kit/form/thank-you.js +36 -0
- package/dist/ui-kit/form/thank-you.js.map +1 -0
- package/dist/ui-kit/structure.css +197 -0
- package/dist/ui.d.ts +10 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +3 -3
- package/dist/ui.js.map +1 -1
- package/package.json +6 -2
|
@@ -714,4 +714,201 @@
|
|
|
714
714
|
outline: none;
|
|
715
715
|
}
|
|
716
716
|
|
|
717
|
+
/* 20-form.css */
|
|
718
|
+
/* Quote form, photo upload and fields: layout and behaviour only. Labels sit above fields; one column below 640 px. */
|
|
719
|
+
|
|
720
|
+
/* A size container can't take its width from its content, so it fills its parent even inside a shrink-to-fit box. */
|
|
721
|
+
[data-bl='quote-form'] {
|
|
722
|
+
display: grid;
|
|
723
|
+
gap: 1.25rem;
|
|
724
|
+
inline-size: 100%;
|
|
725
|
+
container-type: inline-size;
|
|
726
|
+
}
|
|
727
|
+
[data-bl='quote-form'][data-density='compact'] {
|
|
728
|
+
gap: 0.875rem;
|
|
729
|
+
}
|
|
730
|
+
[data-bl='quote-form'] [data-slot='row'] {
|
|
731
|
+
display: grid;
|
|
732
|
+
gap: inherit;
|
|
733
|
+
grid-template-columns: minmax(0, 1fr);
|
|
734
|
+
}
|
|
735
|
+
@media (min-width: 640px) {
|
|
736
|
+
@container (min-width: 28rem) {
|
|
737
|
+
[data-bl='quote-form'] [data-slot='row'] {
|
|
738
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
:where([data-bl='quote-form'], [data-bl='field'], [data-bl='photo-upload']) {
|
|
744
|
+
min-width: 0;
|
|
745
|
+
}
|
|
746
|
+
[data-bl='field'],
|
|
747
|
+
[data-bl='photo-upload'] {
|
|
748
|
+
display: grid;
|
|
749
|
+
gap: 0.375rem;
|
|
750
|
+
align-content: start;
|
|
751
|
+
}
|
|
752
|
+
:where([data-bl='quote-form'], [data-bl='field']) :where(input:not([type='file']), textarea, select) {
|
|
753
|
+
width: 100%;
|
|
754
|
+
min-height: 44px;
|
|
755
|
+
font: inherit;
|
|
756
|
+
}
|
|
757
|
+
:where([data-bl='quote-form'], [data-bl='field']) textarea {
|
|
758
|
+
resize: vertical;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/* The drop box: the label covers the whole box, so a tap anywhere opens the picker; the hidden input keeps focus. */
|
|
762
|
+
[data-bl='photo-upload'] [data-slot='drop'] {
|
|
763
|
+
position: relative;
|
|
764
|
+
display: flex;
|
|
765
|
+
flex-wrap: wrap;
|
|
766
|
+
align-items: center;
|
|
767
|
+
justify-content: space-between;
|
|
768
|
+
gap: 0.5rem 1rem;
|
|
769
|
+
min-height: 44px;
|
|
770
|
+
padding: 0.75rem 1rem;
|
|
771
|
+
border: 1px dashed var(--bl-color-line, currentColor);
|
|
772
|
+
border-radius: var(--bl-radius-control, 0);
|
|
773
|
+
cursor: pointer;
|
|
774
|
+
}
|
|
775
|
+
[data-bl='photo-upload'] [data-slot='drop'][data-disabled='true'] {
|
|
776
|
+
cursor: not-allowed;
|
|
777
|
+
}
|
|
778
|
+
[data-bl='photo-upload'] [data-slot='drop'][data-state='busy'] {
|
|
779
|
+
cursor: progress;
|
|
780
|
+
}
|
|
781
|
+
[data-bl='photo-upload'] [data-slot='drop']:has(input:focus-visible) {
|
|
782
|
+
outline: 2px solid var(--bl-color-focus, currentColor);
|
|
783
|
+
outline-offset: 3px;
|
|
784
|
+
}
|
|
785
|
+
[data-bl='photo-upload'] [data-slot='drop'] [data-slot='label'] {
|
|
786
|
+
display: inline-flex;
|
|
787
|
+
align-items: center;
|
|
788
|
+
gap: 0.5rem;
|
|
789
|
+
cursor: inherit;
|
|
790
|
+
}
|
|
791
|
+
[data-bl='photo-upload'] [data-slot='drop'] [data-slot='label']::after {
|
|
792
|
+
content: '';
|
|
793
|
+
position: absolute;
|
|
794
|
+
inset: 0;
|
|
795
|
+
}
|
|
796
|
+
[data-bl='photo-upload'] [data-slot='dropIcon'] svg {
|
|
797
|
+
width: 1.5em;
|
|
798
|
+
height: 1.5em;
|
|
799
|
+
}
|
|
800
|
+
[data-bl='photo-upload'] [data-slot='photos'] {
|
|
801
|
+
display: flex;
|
|
802
|
+
flex-wrap: wrap;
|
|
803
|
+
gap: 0.75rem;
|
|
804
|
+
margin: 0;
|
|
805
|
+
padding: 0;
|
|
806
|
+
list-style: none;
|
|
807
|
+
}
|
|
808
|
+
[data-bl='photo-upload'] [data-slot='photo'] {
|
|
809
|
+
position: relative;
|
|
810
|
+
}
|
|
811
|
+
[data-bl='photo-upload'] [data-slot='thumb'] {
|
|
812
|
+
display: block;
|
|
813
|
+
width: 4rem;
|
|
814
|
+
height: 4rem;
|
|
815
|
+
object-fit: cover;
|
|
816
|
+
border-radius: var(--bl-radius-control, 0);
|
|
817
|
+
}
|
|
818
|
+
[data-bl='photo-upload'] [data-slot='remove'] {
|
|
819
|
+
position: absolute;
|
|
820
|
+
inset-block-start: -0.75rem;
|
|
821
|
+
inset-inline-end: -0.75rem;
|
|
822
|
+
display: inline-flex;
|
|
823
|
+
align-items: center;
|
|
824
|
+
justify-content: center;
|
|
825
|
+
min-width: 44px;
|
|
826
|
+
min-height: 44px;
|
|
827
|
+
padding: 0;
|
|
828
|
+
border: 0;
|
|
829
|
+
background: none;
|
|
830
|
+
color: inherit;
|
|
831
|
+
cursor: pointer;
|
|
832
|
+
}
|
|
833
|
+
[data-bl='photo-upload'] [data-slot='remove'] svg {
|
|
834
|
+
width: 1.25rem;
|
|
835
|
+
height: 1.25rem;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
[data-bl='quote-form'] [data-slot='submit'] {
|
|
839
|
+
display: inline-flex;
|
|
840
|
+
align-items: center;
|
|
841
|
+
justify-content: center;
|
|
842
|
+
gap: 0.5rem;
|
|
843
|
+
min-height: 44px;
|
|
844
|
+
justify-self: start;
|
|
845
|
+
}
|
|
846
|
+
[data-bl='quote-form'][data-variant='card'] [data-slot='submit'],
|
|
847
|
+
[data-bl='quote-form'][data-variant='inline'] [data-slot='submit'] {
|
|
848
|
+
justify-self: stretch;
|
|
849
|
+
}
|
|
850
|
+
[data-bl='quote-form'] [data-slot='submit'][data-state='busy'] {
|
|
851
|
+
cursor: progress;
|
|
852
|
+
}
|
|
853
|
+
[data-bl='quote-form'] :where([data-slot='consent'], [data-slot='status']) {
|
|
854
|
+
margin: 0;
|
|
855
|
+
}
|
|
856
|
+
/* Empty, the status region stays in the accessibility tree (visually hidden), so its next message is announced. */
|
|
857
|
+
[data-bl='quote-form'] [data-slot='status']:empty {
|
|
858
|
+
position: absolute;
|
|
859
|
+
width: 1px;
|
|
860
|
+
height: 1px;
|
|
861
|
+
overflow: hidden;
|
|
862
|
+
clip-path: inset(50%);
|
|
863
|
+
white-space: nowrap;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/* 21-dialog.css */
|
|
867
|
+
/* Dialog: a native modal. The page behind doesn't scroll; the body scrolls inside the panel on short screens. */
|
|
868
|
+
|
|
869
|
+
[data-bl='dialog'] {
|
|
870
|
+
width: min(40rem, calc(100% - 2 * var(--bl-gutter, 1rem)));
|
|
871
|
+
max-height: calc(100dvh - 2rem);
|
|
872
|
+
padding: 0;
|
|
873
|
+
border: 0;
|
|
874
|
+
overflow: auto;
|
|
875
|
+
background: var(--bl-color-surface, Canvas);
|
|
876
|
+
color: var(--bl-color-ink, CanvasText);
|
|
877
|
+
border-radius: var(--bl-radius-card, 0);
|
|
878
|
+
box-shadow: var(--bl-shadow-overlay, none);
|
|
879
|
+
}
|
|
880
|
+
:root:has([data-bl='dialog'][open]) {
|
|
881
|
+
overflow: hidden;
|
|
882
|
+
}
|
|
883
|
+
[data-bl='dialog'] [data-slot='header'] {
|
|
884
|
+
display: flex;
|
|
885
|
+
align-items: flex-start;
|
|
886
|
+
justify-content: space-between;
|
|
887
|
+
gap: 1rem;
|
|
888
|
+
padding: 1rem var(--bl-gutter, 1.25rem) 0;
|
|
889
|
+
}
|
|
890
|
+
[data-bl='dialog'] [data-slot='title'] {
|
|
891
|
+
margin: 0;
|
|
892
|
+
}
|
|
893
|
+
[data-bl='dialog'] [data-slot='close'] {
|
|
894
|
+
display: inline-flex;
|
|
895
|
+
align-items: center;
|
|
896
|
+
justify-content: center;
|
|
897
|
+
flex-shrink: 0;
|
|
898
|
+
min-width: 44px;
|
|
899
|
+
min-height: 44px;
|
|
900
|
+
padding: 0;
|
|
901
|
+
border: 0;
|
|
902
|
+
background: none;
|
|
903
|
+
color: inherit;
|
|
904
|
+
cursor: pointer;
|
|
905
|
+
}
|
|
906
|
+
[data-bl='dialog'] [data-slot='close'] svg {
|
|
907
|
+
width: 1.5rem;
|
|
908
|
+
height: 1.5rem;
|
|
909
|
+
}
|
|
910
|
+
[data-bl='dialog'] [data-slot='body'] {
|
|
911
|
+
padding: 1rem var(--bl-gutter, 1.25rem) var(--bl-gutter, 1.25rem);
|
|
912
|
+
}
|
|
913
|
+
|
|
717
914
|
}
|
package/dist/ui.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface HeadlessDisclosureProps extends DetailsHTMLAttributes<HTMLDetai
|
|
|
14
14
|
children: ReactNode;
|
|
15
15
|
}
|
|
16
16
|
export declare function HeadlessDisclosure({ summary, summaryClassName, contentClassName, children, ...detailsProps }: HeadlessDisclosureProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
/** `data-*` attributes only: stable hooks for a design system's styling, never behaviour. */
|
|
18
|
+
export type HeadlessDataAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
|
|
17
19
|
export interface HeadlessFieldProps {
|
|
18
20
|
id: string;
|
|
19
21
|
label: ReactNode;
|
|
@@ -24,6 +26,13 @@ export interface HeadlessFieldProps {
|
|
|
24
26
|
labelClassName?: string;
|
|
25
27
|
descriptionClassName?: string;
|
|
26
28
|
errorClassName?: string;
|
|
29
|
+
/** Optional `data-*` hooks for the wrapper, label, description and error elements. */
|
|
30
|
+
dataAttributes?: {
|
|
31
|
+
field?: HeadlessDataAttributes;
|
|
32
|
+
label?: HeadlessDataAttributes;
|
|
33
|
+
description?: HeadlessDataAttributes;
|
|
34
|
+
error?: HeadlessDataAttributes;
|
|
35
|
+
};
|
|
27
36
|
children: (input: {
|
|
28
37
|
id: string;
|
|
29
38
|
required: boolean;
|
|
@@ -31,7 +40,7 @@ export interface HeadlessFieldProps {
|
|
|
31
40
|
'aria-describedby': string | undefined;
|
|
32
41
|
}) => ReactNode;
|
|
33
42
|
}
|
|
34
|
-
export declare function HeadlessField({ id, label, description, error, required, children, ...classes }: HeadlessFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
export declare function HeadlessField({ id, label, description, error, required, children, dataAttributes, ...classes }: HeadlessFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
35
44
|
export interface HeadlessStatusProps extends HTMLAttributes<HTMLDivElement> {
|
|
36
45
|
children: ReactNode;
|
|
37
46
|
kind?: 'status' | 'error';
|
package/dist/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui.js
CHANGED
|
@@ -6,16 +6,16 @@ export function HeadlessSection({ heading, headingId, headingClassName, contentC
|
|
|
6
6
|
export function HeadlessDisclosure({ summary, summaryClassName, contentClassName, children, ...detailsProps }) {
|
|
7
7
|
return (_jsxs("details", { ...detailsProps, children: [_jsx("summary", { className: summaryClassName, children: summary }), _jsx("div", { className: contentClassName, children: children })] }));
|
|
8
8
|
}
|
|
9
|
-
export function HeadlessField({ id, label, description, error, required = false, children, ...classes }) {
|
|
9
|
+
export function HeadlessField({ id, label, description, error, required = false, children, dataAttributes, ...classes }) {
|
|
10
10
|
const descriptionId = description ? `${id}-description` : undefined;
|
|
11
11
|
const errorId = error ? `${id}-error` : undefined;
|
|
12
12
|
const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined;
|
|
13
|
-
return (_jsxs("div", { className: classes.className, children: [_jsx("label", { className: classes.labelClassName, htmlFor: id, children: label }), description ? (_jsx("div", { className: classes.descriptionClassName, id: descriptionId, children: description })) : null, children({
|
|
13
|
+
return (_jsxs("div", { ...dataAttributes?.field, className: classes.className, children: [_jsx("label", { ...dataAttributes?.label, className: classes.labelClassName, htmlFor: id, children: label }), description ? (_jsx("div", { ...dataAttributes?.description, className: classes.descriptionClassName, id: descriptionId, children: description })) : null, children({
|
|
14
14
|
id,
|
|
15
15
|
required,
|
|
16
16
|
'aria-invalid': error ? true : undefined,
|
|
17
17
|
'aria-describedby': describedBy,
|
|
18
|
-
}), error ? (_jsx("div", { className: classes.errorClassName, id: errorId, role: "alert", children: error })) : null] }));
|
|
18
|
+
}), error ? (_jsx("div", { ...dataAttributes?.error, className: classes.errorClassName, id: errorId, role: "alert", children: error })) : null] }));
|
|
19
19
|
}
|
|
20
20
|
export function HeadlessStatus({ children, kind = 'status', ...props }) {
|
|
21
21
|
return (_jsx("div", { ...props, "aria-live": kind === 'error' ? 'assertive' : 'polite', role: kind === 'error' ? 'alert' : 'status', children: children }));
|
package/dist/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnchorHTMLAttributes,\n DetailsHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n} from 'react'\nimport { assertSafeRichTextHref, sanitizeRichTextHref } from '@brandlab-digital/site-core/rich-text'\n\nexport interface HeadlessSectionProps extends HTMLAttributes<HTMLElement> {\n heading: ReactNode\n headingId: string\n headingClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessSection({\n heading,\n headingId,\n headingClassName,\n contentClassName,\n children,\n ...sectionProps\n}: HeadlessSectionProps) {\n return (\n <section {...sectionProps} aria-labelledby={headingId}>\n <h2 className={headingClassName} id={headingId}>\n {heading}\n </h2>\n <div className={contentClassName}>{children}</div>\n </section>\n )\n}\n\nexport interface HeadlessDisclosureProps extends DetailsHTMLAttributes<HTMLDetailsElement> {\n summary: ReactNode\n summaryClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessDisclosure({\n summary,\n summaryClassName,\n contentClassName,\n children,\n ...detailsProps\n}: HeadlessDisclosureProps) {\n return (\n <details {...detailsProps}>\n <summary className={summaryClassName}>{summary}</summary>\n <div className={contentClassName}>{children}</div>\n </details>\n )\n}\n\nexport interface HeadlessFieldProps {\n id: string\n label: ReactNode\n description?: ReactNode\n error?: ReactNode\n required?: boolean\n className?: string\n labelClassName?: string\n descriptionClassName?: string\n errorClassName?: string\n children: (input: {\n id: string\n required: boolean\n 'aria-invalid': true | undefined\n 'aria-describedby': string | undefined\n }) => ReactNode\n}\n\nexport function HeadlessField({\n id,\n label,\n description,\n error,\n required = false,\n children,\n ...classes\n}: HeadlessFieldProps) {\n const descriptionId = description ? `${id}-description` : undefined\n const errorId = error ? `${id}-error` : undefined\n const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined\n return (\n <div className={classes.className}>\n <label className={classes.labelClassName} htmlFor={id}>\n {label}\n </label>\n {description ? (\n <div className={classes.descriptionClassName} id={descriptionId}>\n {description}\n </div>\n ) : null}\n {children({\n id,\n required,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': describedBy,\n })}\n {error ? (\n <div className={classes.errorClassName} id={errorId} role=\"alert\">\n {error}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport interface HeadlessStatusProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode\n kind?: 'status' | 'error'\n}\n\nexport function HeadlessStatus({ children, kind = 'status', ...props }: HeadlessStatusProps) {\n return (\n <div {...props} aria-live={kind === 'error' ? 'assertive' : 'polite'} role={kind === 'error' ? 'alert' : 'status'}>\n {children}\n </div>\n )\n}\n\nexport interface HeadlessErrorSummaryItem {\n fieldId: string\n message: ReactNode\n}\n\nexport interface HeadlessErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {\n heading: ReactNode\n errors: readonly HeadlessErrorSummaryItem[]\n headingId: string\n linkClassName?: string\n}\n\nexport function HeadlessErrorSummary({\n heading,\n errors,\n headingId,\n linkClassName,\n ...props\n}: HeadlessErrorSummaryProps) {\n if (errors.length === 0) return null\n return (\n <div {...props} aria-labelledby={headingId} role=\"alert\" tabIndex={-1}>\n <h2 id={headingId}>{heading}</h2>\n <ul>\n {errors.map((error) => (\n <li key={error.fieldId}>\n <a\n className={linkClassName}\n href={`#${assertHtmlIdentifier(error.fieldId, 'Error summary fieldId')}`}\n >\n {error.message}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n targetId: string\n children: ReactNode\n}\n\nexport function SkipLink({ targetId, children, ...props }: SkipLinkProps) {\n assertHtmlIdentifier(targetId, 'SkipLink targetId')\n return (\n <a {...props} href={`#${targetId}`}>\n {children}\n </a>\n )\n}\n\nfunction assertHtmlIdentifier(value: string, label: string) {\n if (!/^[A-Za-z][A-Za-z0-9_:.-]*$/.test(value)) {\n throw new Error(`${label} must be a valid HTML identifier.`)\n }\n return value\n}\n\nexport type SafeRichTextNode =\n | { type: 'text'; value: string; emphasis?: 'strong' | 'emphasis' }\n | { type: 'paragraph'; children: readonly SafeRichTextNode[] }\n | { type: 'link'; href: string; children: readonly SafeRichTextNode[]; external?: boolean }\n | { type: 'unordered-list' | 'ordered-list'; children: readonly SafeRichTextNode[] }\n | { type: 'list-item'; children: readonly SafeRichTextNode[] }\n | { type: 'line-break' }\n\nexport type SafeRichTextElement = 'div' | 'p' | 'span'\n\nexport interface SafeRichTextProps extends HTMLAttributes<HTMLElement> {\n nodes: readonly SafeRichTextNode[]\n /**\n * The wrapper element. `div` (default) holds block content: paragraphs and\n * lists. `p` and `span` hold inline content only (text, emphasis, links and\n * line breaks), so the output has no block element and can sit where only\n * phrasing content is allowed, such as inside a button; a block node under\n * them throws.\n */\n as?: SafeRichTextElement\n /** Class for every link, rendered after `href`. */\n linkClassName?: string\n}\n\nconst INLINE_RICH_TEXT_TYPES = new Set<SafeRichTextNode['type']>(['text', 'link', 'line-break'])\n\nfunction assertInlineRichText(nodes: readonly SafeRichTextNode[], element: SafeRichTextElement) {\n for (const node of nodes) {\n if (!INLINE_RICH_TEXT_TYPES.has(node.type)) {\n throw new Error(`SafeRichText as=\"${element}\" renders inline content only; \"${node.type}\" is a block node.`)\n }\n if (node.type === 'link') assertInlineRichText(node.children, element)\n }\n}\n\nfunction renderSafeRichTextNode(node: SafeRichTextNode, key: string, linkClassName?: string): ReactNode {\n if (node.type === 'text') {\n if (node.emphasis === 'strong') return <strong key={key}>{node.value}</strong>\n if (node.emphasis === 'emphasis') return <em key={key}>{node.value}</em>\n return node.value\n }\n if (node.type === 'line-break') return <br key={key} />\n const children = node.children.map((child, index) =>\n renderSafeRichTextNode(child, `${key}-${index}`, linkClassName),\n )\n if (node.type === 'paragraph') return <p key={key}>{children}</p>\n if (node.type === 'list-item') return <li key={key}>{children}</li>\n if (node.type === 'unordered-list') return <ul key={key}>{children}</ul>\n if (node.type === 'ordered-list') return <ol key={key}>{children}</ol>\n if (node.type !== 'link') throw new Error('Unsupported rich text node.')\n const href = assertSafeRichTextHref(node.href)\n return (\n <a\n href={href}\n className={linkClassName}\n key={key}\n {...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {})}\n >\n {children}\n </a>\n )\n}\n\nexport function SafeRichText({ nodes, as: Element = 'div', linkClassName, ...props }: SafeRichTextProps) {\n if (Element !== 'div' && Element !== 'p' && Element !== 'span') {\n throw new Error('SafeRichText renders as \"div\", \"p\" or \"span\".')\n }\n if (Element !== 'div') assertInlineRichText(nodes, Element)\n return (\n <Element {...props}>\n {nodes.map((node, index) => renderSafeRichTextNode(node, String(index), linkClassName))}\n </Element>\n )\n}\n\nconst INLINE_MARKUP_PATTERN = /<(strong|b)>(.*?)<\\/\\1>|<a\\s+[^>]*href=([\"'])(.*?)\\3[^>]*>(.*?)<\\/a>/gis\n\n/**\n * Inline rich-text markup as nodes, for content written as short HTML\n * strings: `<strong>` and `<b>` become strong text, `<a href>` becomes a link\n * when its href passes sanitizeRichTextHref (otherwise its text stays as plain\n * text), every other tag is dropped and text is kept exactly as written\n * (React escapes it). Nothing is ever rendered as HTML. Strong text holds text\n * only; markup nested inside it throws.\n */\nexport function parseInlineRichText(markup: string): SafeRichTextNode[] {\n if (typeof markup !== 'string') throw new TypeError('Inline rich text must be a string.')\n return parseInlineMarkup(markup, false)\n}\n\nfunction parseInlineMarkup(markup: string, insideLink: boolean): SafeRichTextNode[] {\n const nodes: SafeRichTextNode[] = []\n const pattern = new RegExp(INLINE_MARKUP_PATTERN.source, INLINE_MARKUP_PATTERN.flags)\n const text = (value: string) => nodes.push({ type: 'text', value: value.replace(/<[^>]*>/g, '') })\n let cursor = 0\n for (let match = pattern.exec(markup); match !== null; match = pattern.exec(markup)) {\n if (match.index > cursor) text(markup.slice(cursor, match.index))\n const [, , strong, , href, linkText] = match\n if (typeof strong === 'string') {\n const inner = parseInlineMarkup(strong, insideLink)\n if (inner.length > 1 || (inner[0] && (inner[0].type !== 'text' || inner[0].emphasis))) {\n throw new Error('Inline rich text supports only text inside <strong>.')\n }\n nodes.push({ type: 'text', value: inner[0]?.type === 'text' ? inner[0].value : '', emphasis: 'strong' })\n } else if (typeof href === 'string' && typeof linkText === 'string') {\n const safeHref = insideLink ? null : sanitizeRichTextHref(href)\n if (insideLink && sanitizeRichTextHref(href)) throw new Error('Inline rich text links cannot be nested.')\n const children = parseInlineMarkup(linkText, true)\n if (safeHref) nodes.push({ type: 'link', href: safeHref, children })\n else nodes.push(...children)\n }\n cursor = match.index + match[0].length\n }\n if (cursor < markup.length) text(markup.slice(cursor))\n return nodes\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnchorHTMLAttributes,\n DetailsHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n} from 'react'\nimport { assertSafeRichTextHref, sanitizeRichTextHref } from '@brandlab-digital/site-core/rich-text'\n\nexport interface HeadlessSectionProps extends HTMLAttributes<HTMLElement> {\n heading: ReactNode\n headingId: string\n headingClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessSection({\n heading,\n headingId,\n headingClassName,\n contentClassName,\n children,\n ...sectionProps\n}: HeadlessSectionProps) {\n return (\n <section {...sectionProps} aria-labelledby={headingId}>\n <h2 className={headingClassName} id={headingId}>\n {heading}\n </h2>\n <div className={contentClassName}>{children}</div>\n </section>\n )\n}\n\nexport interface HeadlessDisclosureProps extends DetailsHTMLAttributes<HTMLDetailsElement> {\n summary: ReactNode\n summaryClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessDisclosure({\n summary,\n summaryClassName,\n contentClassName,\n children,\n ...detailsProps\n}: HeadlessDisclosureProps) {\n return (\n <details {...detailsProps}>\n <summary className={summaryClassName}>{summary}</summary>\n <div className={contentClassName}>{children}</div>\n </details>\n )\n}\n\n/** `data-*` attributes only: stable hooks for a design system's styling, never behaviour. */\nexport type HeadlessDataAttributes = Readonly<Record<`data-${string}`, string | undefined>>\n\nexport interface HeadlessFieldProps {\n id: string\n label: ReactNode\n description?: ReactNode\n error?: ReactNode\n required?: boolean\n className?: string\n labelClassName?: string\n descriptionClassName?: string\n errorClassName?: string\n /** Optional `data-*` hooks for the wrapper, label, description and error elements. */\n dataAttributes?: {\n field?: HeadlessDataAttributes\n label?: HeadlessDataAttributes\n description?: HeadlessDataAttributes\n error?: HeadlessDataAttributes\n }\n children: (input: {\n id: string\n required: boolean\n 'aria-invalid': true | undefined\n 'aria-describedby': string | undefined\n }) => ReactNode\n}\n\nexport function HeadlessField({\n id,\n label,\n description,\n error,\n required = false,\n children,\n dataAttributes,\n ...classes\n}: HeadlessFieldProps) {\n const descriptionId = description ? `${id}-description` : undefined\n const errorId = error ? `${id}-error` : undefined\n const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined\n return (\n <div {...dataAttributes?.field} className={classes.className}>\n <label {...dataAttributes?.label} className={classes.labelClassName} htmlFor={id}>\n {label}\n </label>\n {description ? (\n <div {...dataAttributes?.description} className={classes.descriptionClassName} id={descriptionId}>\n {description}\n </div>\n ) : null}\n {children({\n id,\n required,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': describedBy,\n })}\n {error ? (\n <div {...dataAttributes?.error} className={classes.errorClassName} id={errorId} role=\"alert\">\n {error}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport interface HeadlessStatusProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode\n kind?: 'status' | 'error'\n}\n\nexport function HeadlessStatus({ children, kind = 'status', ...props }: HeadlessStatusProps) {\n return (\n <div {...props} aria-live={kind === 'error' ? 'assertive' : 'polite'} role={kind === 'error' ? 'alert' : 'status'}>\n {children}\n </div>\n )\n}\n\nexport interface HeadlessErrorSummaryItem {\n fieldId: string\n message: ReactNode\n}\n\nexport interface HeadlessErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {\n heading: ReactNode\n errors: readonly HeadlessErrorSummaryItem[]\n headingId: string\n linkClassName?: string\n}\n\nexport function HeadlessErrorSummary({\n heading,\n errors,\n headingId,\n linkClassName,\n ...props\n}: HeadlessErrorSummaryProps) {\n if (errors.length === 0) return null\n return (\n <div {...props} aria-labelledby={headingId} role=\"alert\" tabIndex={-1}>\n <h2 id={headingId}>{heading}</h2>\n <ul>\n {errors.map((error) => (\n <li key={error.fieldId}>\n <a\n className={linkClassName}\n href={`#${assertHtmlIdentifier(error.fieldId, 'Error summary fieldId')}`}\n >\n {error.message}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n targetId: string\n children: ReactNode\n}\n\nexport function SkipLink({ targetId, children, ...props }: SkipLinkProps) {\n assertHtmlIdentifier(targetId, 'SkipLink targetId')\n return (\n <a {...props} href={`#${targetId}`}>\n {children}\n </a>\n )\n}\n\nfunction assertHtmlIdentifier(value: string, label: string) {\n if (!/^[A-Za-z][A-Za-z0-9_:.-]*$/.test(value)) {\n throw new Error(`${label} must be a valid HTML identifier.`)\n }\n return value\n}\n\nexport type SafeRichTextNode =\n | { type: 'text'; value: string; emphasis?: 'strong' | 'emphasis' }\n | { type: 'paragraph'; children: readonly SafeRichTextNode[] }\n | { type: 'link'; href: string; children: readonly SafeRichTextNode[]; external?: boolean }\n | { type: 'unordered-list' | 'ordered-list'; children: readonly SafeRichTextNode[] }\n | { type: 'list-item'; children: readonly SafeRichTextNode[] }\n | { type: 'line-break' }\n\nexport type SafeRichTextElement = 'div' | 'p' | 'span'\n\nexport interface SafeRichTextProps extends HTMLAttributes<HTMLElement> {\n nodes: readonly SafeRichTextNode[]\n /**\n * The wrapper element. `div` (default) holds block content: paragraphs and\n * lists. `p` and `span` hold inline content only (text, emphasis, links and\n * line breaks), so the output has no block element and can sit where only\n * phrasing content is allowed, such as inside a button; a block node under\n * them throws.\n */\n as?: SafeRichTextElement\n /** Class for every link, rendered after `href`. */\n linkClassName?: string\n}\n\nconst INLINE_RICH_TEXT_TYPES = new Set<SafeRichTextNode['type']>(['text', 'link', 'line-break'])\n\nfunction assertInlineRichText(nodes: readonly SafeRichTextNode[], element: SafeRichTextElement) {\n for (const node of nodes) {\n if (!INLINE_RICH_TEXT_TYPES.has(node.type)) {\n throw new Error(`SafeRichText as=\"${element}\" renders inline content only; \"${node.type}\" is a block node.`)\n }\n if (node.type === 'link') assertInlineRichText(node.children, element)\n }\n}\n\nfunction renderSafeRichTextNode(node: SafeRichTextNode, key: string, linkClassName?: string): ReactNode {\n if (node.type === 'text') {\n if (node.emphasis === 'strong') return <strong key={key}>{node.value}</strong>\n if (node.emphasis === 'emphasis') return <em key={key}>{node.value}</em>\n return node.value\n }\n if (node.type === 'line-break') return <br key={key} />\n const children = node.children.map((child, index) =>\n renderSafeRichTextNode(child, `${key}-${index}`, linkClassName),\n )\n if (node.type === 'paragraph') return <p key={key}>{children}</p>\n if (node.type === 'list-item') return <li key={key}>{children}</li>\n if (node.type === 'unordered-list') return <ul key={key}>{children}</ul>\n if (node.type === 'ordered-list') return <ol key={key}>{children}</ol>\n if (node.type !== 'link') throw new Error('Unsupported rich text node.')\n const href = assertSafeRichTextHref(node.href)\n return (\n <a\n href={href}\n className={linkClassName}\n key={key}\n {...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {})}\n >\n {children}\n </a>\n )\n}\n\nexport function SafeRichText({ nodes, as: Element = 'div', linkClassName, ...props }: SafeRichTextProps) {\n if (Element !== 'div' && Element !== 'p' && Element !== 'span') {\n throw new Error('SafeRichText renders as \"div\", \"p\" or \"span\".')\n }\n if (Element !== 'div') assertInlineRichText(nodes, Element)\n return (\n <Element {...props}>\n {nodes.map((node, index) => renderSafeRichTextNode(node, String(index), linkClassName))}\n </Element>\n )\n}\n\nconst INLINE_MARKUP_PATTERN = /<(strong|b)>(.*?)<\\/\\1>|<a\\s+[^>]*href=([\"'])(.*?)\\3[^>]*>(.*?)<\\/a>/gis\n\n/**\n * Inline rich-text markup as nodes, for content written as short HTML\n * strings: `<strong>` and `<b>` become strong text, `<a href>` becomes a link\n * when its href passes sanitizeRichTextHref (otherwise its text stays as plain\n * text), every other tag is dropped and text is kept exactly as written\n * (React escapes it). Nothing is ever rendered as HTML. Strong text holds text\n * only; markup nested inside it throws.\n */\nexport function parseInlineRichText(markup: string): SafeRichTextNode[] {\n if (typeof markup !== 'string') throw new TypeError('Inline rich text must be a string.')\n return parseInlineMarkup(markup, false)\n}\n\nfunction parseInlineMarkup(markup: string, insideLink: boolean): SafeRichTextNode[] {\n const nodes: SafeRichTextNode[] = []\n const pattern = new RegExp(INLINE_MARKUP_PATTERN.source, INLINE_MARKUP_PATTERN.flags)\n const text = (value: string) => nodes.push({ type: 'text', value: value.replace(/<[^>]*>/g, '') })\n let cursor = 0\n for (let match = pattern.exec(markup); match !== null; match = pattern.exec(markup)) {\n if (match.index > cursor) text(markup.slice(cursor, match.index))\n const [, , strong, , href, linkText] = match\n if (typeof strong === 'string') {\n const inner = parseInlineMarkup(strong, insideLink)\n if (inner.length > 1 || (inner[0] && (inner[0].type !== 'text' || inner[0].emphasis))) {\n throw new Error('Inline rich text supports only text inside <strong>.')\n }\n nodes.push({ type: 'text', value: inner[0]?.type === 'text' ? inner[0].value : '', emphasis: 'strong' })\n } else if (typeof href === 'string' && typeof linkText === 'string') {\n const safeHref = insideLink ? null : sanitizeRichTextHref(href)\n if (insideLink && sanitizeRichTextHref(href)) throw new Error('Inline rich text links cannot be nested.')\n const children = parseInlineMarkup(linkText, true)\n if (safeHref) nodes.push({ type: 'link', href: safeHref, children })\n else nodes.push(...children)\n }\n cursor = match.index + match[0].length\n }\n if (cursor < markup.length) text(markup.slice(cursor))\n return nodes\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brandlab-digital/site-next",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@brandlab-digital/site-core": "3.
|
|
28
|
+
"@brandlab-digital/site-core": "3.10.0",
|
|
29
29
|
"browser-image-compression": "2.0.2",
|
|
30
30
|
"pdf-lib": "1.17.1",
|
|
31
31
|
"server-only": "0.0.1",
|
|
@@ -170,6 +170,10 @@
|
|
|
170
170
|
"types": "./dist/navigation/index.d.ts",
|
|
171
171
|
"import": "./dist/navigation/index.js"
|
|
172
172
|
},
|
|
173
|
+
"./ui-kit/form": {
|
|
174
|
+
"types": "./dist/ui-kit/form/index.d.ts",
|
|
175
|
+
"import": "./dist/ui-kit/form/index.js"
|
|
176
|
+
},
|
|
173
177
|
"./ui-kit/structure.css": {
|
|
174
178
|
"style": "./dist/ui-kit/structure.css",
|
|
175
179
|
"default": "./dist/ui-kit/structure.css"
|