@refraction-ui/react 0.12.2 → 0.13.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/dist/{applicationinsights-web-62HUCH3W.js → applicationinsights-web-H7OBLIVJ.js} +199 -68
- package/dist/applicationinsights-web-H7OBLIVJ.js.map +1 -0
- package/dist/index.cjs +900 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +692 -17
- package/dist/index.js.map +1 -1
- package/dist/internal/button/index.d.cts +12 -3
- package/dist/internal/button/index.d.ts +12 -3
- package/dist/internal/empty-state/index.d.cts +39 -0
- package/dist/internal/empty-state/index.d.ts +39 -0
- package/dist/internal/input/index.d.cts +19 -1
- package/dist/internal/input/index.d.ts +19 -1
- package/dist/internal/react-empty-state/index.d.cts +36 -0
- package/dist/internal/react-empty-state/index.d.ts +36 -0
- package/dist/internal/react-input/index.d.cts +16 -0
- package/dist/internal/react-input/index.d.ts +16 -0
- package/dist/internal/react-password-input/index.d.cts +26 -0
- package/dist/internal/react-password-input/index.d.ts +26 -0
- package/dist/internal/react-segmented-control/index.d.cts +38 -0
- package/dist/internal/react-segmented-control/index.d.ts +38 -0
- package/dist/internal/react-separator/index.d.cts +29 -0
- package/dist/internal/react-separator/index.d.ts +29 -0
- package/dist/internal/react-social-auth-button/index.d.cts +31 -0
- package/dist/internal/react-social-auth-button/index.d.ts +31 -0
- package/dist/internal/react-status-indicator/index.d.cts +5 -18
- package/dist/internal/react-status-indicator/index.d.ts +5 -18
- package/dist/internal/react-theme/index.d.cts +19 -1
- package/dist/internal/react-theme/index.d.ts +19 -1
- package/dist/internal/segmented-control/index.d.cts +56 -0
- package/dist/internal/segmented-control/index.d.ts +56 -0
- package/dist/internal/separator/index.d.cts +55 -0
- package/dist/internal/separator/index.d.ts +55 -0
- package/dist/internal/social-auth-button/index.d.cts +47 -0
- package/dist/internal/social-auth-button/index.d.ts +47 -0
- package/dist/internal/theme/index.d.cts +35 -1
- package/dist/internal/theme/index.d.ts +35 -1
- package/dist/theme.cjs +27 -4
- package/dist/theme.cjs.map +1 -1
- package/dist/theme.js +27 -4
- package/dist/theme.js.map +1 -1
- package/package.json +25 -20
- package/dist/applicationinsights-web-62HUCH3W.js.map +0 -1
|
@@ -1,32 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
import { StatusType } from '../status-indicator/index.cjs';
|
|
3
4
|
export { StatusProps as CoreStatusProps, STATUS_COLORS, STATUS_LABELS, StatusAPI, StatusType, statusContainerStyles, statusDotVariants, statusLabelStyles, statusPulseVariants } from '../status-indicator/index.cjs';
|
|
4
5
|
|
|
5
6
|
interface StatusIndicatorProps {
|
|
6
7
|
type: StatusType;
|
|
8
|
+
/** Explicit text label. Takes precedence over `children`. */
|
|
7
9
|
label?: string;
|
|
10
|
+
/** Composable label content. Used when `label` is omitted. */
|
|
11
|
+
children?: React.ReactNode;
|
|
8
12
|
pulse?: boolean;
|
|
9
13
|
showLabel?: boolean;
|
|
10
14
|
className?: string;
|
|
11
15
|
}
|
|
12
|
-
declare function StatusIndicator({ type, label, pulse, showLabel, className, }: StatusIndicatorProps):
|
|
13
|
-
className: string;
|
|
14
|
-
role?: string | undefined;
|
|
15
|
-
tabIndex?: number | undefined;
|
|
16
|
-
'aria-label'?: string | undefined;
|
|
17
|
-
'aria-labelledby'?: string | undefined;
|
|
18
|
-
'aria-describedby'?: string | undefined;
|
|
19
|
-
'aria-controls'?: string | undefined;
|
|
20
|
-
'aria-expanded'?: boolean | undefined;
|
|
21
|
-
'aria-selected'?: boolean | undefined;
|
|
22
|
-
'aria-hidden'?: boolean | undefined;
|
|
23
|
-
'aria-disabled'?: boolean | undefined;
|
|
24
|
-
'aria-pressed'?: boolean | "mixed" | undefined;
|
|
25
|
-
'aria-checked'?: boolean | "mixed" | undefined;
|
|
26
|
-
'aria-current'?: boolean | "page" | "step" | "location" | "date" | "time" | undefined;
|
|
27
|
-
'aria-live'?: "off" | "assertive" | "polite" | undefined;
|
|
28
|
-
'aria-atomic'?: boolean | undefined;
|
|
29
|
-
}, HTMLElement>;
|
|
16
|
+
declare function StatusIndicator({ type, label, children, pulse, showLabel, className, }: StatusIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
30
17
|
declare namespace StatusIndicator {
|
|
31
18
|
var displayName: string;
|
|
32
19
|
}
|
|
@@ -1,32 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
import { StatusType } from '../status-indicator/index.js';
|
|
3
4
|
export { StatusProps as CoreStatusProps, STATUS_COLORS, STATUS_LABELS, StatusAPI, StatusType, statusContainerStyles, statusDotVariants, statusLabelStyles, statusPulseVariants } from '../status-indicator/index.js';
|
|
4
5
|
|
|
5
6
|
interface StatusIndicatorProps {
|
|
6
7
|
type: StatusType;
|
|
8
|
+
/** Explicit text label. Takes precedence over `children`. */
|
|
7
9
|
label?: string;
|
|
10
|
+
/** Composable label content. Used when `label` is omitted. */
|
|
11
|
+
children?: React.ReactNode;
|
|
8
12
|
pulse?: boolean;
|
|
9
13
|
showLabel?: boolean;
|
|
10
14
|
className?: string;
|
|
11
15
|
}
|
|
12
|
-
declare function StatusIndicator({ type, label, pulse, showLabel, className, }: StatusIndicatorProps):
|
|
13
|
-
className: string;
|
|
14
|
-
role?: string | undefined;
|
|
15
|
-
tabIndex?: number | undefined;
|
|
16
|
-
'aria-label'?: string | undefined;
|
|
17
|
-
'aria-labelledby'?: string | undefined;
|
|
18
|
-
'aria-describedby'?: string | undefined;
|
|
19
|
-
'aria-controls'?: string | undefined;
|
|
20
|
-
'aria-expanded'?: boolean | undefined;
|
|
21
|
-
'aria-selected'?: boolean | undefined;
|
|
22
|
-
'aria-hidden'?: boolean | undefined;
|
|
23
|
-
'aria-disabled'?: boolean | undefined;
|
|
24
|
-
'aria-pressed'?: boolean | "mixed" | undefined;
|
|
25
|
-
'aria-checked'?: boolean | "mixed" | undefined;
|
|
26
|
-
'aria-current'?: boolean | "page" | "step" | "location" | "date" | "time" | undefined;
|
|
27
|
-
'aria-live'?: "off" | "assertive" | "polite" | undefined;
|
|
28
|
-
'aria-atomic'?: boolean | undefined;
|
|
29
|
-
}, HTMLElement>;
|
|
16
|
+
declare function StatusIndicator({ type, label, children, pulse, showLabel, className, }: StatusIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
30
17
|
declare namespace StatusIndicator {
|
|
31
18
|
var displayName: string;
|
|
32
19
|
}
|
|
@@ -28,14 +28,32 @@ declare function ThemeToggle({ className, variant }: ThemeToggleProps): React.De
|
|
|
28
28
|
}, HTMLDivElement>;
|
|
29
29
|
|
|
30
30
|
interface ThemeScriptProps {
|
|
31
|
+
/** localStorage key the ThemeProvider reads. */
|
|
31
32
|
storageKey?: string;
|
|
33
|
+
/** Attribute strategy. `class` toggles `light`/`dark` on <html>; otherwise an HTML attribute. */
|
|
32
34
|
attribute?: 'class' | 'data-theme';
|
|
35
|
+
/**
|
|
36
|
+
* Theme to apply when nothing is stored. Match this to `<ThemeProvider defaultMode>`
|
|
37
|
+
* so the pre-paint script and provider agree on the no-storage path. Defaults
|
|
38
|
+
* to `'system'` (current behaviour — OS preference wins). Issue #317.
|
|
39
|
+
*/
|
|
40
|
+
defaultMode?: ThemeMode;
|
|
41
|
+
/**
|
|
42
|
+
* When `false` the inline script never reads `prefers-color-scheme`; the
|
|
43
|
+
* `defaultMode` is applied as-is for first-time visitors. Default `true`.
|
|
44
|
+
*/
|
|
45
|
+
enableSystem?: boolean;
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
48
|
* Renders an inline <script> that prevents theme flash on SSR pages.
|
|
36
49
|
* Place this in the <head> of your document (in Next.js layout.tsx, Remix root, etc.)
|
|
50
|
+
*
|
|
51
|
+
* Mirror the props your <ThemeProvider> uses so first-paint and React mount stay in sync:
|
|
52
|
+
*
|
|
53
|
+
* <ThemeScript defaultMode="light" storageKey="app_theme" />
|
|
54
|
+
* <ThemeProvider defaultMode="light" storageKey="app_theme">…</ThemeProvider>
|
|
37
55
|
*/
|
|
38
|
-
declare function ThemeScript({ storageKey, attribute, }: ThemeScriptProps): React.DetailedReactHTMLElement<{
|
|
56
|
+
declare function ThemeScript({ storageKey, attribute, defaultMode, enableSystem, }: ThemeScriptProps): React.DetailedReactHTMLElement<{
|
|
39
57
|
dangerouslySetInnerHTML: {
|
|
40
58
|
__html: string;
|
|
41
59
|
};
|
|
@@ -28,14 +28,32 @@ declare function ThemeToggle({ className, variant }: ThemeToggleProps): React.De
|
|
|
28
28
|
}, HTMLDivElement>;
|
|
29
29
|
|
|
30
30
|
interface ThemeScriptProps {
|
|
31
|
+
/** localStorage key the ThemeProvider reads. */
|
|
31
32
|
storageKey?: string;
|
|
33
|
+
/** Attribute strategy. `class` toggles `light`/`dark` on <html>; otherwise an HTML attribute. */
|
|
32
34
|
attribute?: 'class' | 'data-theme';
|
|
35
|
+
/**
|
|
36
|
+
* Theme to apply when nothing is stored. Match this to `<ThemeProvider defaultMode>`
|
|
37
|
+
* so the pre-paint script and provider agree on the no-storage path. Defaults
|
|
38
|
+
* to `'system'` (current behaviour — OS preference wins). Issue #317.
|
|
39
|
+
*/
|
|
40
|
+
defaultMode?: ThemeMode;
|
|
41
|
+
/**
|
|
42
|
+
* When `false` the inline script never reads `prefers-color-scheme`; the
|
|
43
|
+
* `defaultMode` is applied as-is for first-time visitors. Default `true`.
|
|
44
|
+
*/
|
|
45
|
+
enableSystem?: boolean;
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
48
|
* Renders an inline <script> that prevents theme flash on SSR pages.
|
|
36
49
|
* Place this in the <head> of your document (in Next.js layout.tsx, Remix root, etc.)
|
|
50
|
+
*
|
|
51
|
+
* Mirror the props your <ThemeProvider> uses so first-paint and React mount stay in sync:
|
|
52
|
+
*
|
|
53
|
+
* <ThemeScript defaultMode="light" storageKey="app_theme" />
|
|
54
|
+
* <ThemeProvider defaultMode="light" storageKey="app_theme">…</ThemeProvider>
|
|
37
55
|
*/
|
|
38
|
-
declare function ThemeScript({ storageKey, attribute, }: ThemeScriptProps): React.DetailedReactHTMLElement<{
|
|
56
|
+
declare function ThemeScript({ storageKey, attribute, defaultMode, enableSystem, }: ThemeScriptProps): React.DetailedReactHTMLElement<{
|
|
39
57
|
dangerouslySetInnerHTML: {
|
|
40
58
|
__html: string;
|
|
41
59
|
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AccessibilityProps } from '../shared/index.cjs';
|
|
2
|
+
|
|
3
|
+
type SegmentedControlSize = 'sm' | 'md';
|
|
4
|
+
/** Value identifying a single segment. */
|
|
5
|
+
type SegmentedControlValue = string;
|
|
6
|
+
interface SegmentedControlProps {
|
|
7
|
+
/** Currently selected segment value (controlled). */
|
|
8
|
+
value?: SegmentedControlValue;
|
|
9
|
+
/** Visual size of the control. */
|
|
10
|
+
size?: SegmentedControlSize;
|
|
11
|
+
}
|
|
12
|
+
interface SegmentedControlAPI {
|
|
13
|
+
/** ARIA attributes to spread on the group element. */
|
|
14
|
+
ariaProps: Partial<AccessibilityProps>;
|
|
15
|
+
/** Data attributes for CSS styling hooks. */
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the framework-agnostic group props for a segmented control.
|
|
20
|
+
*
|
|
21
|
+
* Returns `role="radiogroup"` plus data attributes; adapters spread these
|
|
22
|
+
* onto their group element and handle their own rendering/state.
|
|
23
|
+
*/
|
|
24
|
+
declare function createSegmentedControl(props?: SegmentedControlProps): SegmentedControlAPI;
|
|
25
|
+
/**
|
|
26
|
+
* Pure keyboard-navigation rule shared by every adapter.
|
|
27
|
+
*
|
|
28
|
+
* Given the current index, the pressed key, and the item count, returns the
|
|
29
|
+
* index that focus/selection should move to. Arrow keys wrap; Home/End jump
|
|
30
|
+
* to the ends. Unhandled keys (or an empty group) return `current` unchanged.
|
|
31
|
+
*
|
|
32
|
+
* - ArrowRight / ArrowDown → next (wraps to 0 past the end)
|
|
33
|
+
* - ArrowLeft / ArrowUp → previous (wraps to last before 0)
|
|
34
|
+
* - Home → first
|
|
35
|
+
* - End → last
|
|
36
|
+
*/
|
|
37
|
+
declare function getNextSegmentIndex(current: number, key: string, count: number): number;
|
|
38
|
+
|
|
39
|
+
/** Pill-shaped container that holds the segments (`role="radiogroup"`). */
|
|
40
|
+
declare const segmentedControlVariants: (props?: ({
|
|
41
|
+
size?: "sm" | "md" | undefined;
|
|
42
|
+
} & {
|
|
43
|
+
className?: string;
|
|
44
|
+
}) | undefined) => string;
|
|
45
|
+
/**
|
|
46
|
+
* A single segment (`role="radio"`). The `state` variant carries the
|
|
47
|
+
* active vs inactive visual treatment so adapters never inline these classes.
|
|
48
|
+
*/
|
|
49
|
+
declare const segmentedControlItemVariants: (props?: ({
|
|
50
|
+
size?: "sm" | "md" | undefined;
|
|
51
|
+
state?: "checked" | "unchecked" | undefined;
|
|
52
|
+
} & {
|
|
53
|
+
className?: string;
|
|
54
|
+
}) | undefined) => string;
|
|
55
|
+
|
|
56
|
+
export { type SegmentedControlAPI, type SegmentedControlProps, type SegmentedControlSize, type SegmentedControlValue, createSegmentedControl, getNextSegmentIndex, segmentedControlItemVariants, segmentedControlVariants };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AccessibilityProps } from '../shared/index.js';
|
|
2
|
+
|
|
3
|
+
type SegmentedControlSize = 'sm' | 'md';
|
|
4
|
+
/** Value identifying a single segment. */
|
|
5
|
+
type SegmentedControlValue = string;
|
|
6
|
+
interface SegmentedControlProps {
|
|
7
|
+
/** Currently selected segment value (controlled). */
|
|
8
|
+
value?: SegmentedControlValue;
|
|
9
|
+
/** Visual size of the control. */
|
|
10
|
+
size?: SegmentedControlSize;
|
|
11
|
+
}
|
|
12
|
+
interface SegmentedControlAPI {
|
|
13
|
+
/** ARIA attributes to spread on the group element. */
|
|
14
|
+
ariaProps: Partial<AccessibilityProps>;
|
|
15
|
+
/** Data attributes for CSS styling hooks. */
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the framework-agnostic group props for a segmented control.
|
|
20
|
+
*
|
|
21
|
+
* Returns `role="radiogroup"` plus data attributes; adapters spread these
|
|
22
|
+
* onto their group element and handle their own rendering/state.
|
|
23
|
+
*/
|
|
24
|
+
declare function createSegmentedControl(props?: SegmentedControlProps): SegmentedControlAPI;
|
|
25
|
+
/**
|
|
26
|
+
* Pure keyboard-navigation rule shared by every adapter.
|
|
27
|
+
*
|
|
28
|
+
* Given the current index, the pressed key, and the item count, returns the
|
|
29
|
+
* index that focus/selection should move to. Arrow keys wrap; Home/End jump
|
|
30
|
+
* to the ends. Unhandled keys (or an empty group) return `current` unchanged.
|
|
31
|
+
*
|
|
32
|
+
* - ArrowRight / ArrowDown → next (wraps to 0 past the end)
|
|
33
|
+
* - ArrowLeft / ArrowUp → previous (wraps to last before 0)
|
|
34
|
+
* - Home → first
|
|
35
|
+
* - End → last
|
|
36
|
+
*/
|
|
37
|
+
declare function getNextSegmentIndex(current: number, key: string, count: number): number;
|
|
38
|
+
|
|
39
|
+
/** Pill-shaped container that holds the segments (`role="radiogroup"`). */
|
|
40
|
+
declare const segmentedControlVariants: (props?: ({
|
|
41
|
+
size?: "sm" | "md" | undefined;
|
|
42
|
+
} & {
|
|
43
|
+
className?: string;
|
|
44
|
+
}) | undefined) => string;
|
|
45
|
+
/**
|
|
46
|
+
* A single segment (`role="radio"`). The `state` variant carries the
|
|
47
|
+
* active vs inactive visual treatment so adapters never inline these classes.
|
|
48
|
+
*/
|
|
49
|
+
declare const segmentedControlItemVariants: (props?: ({
|
|
50
|
+
size?: "sm" | "md" | undefined;
|
|
51
|
+
state?: "checked" | "unchecked" | undefined;
|
|
52
|
+
} & {
|
|
53
|
+
className?: string;
|
|
54
|
+
}) | undefined) => string;
|
|
55
|
+
|
|
56
|
+
export { type SegmentedControlAPI, type SegmentedControlProps, type SegmentedControlSize, type SegmentedControlValue, createSegmentedControl, getNextSegmentIndex, segmentedControlItemVariants, segmentedControlVariants };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AccessibilityProps } from '../shared/index.cjs';
|
|
2
|
+
|
|
3
|
+
type SeparatorOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
interface SeparatorProps {
|
|
5
|
+
/** Orientation of the separator. Defaults to `'horizontal'`. */
|
|
6
|
+
orientation?: SeparatorOrientation;
|
|
7
|
+
/**
|
|
8
|
+
* When `true` (the default) the separator is purely visual and is hidden
|
|
9
|
+
* from assistive tech (`role="none"`). When `false` it is exposed as a
|
|
10
|
+
* semantic `role="separator"` with the appropriate `aria-orientation`.
|
|
11
|
+
*/
|
|
12
|
+
decorative?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* ARIA attributes for a separator. Extends the shared base with
|
|
16
|
+
* `aria-orientation`, which is specific to the `separator` role.
|
|
17
|
+
*/
|
|
18
|
+
interface SeparatorAriaProps extends Partial<AccessibilityProps> {
|
|
19
|
+
'aria-orientation'?: SeparatorOrientation;
|
|
20
|
+
}
|
|
21
|
+
interface SeparatorAPI {
|
|
22
|
+
/** ARIA attributes to spread on the element. */
|
|
23
|
+
ariaProps: SeparatorAriaProps;
|
|
24
|
+
/** Data attributes for CSS styling hooks. */
|
|
25
|
+
dataAttributes: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Headless separator core — computes ARIA semantics and data attributes for
|
|
29
|
+
* a separator rule. JSX-free so it can be shared across framework adapters.
|
|
30
|
+
*
|
|
31
|
+
* Per ARIA, a decorative separator must not be announced (`role="none"`),
|
|
32
|
+
* while a semantic one exposes `role="separator"` and `aria-orientation`.
|
|
33
|
+
*/
|
|
34
|
+
declare function createSeparator(props?: SeparatorProps): SeparatorAPI;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Visual variants for the separator rule.
|
|
38
|
+
*
|
|
39
|
+
* - `orientation: horizontal` → a full-width 1px line.
|
|
40
|
+
* - `orientation: vertical` → a full-height 1px line.
|
|
41
|
+
* - `labeled` → flex layout used by the labeled-divider variant, which
|
|
42
|
+
* arranges a centered label between two flanking lines.
|
|
43
|
+
*/
|
|
44
|
+
declare const separatorVariants: (props?: ({
|
|
45
|
+
orientation?: "horizontal" | "vertical" | undefined;
|
|
46
|
+
labeled?: "true" | "false" | undefined;
|
|
47
|
+
} & {
|
|
48
|
+
className?: string;
|
|
49
|
+
}) | undefined) => string;
|
|
50
|
+
/** Class for each flanking line in the labeled-divider variant. */
|
|
51
|
+
declare const separatorLineClass = "h-px flex-1 bg-border";
|
|
52
|
+
/** Class for the centered label in the labeled-divider variant. */
|
|
53
|
+
declare const separatorLabelClass = "px-3 text-xs uppercase tracking-wide text-muted-foreground";
|
|
54
|
+
|
|
55
|
+
export { type SeparatorAPI, type SeparatorOrientation, type SeparatorProps, createSeparator, separatorLabelClass, separatorLineClass, separatorVariants };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AccessibilityProps } from '../shared/index.js';
|
|
2
|
+
|
|
3
|
+
type SeparatorOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
interface SeparatorProps {
|
|
5
|
+
/** Orientation of the separator. Defaults to `'horizontal'`. */
|
|
6
|
+
orientation?: SeparatorOrientation;
|
|
7
|
+
/**
|
|
8
|
+
* When `true` (the default) the separator is purely visual and is hidden
|
|
9
|
+
* from assistive tech (`role="none"`). When `false` it is exposed as a
|
|
10
|
+
* semantic `role="separator"` with the appropriate `aria-orientation`.
|
|
11
|
+
*/
|
|
12
|
+
decorative?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* ARIA attributes for a separator. Extends the shared base with
|
|
16
|
+
* `aria-orientation`, which is specific to the `separator` role.
|
|
17
|
+
*/
|
|
18
|
+
interface SeparatorAriaProps extends Partial<AccessibilityProps> {
|
|
19
|
+
'aria-orientation'?: SeparatorOrientation;
|
|
20
|
+
}
|
|
21
|
+
interface SeparatorAPI {
|
|
22
|
+
/** ARIA attributes to spread on the element. */
|
|
23
|
+
ariaProps: SeparatorAriaProps;
|
|
24
|
+
/** Data attributes for CSS styling hooks. */
|
|
25
|
+
dataAttributes: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Headless separator core — computes ARIA semantics and data attributes for
|
|
29
|
+
* a separator rule. JSX-free so it can be shared across framework adapters.
|
|
30
|
+
*
|
|
31
|
+
* Per ARIA, a decorative separator must not be announced (`role="none"`),
|
|
32
|
+
* while a semantic one exposes `role="separator"` and `aria-orientation`.
|
|
33
|
+
*/
|
|
34
|
+
declare function createSeparator(props?: SeparatorProps): SeparatorAPI;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Visual variants for the separator rule.
|
|
38
|
+
*
|
|
39
|
+
* - `orientation: horizontal` → a full-width 1px line.
|
|
40
|
+
* - `orientation: vertical` → a full-height 1px line.
|
|
41
|
+
* - `labeled` → flex layout used by the labeled-divider variant, which
|
|
42
|
+
* arranges a centered label between two flanking lines.
|
|
43
|
+
*/
|
|
44
|
+
declare const separatorVariants: (props?: ({
|
|
45
|
+
orientation?: "horizontal" | "vertical" | undefined;
|
|
46
|
+
labeled?: "true" | "false" | undefined;
|
|
47
|
+
} & {
|
|
48
|
+
className?: string;
|
|
49
|
+
}) | undefined) => string;
|
|
50
|
+
/** Class for each flanking line in the labeled-divider variant. */
|
|
51
|
+
declare const separatorLineClass = "h-px flex-1 bg-border";
|
|
52
|
+
/** Class for the centered label in the labeled-divider variant. */
|
|
53
|
+
declare const separatorLabelClass = "px-3 text-xs uppercase tracking-wide text-muted-foreground";
|
|
54
|
+
|
|
55
|
+
export { type SeparatorAPI, type SeparatorOrientation, type SeparatorProps, createSeparator, separatorLabelClass, separatorLineClass, separatorVariants };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type SocialProvider = 'google' | 'github' | 'microsoft' | 'apple';
|
|
2
|
+
/** "Continue with …" label shown on each provider's button. */
|
|
3
|
+
declare const PROVIDER_LABELS: Record<SocialProvider, string>;
|
|
4
|
+
/**
|
|
5
|
+
* Which providers render their brand mark monochrome (currentColor). GitHub and
|
|
6
|
+
* Apple are monochrome by design so they read correctly on dark/outline
|
|
7
|
+
* surfaces; Google and Microsoft keep their full brand color.
|
|
8
|
+
*/
|
|
9
|
+
declare const PROVIDER_MONO: Record<SocialProvider, boolean>;
|
|
10
|
+
interface SocialAuthButtonProps {
|
|
11
|
+
/** Identity provider this button authenticates against. */
|
|
12
|
+
provider: SocialProvider;
|
|
13
|
+
}
|
|
14
|
+
interface SocialAuthButtonAPI {
|
|
15
|
+
/** Data attributes for CSS styling hooks. */
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
/** "Continue with …" label for the provider. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Whether the brand mark should render monochrome. */
|
|
20
|
+
mono: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Framework-agnostic core for a social sign-in button. Returns the provider
|
|
24
|
+
* label, monochrome hint, and the `data-provider` styling hook. No React/JSX.
|
|
25
|
+
*/
|
|
26
|
+
declare function createSocialAuthButton(props: SocialAuthButtonProps): SocialAuthButtonAPI;
|
|
27
|
+
|
|
28
|
+
/** Wrapper around an individual social auth button (positions the lastUsed badge). */
|
|
29
|
+
declare const socialAuthButtonVariants: (props?: ({
|
|
30
|
+
[x: string]: string | undefined;
|
|
31
|
+
} & {
|
|
32
|
+
className?: string;
|
|
33
|
+
}) | undefined) => string;
|
|
34
|
+
/** Responsive grid wrapper: one column on mobile, two columns from `sm` up. */
|
|
35
|
+
declare const socialAuthRowVariants: (props?: ({
|
|
36
|
+
[x: string]: string | undefined;
|
|
37
|
+
} & {
|
|
38
|
+
className?: string;
|
|
39
|
+
}) | undefined) => string;
|
|
40
|
+
/** Floating "Last used" badge anchored to the top-right of a button. */
|
|
41
|
+
declare const lastUsedBadgeVariants: (props?: ({
|
|
42
|
+
[x: string]: string | undefined;
|
|
43
|
+
} & {
|
|
44
|
+
className?: string;
|
|
45
|
+
}) | undefined) => string;
|
|
46
|
+
|
|
47
|
+
export { PROVIDER_LABELS, PROVIDER_MONO, type SocialAuthButtonAPI, type SocialAuthButtonProps, type SocialProvider, createSocialAuthButton, lastUsedBadgeVariants, socialAuthButtonVariants, socialAuthRowVariants };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type SocialProvider = 'google' | 'github' | 'microsoft' | 'apple';
|
|
2
|
+
/** "Continue with …" label shown on each provider's button. */
|
|
3
|
+
declare const PROVIDER_LABELS: Record<SocialProvider, string>;
|
|
4
|
+
/**
|
|
5
|
+
* Which providers render their brand mark monochrome (currentColor). GitHub and
|
|
6
|
+
* Apple are monochrome by design so they read correctly on dark/outline
|
|
7
|
+
* surfaces; Google and Microsoft keep their full brand color.
|
|
8
|
+
*/
|
|
9
|
+
declare const PROVIDER_MONO: Record<SocialProvider, boolean>;
|
|
10
|
+
interface SocialAuthButtonProps {
|
|
11
|
+
/** Identity provider this button authenticates against. */
|
|
12
|
+
provider: SocialProvider;
|
|
13
|
+
}
|
|
14
|
+
interface SocialAuthButtonAPI {
|
|
15
|
+
/** Data attributes for CSS styling hooks. */
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
/** "Continue with …" label for the provider. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Whether the brand mark should render monochrome. */
|
|
20
|
+
mono: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Framework-agnostic core for a social sign-in button. Returns the provider
|
|
24
|
+
* label, monochrome hint, and the `data-provider` styling hook. No React/JSX.
|
|
25
|
+
*/
|
|
26
|
+
declare function createSocialAuthButton(props: SocialAuthButtonProps): SocialAuthButtonAPI;
|
|
27
|
+
|
|
28
|
+
/** Wrapper around an individual social auth button (positions the lastUsed badge). */
|
|
29
|
+
declare const socialAuthButtonVariants: (props?: ({
|
|
30
|
+
[x: string]: string | undefined;
|
|
31
|
+
} & {
|
|
32
|
+
className?: string;
|
|
33
|
+
}) | undefined) => string;
|
|
34
|
+
/** Responsive grid wrapper: one column on mobile, two columns from `sm` up. */
|
|
35
|
+
declare const socialAuthRowVariants: (props?: ({
|
|
36
|
+
[x: string]: string | undefined;
|
|
37
|
+
} & {
|
|
38
|
+
className?: string;
|
|
39
|
+
}) | undefined) => string;
|
|
40
|
+
/** Floating "Last used" badge anchored to the top-right of a button. */
|
|
41
|
+
declare const lastUsedBadgeVariants: (props?: ({
|
|
42
|
+
[x: string]: string | undefined;
|
|
43
|
+
} & {
|
|
44
|
+
className?: string;
|
|
45
|
+
}) | undefined) => string;
|
|
46
|
+
|
|
47
|
+
export { PROVIDER_LABELS, PROVIDER_MONO, type SocialAuthButtonAPI, type SocialAuthButtonProps, type SocialProvider, createSocialAuthButton, lastUsedBadgeVariants, socialAuthButtonVariants, socialAuthRowVariants };
|
|
@@ -43,7 +43,41 @@ declare function createTheme(config?: ThemeConfig, storage?: StorageAdapter, med
|
|
|
43
43
|
* Inject this as a <script> tag in the <head> before any CSS.
|
|
44
44
|
* Works with any framework (React, Astro, plain HTML).
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
interface ThemeScriptOptions {
|
|
48
|
+
/** localStorage key the corresponding ThemeProvider reads. */
|
|
49
|
+
storageKey?: string;
|
|
50
|
+
/** Attribute strategy: 'class' toggles `light`/`dark` classes; otherwise an HTML attribute. */
|
|
51
|
+
attribute?: 'class' | 'data-theme';
|
|
52
|
+
/**
|
|
53
|
+
* Theme to apply when nothing is stored AND `enableSystem` is false
|
|
54
|
+
* (or `defaultMode` is explicitly 'light'/'dark'). Match this to your
|
|
55
|
+
* ThemeProvider's `defaultMode` so the pre-paint script and provider agree.
|
|
56
|
+
* Defaults to `'system'` — current behavior, OS preference wins.
|
|
57
|
+
*
|
|
58
|
+
* Issue #317.
|
|
59
|
+
*/
|
|
60
|
+
defaultMode?: ThemeMode;
|
|
61
|
+
/**
|
|
62
|
+
* When `true` (default) and `defaultMode === 'system'`, the script falls
|
|
63
|
+
* through to `prefers-color-scheme`. When `false`, the script applies
|
|
64
|
+
* `defaultMode` directly and never reads the OS preference.
|
|
65
|
+
*/
|
|
66
|
+
enableSystem?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build the pre-paint inline script. Mirrors the resolution order used by
|
|
70
|
+
* the React/Astro `ThemeProvider`:
|
|
71
|
+
*
|
|
72
|
+
* 1. stored value (light|dark|system)
|
|
73
|
+
* 2. if no stored value: `defaultMode` (light|dark applied as-is)
|
|
74
|
+
* 3. if stored or default is 'system' AND `enableSystem`: matchMedia
|
|
75
|
+
* 4. else: 'light'
|
|
76
|
+
*
|
|
77
|
+
* Back-compat: with no options the script behaves exactly as before —
|
|
78
|
+
* stored value, then matchMedia, then 'light'.
|
|
79
|
+
*/
|
|
80
|
+
declare function getThemeScript(storageKeyOrOptions?: string | ThemeScriptOptions, attribute?: 'class' | 'data-theme'): string;
|
|
47
81
|
|
|
48
82
|
/**
|
|
49
83
|
* Browser DOM adapters for the theme machine.
|
|
@@ -43,7 +43,41 @@ declare function createTheme(config?: ThemeConfig, storage?: StorageAdapter, med
|
|
|
43
43
|
* Inject this as a <script> tag in the <head> before any CSS.
|
|
44
44
|
* Works with any framework (React, Astro, plain HTML).
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
interface ThemeScriptOptions {
|
|
48
|
+
/** localStorage key the corresponding ThemeProvider reads. */
|
|
49
|
+
storageKey?: string;
|
|
50
|
+
/** Attribute strategy: 'class' toggles `light`/`dark` classes; otherwise an HTML attribute. */
|
|
51
|
+
attribute?: 'class' | 'data-theme';
|
|
52
|
+
/**
|
|
53
|
+
* Theme to apply when nothing is stored AND `enableSystem` is false
|
|
54
|
+
* (or `defaultMode` is explicitly 'light'/'dark'). Match this to your
|
|
55
|
+
* ThemeProvider's `defaultMode` so the pre-paint script and provider agree.
|
|
56
|
+
* Defaults to `'system'` — current behavior, OS preference wins.
|
|
57
|
+
*
|
|
58
|
+
* Issue #317.
|
|
59
|
+
*/
|
|
60
|
+
defaultMode?: ThemeMode;
|
|
61
|
+
/**
|
|
62
|
+
* When `true` (default) and `defaultMode === 'system'`, the script falls
|
|
63
|
+
* through to `prefers-color-scheme`. When `false`, the script applies
|
|
64
|
+
* `defaultMode` directly and never reads the OS preference.
|
|
65
|
+
*/
|
|
66
|
+
enableSystem?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build the pre-paint inline script. Mirrors the resolution order used by
|
|
70
|
+
* the React/Astro `ThemeProvider`:
|
|
71
|
+
*
|
|
72
|
+
* 1. stored value (light|dark|system)
|
|
73
|
+
* 2. if no stored value: `defaultMode` (light|dark applied as-is)
|
|
74
|
+
* 3. if stored or default is 'system' AND `enableSystem`: matchMedia
|
|
75
|
+
* 4. else: 'light'
|
|
76
|
+
*
|
|
77
|
+
* Back-compat: with no options the script behaves exactly as before —
|
|
78
|
+
* stored value, then matchMedia, then 'light'.
|
|
79
|
+
*/
|
|
80
|
+
declare function getThemeScript(storageKeyOrOptions?: string | ThemeScriptOptions, attribute?: 'class' | 'data-theme'): string;
|
|
47
81
|
|
|
48
82
|
/**
|
|
49
83
|
* Browser DOM adapters for the theme machine.
|
package/dist/theme.cjs
CHANGED
|
@@ -90,8 +90,29 @@ function createTheme(config = {}, storage, mediaQuery) {
|
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
-
function getThemeScript(
|
|
94
|
-
|
|
93
|
+
function getThemeScript(storageKeyOrOptions = "rfr-theme", attribute = "class") {
|
|
94
|
+
const opts = typeof storageKeyOrOptions === "string" ? {
|
|
95
|
+
storageKey: storageKeyOrOptions,
|
|
96
|
+
attribute,
|
|
97
|
+
defaultMode: "system",
|
|
98
|
+
enableSystem: true
|
|
99
|
+
} : {
|
|
100
|
+
storageKey: storageKeyOrOptions.storageKey ?? "rfr-theme",
|
|
101
|
+
attribute: storageKeyOrOptions.attribute ?? "class",
|
|
102
|
+
defaultMode: storageKeyOrOptions.defaultMode ?? "system",
|
|
103
|
+
enableSystem: storageKeyOrOptions.enableSystem ?? true
|
|
104
|
+
};
|
|
105
|
+
const noSystemFallback = opts.defaultMode === "light" || opts.defaultMode === "dark" || !opts.enableSystem;
|
|
106
|
+
const safeDefault = opts.defaultMode === "dark" ? "dark" : "light";
|
|
107
|
+
const resolveExpr = noSystemFallback ? (
|
|
108
|
+
// Stored wins → else hard default. No matchMedia call at all.
|
|
109
|
+
`var t=m==='dark'?'dark':(m==='light'?'light':'${safeDefault}');`
|
|
110
|
+
) : (
|
|
111
|
+
// Original behaviour: stored → else matchMedia → else light.
|
|
112
|
+
`var s=window.matchMedia('(prefers-color-scheme:dark)').matches;var t=m==='dark'||(m!=='light'&&s)?'dark':'light';`
|
|
113
|
+
);
|
|
114
|
+
const applyExpr = opts.attribute === "class" ? "d.classList.remove('light','dark');d.classList.add(t);" : `d.setAttribute('${opts.attribute}',t);`;
|
|
115
|
+
return `(function(){try{var m=localStorage.getItem('${opts.storageKey}');${resolveExpr}var d=document.documentElement;${applyExpr}d.style.colorScheme=t;}catch(e){}})()`;
|
|
95
116
|
}
|
|
96
117
|
function createLocalStorageAdapter() {
|
|
97
118
|
return {
|
|
@@ -330,11 +351,13 @@ function ThemeToggle({ className, variant = "segmented" }) {
|
|
|
330
351
|
}
|
|
331
352
|
function ThemeScript({
|
|
332
353
|
storageKey = "rfr-theme",
|
|
333
|
-
attribute = "class"
|
|
354
|
+
attribute = "class",
|
|
355
|
+
defaultMode = "system",
|
|
356
|
+
enableSystem = true
|
|
334
357
|
}) {
|
|
335
358
|
return React2__namespace.createElement("script", {
|
|
336
359
|
dangerouslySetInnerHTML: {
|
|
337
|
-
__html: getThemeScript(storageKey, attribute)
|
|
360
|
+
__html: getThemeScript({ storageKey, attribute, defaultMode, enableSystem })
|
|
338
361
|
}
|
|
339
362
|
});
|
|
340
363
|
}
|