@particle-network/ui-react 0.4.5-beta.2 → 0.4.5-beta.21
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/UXButton/button-theme.d.ts +3 -0
- package/dist/components/UXButton/button-theme.js +36 -9
- package/dist/components/UXButton/use-button.js +2 -1
- package/dist/components/UXChip/chip.extend.d.ts +1 -1
- package/dist/components/UXChip/chip.extend.js +17 -2
- package/dist/components/UXChip/index.d.ts +1 -1
- package/dist/components/UXInput/index.d.ts +2 -0
- package/dist/components/UXInput/input.extend.d.ts +2 -0
- package/dist/components/UXModal/index.js +2 -5
- package/dist/components/UXNumberInput/number-input.extend.d.ts +1 -0
- package/dist/components/UXSlider/index.d.ts +5 -0
- package/dist/components/UXSlider/index.js +3 -0
- package/dist/components/UXSlider/slider-theme.d.ts +521 -0
- package/dist/components/UXSlider/slider-theme.js +464 -0
- package/dist/components/UXSlider/slider-thumb.d.ts +4 -0
- package/dist/components/UXSlider/slider-thumb.js +33 -0
- package/dist/components/UXSlider/slider.d.ts +4 -0
- package/dist/components/UXSlider/slider.js +77 -0
- package/dist/components/UXSlider/use-slider-thumb.d.ts +61 -0
- package/dist/components/UXSlider/use-slider-thumb.js +79 -0
- package/dist/components/UXSlider/use-slider.d.ts +182 -0
- package/dist/components/UXSlider/use-slider.js +277 -0
- package/dist/components/UXTabSwitch/index.d.ts +2 -0
- package/dist/components/UXTabSwitch/index.js +3 -1
- package/dist/components/UXTabs/tabs.classes.js +4 -4
- package/dist/components/UXThemeSwitch/theme-switch.d.ts +4 -2
- package/dist/components/UXThemeSwitch/theme-switch.js +11 -8
- package/dist/components/UXToast/index.js +2 -2
- package/dist/components/UXTooltip/index.d.ts +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/utils/classes.d.ts +11 -0
- package/dist/utils/classes.js +12 -1
- package/dist/utils/input-classes.d.ts +37 -2
- package/dist/utils/input-classes.js +65 -6
- package/package.json +5 -5
- package/tailwind-preset.js +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { useDOMRef } from "@heroui/react-utils";
|
|
3
|
+
import { dataAttr, mergeProps } from "@heroui/shared-utils";
|
|
4
|
+
import { useFocusRing } from "@react-aria/focus";
|
|
5
|
+
import { useNumberFormatter } from "@react-aria/i18n";
|
|
6
|
+
import { useHover, usePress } from "@react-aria/interactions";
|
|
7
|
+
import { useSliderThumb } from "@react-aria/slider";
|
|
8
|
+
import { bgWithTextColorClasses } from "../../utils/classes.js";
|
|
9
|
+
function use_slider_thumb_useSliderThumb(props) {
|
|
10
|
+
const { ref, as, state, index, name, trackRef, className, tooltipProps, isVertical, showTooltip, getTooltipValue, formatOptions, renderThumb, ...otherProps } = props;
|
|
11
|
+
const Component = as || 'div';
|
|
12
|
+
const domRef = useDOMRef(ref);
|
|
13
|
+
const inputRef = useRef(null);
|
|
14
|
+
const numberFormatter = useNumberFormatter(formatOptions);
|
|
15
|
+
const { thumbProps, inputProps, isDragging, isFocused } = useSliderThumb({
|
|
16
|
+
index,
|
|
17
|
+
trackRef,
|
|
18
|
+
inputRef,
|
|
19
|
+
name,
|
|
20
|
+
...otherProps
|
|
21
|
+
}, state);
|
|
22
|
+
const { hoverProps, isHovered } = useHover({
|
|
23
|
+
isDisabled: state.isDisabled
|
|
24
|
+
});
|
|
25
|
+
const { focusProps, isFocusVisible } = useFocusRing();
|
|
26
|
+
const { pressProps, isPressed } = usePress({
|
|
27
|
+
isDisabled: state.isDisabled
|
|
28
|
+
});
|
|
29
|
+
const getThumbProps = (props = {})=>({
|
|
30
|
+
ref: domRef,
|
|
31
|
+
'data-slot': 'thumb',
|
|
32
|
+
'data-hover': dataAttr(isHovered),
|
|
33
|
+
'data-pressed': dataAttr(isPressed),
|
|
34
|
+
'data-dragging': dataAttr(isDragging),
|
|
35
|
+
'data-focused': dataAttr(isFocused),
|
|
36
|
+
'data-focus-visible': dataAttr(isFocusVisible),
|
|
37
|
+
'aria-label': props['aria-label'] || `Slider thumb ${void 0 !== index ? `${index + 1}` : ''}`,
|
|
38
|
+
...mergeProps(thumbProps, pressProps, hoverProps, otherProps),
|
|
39
|
+
className,
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
const getTooltipProps = ()=>{
|
|
43
|
+
const stateValue = tooltipProps?.content ? tooltipProps.content : getTooltipValue ? 1 === state.values.length ? getTooltipValue(state.values[index ?? 0]) : getTooltipValue(state.values, index ?? 0) : state.values[index ?? 0];
|
|
44
|
+
const value = numberFormatter && 'number' == typeof stateValue ? numberFormatter.format(stateValue) : stateValue;
|
|
45
|
+
return {
|
|
46
|
+
...tooltipProps,
|
|
47
|
+
placement: tooltipProps?.placement ? tooltipProps?.placement : isVertical ? 'right' : 'top',
|
|
48
|
+
content: tooltipProps?.content ? tooltipProps?.content : value,
|
|
49
|
+
updatePositionDeps: [
|
|
50
|
+
isDragging,
|
|
51
|
+
isHovered,
|
|
52
|
+
isFocused,
|
|
53
|
+
isFocusVisible,
|
|
54
|
+
value
|
|
55
|
+
],
|
|
56
|
+
isOpen: tooltipProps?.isOpen !== void 0 ? tooltipProps?.isOpen : isHovered || isDragging || isFocused || isFocusVisible,
|
|
57
|
+
role: 'tooltip',
|
|
58
|
+
'aria-label': `Current value: ${value}`,
|
|
59
|
+
classNames: {
|
|
60
|
+
content: bgWithTextColorClasses[tooltipProps?.color]
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
const getInputProps = (props = {})=>({
|
|
65
|
+
ref: inputRef,
|
|
66
|
+
...mergeProps(inputProps, focusProps),
|
|
67
|
+
...props
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
Component,
|
|
71
|
+
index,
|
|
72
|
+
showTooltip,
|
|
73
|
+
renderThumb,
|
|
74
|
+
getThumbProps,
|
|
75
|
+
getTooltipProps,
|
|
76
|
+
getInputProps
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export { use_slider_thumb_useSliderThumb as useSliderThumb };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { ReactRef } from '@heroui/react-utils';
|
|
4
|
+
import type { DOMAttributes, HTMLHeroUIProps, PropGetter } from '@heroui/system';
|
|
5
|
+
import type { SliderSlots, SliderVariantProps, SlotsToClasses } from '@heroui/theme';
|
|
6
|
+
import type { TooltipProps } from '@heroui/tooltip';
|
|
7
|
+
import type { AriaSliderProps } from '@react-aria/slider';
|
|
8
|
+
import type { ValueBase } from '@react-types/shared';
|
|
9
|
+
import type { SliderThumbProps } from './slider-thumb';
|
|
10
|
+
export type SliderValue = number | number[];
|
|
11
|
+
export interface SliderStepMark {
|
|
12
|
+
value: number;
|
|
13
|
+
label: string;
|
|
14
|
+
}
|
|
15
|
+
export type SliderRenderThumbProps = DOMAttributes<HTMLDivElement> & {
|
|
16
|
+
index?: number;
|
|
17
|
+
};
|
|
18
|
+
interface Props extends HTMLHeroUIProps {
|
|
19
|
+
/**
|
|
20
|
+
* Ref to the DOM node.
|
|
21
|
+
*/
|
|
22
|
+
ref?: ReactRef<HTMLElement | null>;
|
|
23
|
+
/**
|
|
24
|
+
* The content to display as the label.
|
|
25
|
+
*/
|
|
26
|
+
label?: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* The input name.
|
|
29
|
+
*/
|
|
30
|
+
name?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The offset from which to start the fill.
|
|
33
|
+
*/
|
|
34
|
+
fillOffset?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The display format of the value label.
|
|
37
|
+
*/
|
|
38
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
39
|
+
/**
|
|
40
|
+
* The display format of the tooltip value label.
|
|
41
|
+
* @default formatOptions
|
|
42
|
+
*/
|
|
43
|
+
tooltipValueFormatOptions?: Intl.NumberFormatOptions;
|
|
44
|
+
/**
|
|
45
|
+
* Whether to show the step indicators.
|
|
46
|
+
* @default false
|
|
47
|
+
*/
|
|
48
|
+
showSteps?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to show step indicators at mark positions.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
showMarksSteps?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the thumbs should have a tooltip with the value on hover the slider.
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
showTooltip?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Custom steps labels.
|
|
61
|
+
* @example [{value: 0, label: "0"}, {value: 50, label: "50"}, {value: 100, label: "100"}]
|
|
62
|
+
* @default []
|
|
63
|
+
*/
|
|
64
|
+
marks?: SliderStepMark[];
|
|
65
|
+
/**
|
|
66
|
+
* Element to be rendered in the start side of the slider.
|
|
67
|
+
*/
|
|
68
|
+
startContent?: React.ReactNode;
|
|
69
|
+
/**
|
|
70
|
+
* Element to be rendered in the end side of the slider.
|
|
71
|
+
*/
|
|
72
|
+
endContent?: React.ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Classname or List of classes to change the classNames of the element.
|
|
75
|
+
* if `className` is passed, it will be added to the base slot.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* <Slider classNames={{
|
|
80
|
+
* base:"base-classes",
|
|
81
|
+
* step: "step-classes",
|
|
82
|
+
* labelWrapper: "label-wrapper-classes",
|
|
83
|
+
* label: "label-classes",
|
|
84
|
+
* value: "value-classes",
|
|
85
|
+
* trackWrapper: "track-wrapper-classes",
|
|
86
|
+
* track: "track-classes",
|
|
87
|
+
* filler: "filler-classes",
|
|
88
|
+
* thumb: "thumb-classes",
|
|
89
|
+
* mark: "mark-classes",
|
|
90
|
+
* }} />
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
classNames?: SlotsToClasses<SliderSlots>;
|
|
94
|
+
/**
|
|
95
|
+
* Tooltip props.
|
|
96
|
+
* @see [Tooltip](https://heroui.com/components/tooltip) for more details.
|
|
97
|
+
* @default {
|
|
98
|
+
* offset: 15,
|
|
99
|
+
* delay: 0,
|
|
100
|
+
* size: "sm",
|
|
101
|
+
* showArrow: true,
|
|
102
|
+
* placement: "top", // "right" for vertical slider
|
|
103
|
+
* content: [sliderValue],
|
|
104
|
+
* color: sliderProps?.color, // same as the slider color
|
|
105
|
+
* isDisabled: sliderProps?.isDisabled,
|
|
106
|
+
* }
|
|
107
|
+
*/
|
|
108
|
+
tooltipProps?: Partial<TooltipProps>;
|
|
109
|
+
/**
|
|
110
|
+
* A function that returns the content to display as the value label.
|
|
111
|
+
* Overrides default formatted number.
|
|
112
|
+
*/
|
|
113
|
+
getValue?: (value: SliderValue) => string;
|
|
114
|
+
/**
|
|
115
|
+
* A function that returns the content to display as the tooltip label. (in analogy to getValue)
|
|
116
|
+
* @param value - The value of the slider, array or single number.
|
|
117
|
+
* @param index - The index of the thumb, if multiple thumbs are used.
|
|
118
|
+
* In addition to formatting with tooltipValueFormatOptions if number is returned.
|
|
119
|
+
*/
|
|
120
|
+
getTooltipValue?: (value: SliderValue, index?: number) => string | number;
|
|
121
|
+
/**
|
|
122
|
+
* Function to render the label.
|
|
123
|
+
*/
|
|
124
|
+
renderLabel?: (props: DOMAttributes<HTMLLabelElement>) => React.ReactNode;
|
|
125
|
+
/**
|
|
126
|
+
* Function to render the value label.
|
|
127
|
+
*/
|
|
128
|
+
renderValue?: (props: DOMAttributes<HTMLOutputElement>) => React.ReactNode;
|
|
129
|
+
/**
|
|
130
|
+
* Function to render the thumb. It can be used to add a tooltip or custom icon.
|
|
131
|
+
*/
|
|
132
|
+
renderThumb?: (props: SliderRenderThumbProps) => React.ReactNode;
|
|
133
|
+
}
|
|
134
|
+
export type UseSliderProps = Omit<Props, keyof ValueBase<SliderValue>> & AriaSliderProps & SliderVariantProps;
|
|
135
|
+
export declare function useSlider(originalProps: UseSliderProps): {
|
|
136
|
+
Component: import("@heroui/system-rsc").As<any>;
|
|
137
|
+
state: import("@react-stately/slider").SliderState;
|
|
138
|
+
value: any;
|
|
139
|
+
domRef: React.RefObject<HTMLElement>;
|
|
140
|
+
label: React.ReactNode;
|
|
141
|
+
steps: number;
|
|
142
|
+
marks: SliderStepMark[];
|
|
143
|
+
startContent: React.ReactNode;
|
|
144
|
+
endContent: React.ReactNode;
|
|
145
|
+
showMarksSteps: boolean;
|
|
146
|
+
minValue: number;
|
|
147
|
+
step: number;
|
|
148
|
+
getStepProps: (index: number) => {
|
|
149
|
+
className: string;
|
|
150
|
+
'data-slot': string;
|
|
151
|
+
'data-in-range': boolean;
|
|
152
|
+
style: {
|
|
153
|
+
[x: string]: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
getBaseProps: PropGetter;
|
|
157
|
+
getValue: ((value: SliderValue) => string) | undefined;
|
|
158
|
+
renderLabel: ((props: DOMAttributes<HTMLLabelElement>) => React.ReactNode) | undefined;
|
|
159
|
+
renderValue: ((props: DOMAttributes<HTMLOutputElement>) => React.ReactNode) | undefined;
|
|
160
|
+
getTrackWrapperProps: PropGetter;
|
|
161
|
+
getLabelWrapperProps: PropGetter;
|
|
162
|
+
getLabelProps: PropGetter;
|
|
163
|
+
getValueProps: PropGetter;
|
|
164
|
+
getTrackProps: PropGetter;
|
|
165
|
+
getFillerProps: PropGetter;
|
|
166
|
+
getThumbProps: (index: number) => SliderThumbProps;
|
|
167
|
+
getMarkProps: (mark: SliderStepMark) => {
|
|
168
|
+
className: string;
|
|
169
|
+
'data-slot': string;
|
|
170
|
+
'data-in-range': boolean;
|
|
171
|
+
style: {
|
|
172
|
+
[x: string]: string;
|
|
173
|
+
};
|
|
174
|
+
onMouseDown: (e: React.MouseEvent) => void;
|
|
175
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
176
|
+
onClick: (e: any) => void;
|
|
177
|
+
};
|
|
178
|
+
getStartContentProps: PropGetter;
|
|
179
|
+
getEndContentProps: PropGetter;
|
|
180
|
+
};
|
|
181
|
+
export type UseSliderReturn = ReturnType<typeof useSlider>;
|
|
182
|
+
export {};
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { useCallback, useMemo, useRef } from "react";
|
|
2
|
+
import { filterDOMProps, useDOMRef } from "@heroui/react-utils";
|
|
3
|
+
import { mergeProps, objectToDeps, warn } from "@heroui/shared-utils";
|
|
4
|
+
import { mapPropsVariants, useProviderContext } from "@heroui/system";
|
|
5
|
+
import { cn } from "@heroui/theme";
|
|
6
|
+
import { useLocale, useNumberFormatter } from "@react-aria/i18n";
|
|
7
|
+
import { useHover } from "@react-aria/interactions";
|
|
8
|
+
import { useSlider } from "@react-aria/slider";
|
|
9
|
+
import { useSliderState } from "@react-stately/slider";
|
|
10
|
+
import { slider } from "./slider-theme.js";
|
|
11
|
+
function use_slider_useSlider(originalProps) {
|
|
12
|
+
const globalContext = useProviderContext();
|
|
13
|
+
const [props, variantProps] = mapPropsVariants(originalProps, slider.variantKeys);
|
|
14
|
+
const { ref, as, name, label, formatOptions, value: valueProp, maxValue = 100, minValue = 0, step = 1, showSteps = false, showMarksSteps = false, showTooltip = false, orientation = 'horizontal', marks = [], startContent, endContent, fillOffset, className, classNames, renderThumb, renderLabel, renderValue, onChange, onChangeEnd, getValue, getTooltipValue, tooltipValueFormatOptions = formatOptions, tooltipProps: userTooltipProps = {}, ...otherProps } = props;
|
|
15
|
+
const isFixedValue = minValue === maxValue;
|
|
16
|
+
if (isFixedValue) warn('Min and max values should not be the same. This may cause unexpected behavior.');
|
|
17
|
+
const Component = as || 'div';
|
|
18
|
+
const shouldFilterDOMProps = 'string' == typeof Component;
|
|
19
|
+
const disableAnimation = originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
|
|
20
|
+
const domRef = useDOMRef(ref);
|
|
21
|
+
const trackRef = useRef(null);
|
|
22
|
+
const numberFormatter = useNumberFormatter(formatOptions);
|
|
23
|
+
const { direction } = useLocale();
|
|
24
|
+
const clampValue = useCallback((valueToClamp)=>Math.min(Math.max(valueToClamp, minValue), maxValue), [
|
|
25
|
+
minValue,
|
|
26
|
+
maxValue
|
|
27
|
+
]);
|
|
28
|
+
const validatedValue = useMemo(()=>{
|
|
29
|
+
if (isFixedValue) return minValue;
|
|
30
|
+
if (void 0 === valueProp) return;
|
|
31
|
+
if (Array.isArray(valueProp)) return valueProp.map(clampValue);
|
|
32
|
+
return clampValue(valueProp);
|
|
33
|
+
}, [
|
|
34
|
+
valueProp,
|
|
35
|
+
clampValue,
|
|
36
|
+
isFixedValue,
|
|
37
|
+
minValue
|
|
38
|
+
]);
|
|
39
|
+
const handleValueChange = useCallback((value)=>{
|
|
40
|
+
onChangeEnd?.(value);
|
|
41
|
+
setTimeout(()=>{
|
|
42
|
+
if (document.activeElement) document.activeElement.blur();
|
|
43
|
+
}, 500);
|
|
44
|
+
}, [
|
|
45
|
+
onChangeEnd
|
|
46
|
+
]);
|
|
47
|
+
const state = useSliderState({
|
|
48
|
+
...otherProps,
|
|
49
|
+
value: validatedValue,
|
|
50
|
+
isDisabled: originalProps?.isDisabled ?? false,
|
|
51
|
+
orientation,
|
|
52
|
+
step,
|
|
53
|
+
minValue,
|
|
54
|
+
maxValue,
|
|
55
|
+
numberFormatter,
|
|
56
|
+
onChange,
|
|
57
|
+
onChangeEnd: handleValueChange
|
|
58
|
+
});
|
|
59
|
+
const tooltipProps = {
|
|
60
|
+
offset: 5,
|
|
61
|
+
delay: 0,
|
|
62
|
+
size: 'sm',
|
|
63
|
+
showArrow: true,
|
|
64
|
+
color: originalProps?.color ? originalProps?.color : slider.defaultVariants?.color,
|
|
65
|
+
isDisabled: originalProps.isDisabled,
|
|
66
|
+
...userTooltipProps
|
|
67
|
+
};
|
|
68
|
+
const { groupProps, trackProps, labelProps, outputProps } = useSlider(originalProps, state, trackRef);
|
|
69
|
+
const { isHovered, hoverProps } = useHover({
|
|
70
|
+
isDisabled: originalProps.isDisabled
|
|
71
|
+
});
|
|
72
|
+
const baseStyles = cn(classNames?.base, className);
|
|
73
|
+
const isVertical = 'vertical' === orientation;
|
|
74
|
+
const hasMarks = marks?.length > 0;
|
|
75
|
+
const hasSingleThumb = void 0 === fillOffset ? 1 === state.values.length : false;
|
|
76
|
+
const slots = useMemo(()=>slider({
|
|
77
|
+
...variantProps,
|
|
78
|
+
hasMarks,
|
|
79
|
+
disableAnimation,
|
|
80
|
+
hasSingleThumb,
|
|
81
|
+
isVertical
|
|
82
|
+
}), [
|
|
83
|
+
objectToDeps(variantProps),
|
|
84
|
+
isVertical,
|
|
85
|
+
disableAnimation,
|
|
86
|
+
hasSingleThumb,
|
|
87
|
+
hasMarks
|
|
88
|
+
]);
|
|
89
|
+
const [startOffset, endOffset] = [
|
|
90
|
+
state.values.length > 1 ? state.getThumbPercent(0) : void 0 !== fillOffset ? state.getValuePercent(fillOffset) : 0,
|
|
91
|
+
state.getThumbPercent(state.values.length - 1)
|
|
92
|
+
].sort();
|
|
93
|
+
const value = 1 === state.values.length ? numberFormatter.format(state.values[0]) : numberFormatter.formatRange(state.values[0], state.values[state.values.length - 1]);
|
|
94
|
+
const steps = showSteps ? Math.floor((maxValue - minValue) / step) + 1 : 0;
|
|
95
|
+
const getBaseProps = (props = {})=>({
|
|
96
|
+
ref: domRef,
|
|
97
|
+
'data-orientation': state.orientation,
|
|
98
|
+
'data-slot': 'base',
|
|
99
|
+
'data-hover': isHovered,
|
|
100
|
+
className: slots.base({
|
|
101
|
+
class: baseStyles
|
|
102
|
+
}),
|
|
103
|
+
...mergeProps(groupProps, hoverProps, filterDOMProps(otherProps, {
|
|
104
|
+
enabled: shouldFilterDOMProps
|
|
105
|
+
}), filterDOMProps(props))
|
|
106
|
+
});
|
|
107
|
+
const getLabelWrapperProps = (props = {})=>({
|
|
108
|
+
className: slots.labelWrapper({
|
|
109
|
+
class: classNames?.labelWrapper
|
|
110
|
+
}),
|
|
111
|
+
'data-slot': 'labelWrapper',
|
|
112
|
+
...props
|
|
113
|
+
});
|
|
114
|
+
const getLabelProps = (props = {})=>({
|
|
115
|
+
'data-slot': 'label',
|
|
116
|
+
className: slots.label({
|
|
117
|
+
class: classNames?.label
|
|
118
|
+
}),
|
|
119
|
+
children: label,
|
|
120
|
+
...labelProps,
|
|
121
|
+
...props
|
|
122
|
+
});
|
|
123
|
+
const getValueProps = (props = {})=>({
|
|
124
|
+
'data-slot': 'value',
|
|
125
|
+
className: slots.value({
|
|
126
|
+
class: classNames?.value
|
|
127
|
+
}),
|
|
128
|
+
children: getValue && 'function' == typeof getValue ? getValue(state.values) : value,
|
|
129
|
+
...outputProps,
|
|
130
|
+
...props
|
|
131
|
+
});
|
|
132
|
+
const getTrackProps = (props = {})=>{
|
|
133
|
+
const fillWidth = (endOffset - startOffset) * 100;
|
|
134
|
+
return {
|
|
135
|
+
ref: trackRef,
|
|
136
|
+
'data-slot': 'track',
|
|
137
|
+
'data-thumb-hidden': !!originalProps?.hideThumb,
|
|
138
|
+
'data-vertical': isVertical,
|
|
139
|
+
...hasSingleThumb ? {
|
|
140
|
+
'data-fill-start': fillWidth > 0,
|
|
141
|
+
'data-fill-end': 100 === fillWidth
|
|
142
|
+
} : {
|
|
143
|
+
'data-fill-start': 0 === startOffset,
|
|
144
|
+
'data-fill-end': 100 * startOffset + fillWidth === 100
|
|
145
|
+
},
|
|
146
|
+
className: slots.track({
|
|
147
|
+
class: classNames?.track
|
|
148
|
+
}),
|
|
149
|
+
...trackProps,
|
|
150
|
+
...props
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
const getTrackWrapperProps = (props = {})=>({
|
|
154
|
+
'data-slot': 'track-wrapper',
|
|
155
|
+
className: slots.trackWrapper({
|
|
156
|
+
class: classNames?.trackWrapper
|
|
157
|
+
}),
|
|
158
|
+
...props
|
|
159
|
+
});
|
|
160
|
+
const getFillerProps = (props = {})=>({
|
|
161
|
+
'data-slot': 'filler',
|
|
162
|
+
className: slots.filler({
|
|
163
|
+
class: classNames?.filler
|
|
164
|
+
}),
|
|
165
|
+
...props,
|
|
166
|
+
style: {
|
|
167
|
+
...props.style,
|
|
168
|
+
[isVertical ? 'bottom' : 'rtl' === direction ? 'right' : 'left']: `${100 * startOffset}%`,
|
|
169
|
+
...isVertical ? {
|
|
170
|
+
height: `${(endOffset - startOffset) * 100}%`
|
|
171
|
+
} : {
|
|
172
|
+
width: `${(endOffset - startOffset) * 100}%`
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
const getThumbProps = (index)=>({
|
|
177
|
+
name,
|
|
178
|
+
index,
|
|
179
|
+
state,
|
|
180
|
+
trackRef,
|
|
181
|
+
orientation,
|
|
182
|
+
isVertical,
|
|
183
|
+
tooltipProps,
|
|
184
|
+
getTooltipValue,
|
|
185
|
+
showTooltip,
|
|
186
|
+
renderThumb,
|
|
187
|
+
formatOptions: tooltipValueFormatOptions,
|
|
188
|
+
className: slots.thumb({
|
|
189
|
+
class: classNames?.thumb
|
|
190
|
+
})
|
|
191
|
+
});
|
|
192
|
+
const getStepProps = (index)=>{
|
|
193
|
+
const percent = state.getValuePercent(index * step + minValue);
|
|
194
|
+
return {
|
|
195
|
+
className: slots.step({
|
|
196
|
+
class: classNames?.step
|
|
197
|
+
}),
|
|
198
|
+
'data-slot': 'step',
|
|
199
|
+
'data-in-range': percent <= endOffset && percent >= startOffset,
|
|
200
|
+
style: {
|
|
201
|
+
[isVertical ? 'bottom' : 'rtl' === direction ? 'right' : 'left']: `${100 * percent}%`
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
const getMarkProps = (mark)=>{
|
|
206
|
+
const percent = state.getValuePercent(mark.value);
|
|
207
|
+
return {
|
|
208
|
+
className: slots.mark({
|
|
209
|
+
class: classNames?.mark
|
|
210
|
+
}),
|
|
211
|
+
'data-slot': 'mark',
|
|
212
|
+
'data-in-range': percent <= endOffset && percent >= startOffset,
|
|
213
|
+
style: {
|
|
214
|
+
[isVertical ? 'bottom' : 'rtl' === direction ? 'right' : 'left']: `${100 * percent}%`
|
|
215
|
+
},
|
|
216
|
+
onMouseDown: (e)=>e.stopPropagation(),
|
|
217
|
+
onPointerDown: (e)=>e.stopPropagation(),
|
|
218
|
+
onClick: (e)=>{
|
|
219
|
+
e.stopPropagation();
|
|
220
|
+
if (isFixedValue) return;
|
|
221
|
+
if (1 === state.values.length) state.setThumbPercent(0, percent);
|
|
222
|
+
else {
|
|
223
|
+
const leftThumbVal = state.values[0];
|
|
224
|
+
const rightThumbVal = state.values[1];
|
|
225
|
+
if (mark.value < leftThumbVal) state.setThumbPercent(0, percent);
|
|
226
|
+
else if (mark.value > rightThumbVal) state.setThumbPercent(1, percent);
|
|
227
|
+
else if (Math.abs(mark.value - leftThumbVal) < Math.abs(mark.value - rightThumbVal)) state.setThumbPercent(0, percent);
|
|
228
|
+
else state.setThumbPercent(1, percent);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
const getStartContentProps = (props = {})=>({
|
|
234
|
+
'data-slot': 'startContent',
|
|
235
|
+
className: slots.startContent({
|
|
236
|
+
class: classNames?.startContent
|
|
237
|
+
}),
|
|
238
|
+
...props
|
|
239
|
+
});
|
|
240
|
+
const getEndContentProps = (props = {})=>({
|
|
241
|
+
'data-slot': 'endContent',
|
|
242
|
+
className: slots.endContent({
|
|
243
|
+
class: classNames?.endContent
|
|
244
|
+
}),
|
|
245
|
+
...props
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
Component,
|
|
249
|
+
state,
|
|
250
|
+
value,
|
|
251
|
+
domRef,
|
|
252
|
+
label,
|
|
253
|
+
steps,
|
|
254
|
+
marks,
|
|
255
|
+
startContent,
|
|
256
|
+
endContent,
|
|
257
|
+
showMarksSteps,
|
|
258
|
+
minValue,
|
|
259
|
+
step,
|
|
260
|
+
getStepProps,
|
|
261
|
+
getBaseProps,
|
|
262
|
+
getValue,
|
|
263
|
+
renderLabel,
|
|
264
|
+
renderValue,
|
|
265
|
+
getTrackWrapperProps,
|
|
266
|
+
getLabelWrapperProps,
|
|
267
|
+
getLabelProps,
|
|
268
|
+
getValueProps,
|
|
269
|
+
getTrackProps,
|
|
270
|
+
getFillerProps,
|
|
271
|
+
getThumbProps,
|
|
272
|
+
getMarkProps,
|
|
273
|
+
getStartContentProps,
|
|
274
|
+
getEndContentProps
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
export { use_slider_useSlider as useSlider };
|
|
@@ -3,9 +3,11 @@ import "react";
|
|
|
3
3
|
import { useI18n } from "../../hooks/useI18n.js";
|
|
4
4
|
import { UXTab, UXTabs } from "../UXTabs/index.js";
|
|
5
5
|
const UXTabSwitch = (props)=>{
|
|
6
|
-
const { size, color, onTitle, offTitle, isSelected = false, isDisabled = false, disableAnimation = false, onValueChange } = props;
|
|
6
|
+
const { className, classNames, size, color, onTitle, offTitle, isSelected = false, isDisabled = false, disableAnimation = false, onValueChange } = props;
|
|
7
7
|
const i18n = useI18n();
|
|
8
8
|
return /*#__PURE__*/ jsxs(UXTabs, {
|
|
9
|
+
className: className,
|
|
10
|
+
classNames: classNames,
|
|
9
11
|
size: size,
|
|
10
12
|
variant: "switch",
|
|
11
13
|
color: color,
|
|
@@ -252,7 +252,7 @@ const tabsClasses = {
|
|
|
252
252
|
color: 'default',
|
|
253
253
|
class: {
|
|
254
254
|
cursor: [
|
|
255
|
-
'
|
|
255
|
+
'bg-tertiary dark:bg-tertiary'
|
|
256
256
|
],
|
|
257
257
|
tabContent: 'group-data-[selected=true]:text-tertiary-foreground'
|
|
258
258
|
}
|
|
@@ -264,7 +264,7 @@ const tabsClasses = {
|
|
|
264
264
|
color: 'default',
|
|
265
265
|
class: {
|
|
266
266
|
cursor: [
|
|
267
|
-
'
|
|
267
|
+
'bg-tertiary'
|
|
268
268
|
],
|
|
269
269
|
tabContent: 'group-data-[selected=true]:text-tertiary-foreground'
|
|
270
270
|
}
|
|
@@ -276,9 +276,9 @@ const tabsClasses = {
|
|
|
276
276
|
color: 'default',
|
|
277
277
|
class: {
|
|
278
278
|
cursor: [
|
|
279
|
-
'
|
|
279
|
+
'bg-background-200'
|
|
280
280
|
],
|
|
281
|
-
tabContent: 'group-data-[selected=true]:text-
|
|
281
|
+
tabContent: 'group-data-[selected=true]:text-foreground'
|
|
282
282
|
}
|
|
283
283
|
},
|
|
284
284
|
{
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { type ThemeId } from '@particle-network/ui-shared';
|
|
3
|
+
import { type UXModalProps } from '../UXModal';
|
|
3
4
|
export interface UXThemeSwitchModalProps extends Pick<UXModalProps, 'isOpen' | 'onClose' | 'onOpenChange' | 'backdrop'> {
|
|
4
5
|
as?: 'modal' | 'drawer';
|
|
6
|
+
omitThemes?: ThemeId[];
|
|
5
7
|
}
|
|
6
8
|
export declare const UXThemeSwitchModal: React.FC<UXThemeSwitchModalProps>;
|
|
7
|
-
export interface UXThemeSwitchProps extends Pick<UXThemeSwitchModalProps, 'as' | 'backdrop'> {
|
|
9
|
+
export interface UXThemeSwitchProps extends Pick<UXThemeSwitchModalProps, 'as' | 'omitThemes' | 'backdrop'> {
|
|
8
10
|
children?: (onOpen: () => void) => React.ReactNode;
|
|
9
11
|
}
|
|
10
12
|
export declare const UXThemeSwitch: React.FC<UXThemeSwitchProps>;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
3
|
import { cn } from "@heroui/theme";
|
|
4
4
|
import { useDisclosure } from "@heroui/use-disclosure";
|
|
5
5
|
import { ChartColorSwitchIcon, CopyIcon } from "@particle-network/icons/web";
|
|
6
6
|
import { themeData } from "@particle-network/ui-shared";
|
|
7
7
|
import { useI18n } from "../../hooks/index.js";
|
|
8
|
-
import { UXCopy, UXTooltip } from "../index.js";
|
|
9
8
|
import { HStack, VStack } from "../layout/index.js";
|
|
10
9
|
import { Text } from "../typography/Text.js";
|
|
11
10
|
import { UXButton } from "../UXButton/index.js";
|
|
11
|
+
import { UXCopy } from "../UXCopy/index.js";
|
|
12
12
|
import { UXDivider } from "../UXDivider/index.js";
|
|
13
13
|
import { UXDrawer } from "../UXDrawer/index.js";
|
|
14
14
|
import { UXInput } from "../UXInput/index.js";
|
|
15
15
|
import { UXModal } from "../UXModal/index.js";
|
|
16
16
|
import { UXSpinner } from "../UXSpinner/index.js";
|
|
17
|
+
import { UXTooltip } from "../UXTooltip/index.js";
|
|
17
18
|
import { ThemeItem } from "./theme-item.js";
|
|
18
19
|
import { useTheme } from "./use-theme.js";
|
|
19
20
|
const FONT_EXAMPLES = [
|
|
@@ -30,11 +31,14 @@ const FONT_EXAMPLES = [
|
|
|
30
31
|
url: 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
|
|
31
32
|
}
|
|
32
33
|
];
|
|
33
|
-
const UXThemeSwitchModal = ({ as = 'modal', backdrop, isOpen, onClose, onOpenChange })=>{
|
|
34
|
+
const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, onClose, onOpenChange })=>{
|
|
34
35
|
const i18n = useI18n();
|
|
35
36
|
const { theme: selectedTheme, setTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
36
37
|
const [isFontExampleOpen, setIsFontExampleOpen] = useState(false);
|
|
37
38
|
const Component = 'modal' === as ? UXModal : UXDrawer;
|
|
39
|
+
const themes = useMemo(()=>themeData.filter((theme)=>!omitThemes.includes(theme.id)), [
|
|
40
|
+
omitThemes
|
|
41
|
+
]);
|
|
38
42
|
return /*#__PURE__*/ jsx(Component, {
|
|
39
43
|
isOpen: isOpen,
|
|
40
44
|
classNames: {
|
|
@@ -44,7 +48,7 @@ const UXThemeSwitchModal = ({ as = 'modal', backdrop, isOpen, onClose, onOpenCha
|
|
|
44
48
|
backdrop: backdrop,
|
|
45
49
|
footer: /*#__PURE__*/ jsx(UXButton, {
|
|
46
50
|
fullWidth: true,
|
|
47
|
-
size: "
|
|
51
|
+
size: "xl",
|
|
48
52
|
color: "primary",
|
|
49
53
|
onPress: onClose,
|
|
50
54
|
children: i18n.theme.done
|
|
@@ -55,7 +59,7 @@ const UXThemeSwitchModal = ({ as = 'modal', backdrop, isOpen, onClose, onOpenCha
|
|
|
55
59
|
children: [
|
|
56
60
|
/*#__PURE__*/ jsx("div", {
|
|
57
61
|
className: "grid grid-cols-3 gap-y-5 pt-1",
|
|
58
|
-
children:
|
|
62
|
+
children: themes.map((theme)=>/*#__PURE__*/ jsx(ThemeItem, {
|
|
59
63
|
isSelected: selectedTheme.id === theme.id,
|
|
60
64
|
onClick: ()=>setTheme(theme),
|
|
61
65
|
...theme
|
|
@@ -159,7 +163,7 @@ const UXThemeSwitchModal = ({ as = 'modal', backdrop, isOpen, onClose, onOpenCha
|
|
|
159
163
|
})
|
|
160
164
|
});
|
|
161
165
|
};
|
|
162
|
-
const UXThemeSwitch = ({
|
|
166
|
+
const UXThemeSwitch = ({ children, ...restProps })=>{
|
|
163
167
|
const { isOpen, onOpen, onClose, onOpenChange } = useDisclosure();
|
|
164
168
|
const renderChildren = ()=>{
|
|
165
169
|
if (children) return children(onOpen);
|
|
@@ -174,8 +178,7 @@ const UXThemeSwitch = ({ as = 'modal', backdrop, children })=>{
|
|
|
174
178
|
children: [
|
|
175
179
|
renderChildren(),
|
|
176
180
|
/*#__PURE__*/ jsx(UXThemeSwitchModal, {
|
|
177
|
-
|
|
178
|
-
backdrop: backdrop,
|
|
181
|
+
...restProps,
|
|
179
182
|
isOpen: isOpen,
|
|
180
183
|
onClose: onClose,
|
|
181
184
|
onOpenChange: onOpenChange
|